diff --git a/BUILD.gn b/BUILD.gn
index 2902e37..eaae83b 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -148,8 +148,6 @@
       deps += [
         "//components/subresource_filter/tools:subresource_filter_tools",
         "//components/zucchini:zucchini",
-        "//gpu/gles2_conform_support:gles2_conform_test",
-        "//gpu/khronos_glcts_support:khronos_glcts_test",
         "//net:hpack_example_generator",
         "//third_party/spirv-tools/src:SPIRV-Tools",
         "//tools/aggregation_service:aggregation_service_tool",
@@ -614,7 +612,6 @@
 
     if (is_linux || is_chromeos_lacros) {
       deps += [
-        "//gpu/khronos_glcts_support:khronos_glcts_test",
         "//skia:filter_fuzz_stub",
         "//skia:image_operations_bench",
         "//ui/snapshot:snapshot_unittests",
diff --git a/DEPS b/DEPS
index a0266d8b..c664ae1 100644
--- a/DEPS
+++ b/DEPS
@@ -307,23 +307,23 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'src_internal_revision': '50e70879b09d050c0010faf7e0faa9c3546a746f',
+  'src_internal_revision': '7065ba45b9e097c55423362bda374e691ae55839',
   # 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': '2121bbc603c722bb2bc530a3a447900c635668ec',
+  'skia_revision': '330eeb106170f34c75b546e5a0b9859251dfe642',
   # 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': '8ade8567adea934309455768cb38ffbb99c4779d',
+  'v8_revision': '6374ee67b88dc2b553eaceb203e0b0bac517c86b',
   # 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': 'd521dd08bef4dc5769690e8ec7c996b2cdd40e27',
+  'angle_revision': 'cdc541de11ed11364cc990293c459faa348ed1d5',
   # 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': '085997ddb08b9df39e55dd727f8145d1a7aa9ce4',
+  'swiftshader_revision': 'cea33ab2d5ad50cd7f1881fb9c36ffcaecdd69fc',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -382,11 +382,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '68fe632a004e438f1f20f13e435fc27412562c99',
+  'catapult_revision': '8c184bf50d33dddcb0fa650999e6e4a4aa8f01b6',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling chromium_variations
   # and whatever else without interference from each other.
-  'chromium_variations_revision': '2d85606f2917fe6c93f1012fa8fc719ad2610b07',
+  'chromium_variations_revision': 'dd19926430790b671b4455b17f9f5a9fa9c30fee',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling CrossBench
   # and whatever else without interference from each other.
@@ -402,7 +402,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': '33f1e4ca2f50a8ade4dd8c58d34efc05d5f204b6',
+  'devtools_frontend_revision': '5839d81905907f4ca1ce08192a23257b2788f121',
   # 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.
@@ -426,7 +426,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': 'd16f1c5767ebfe40278cd4dcb31b0f181bff2e03',
+  'dawn_revision': '6b46c4ac1055d9980b05983bcd988fa90d6ed1e9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -1269,12 +1269,12 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    'ebe9c7de0e204bbe1d3f11af3717aea5529d1d60',
+    '502004caf543a3bc541487ae4f4c65486f50fb5a',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
   'src/docs/website': {
-    'url': Var('chromium_git') + '/website.git' + '@' + 'a685042c1ed1a9772e7f824b314be89fdb8650b9',
+    'url': Var('chromium_git') + '/website.git' + '@' + '5bcb9612ba762a369ee54c1dab51fb6025c92652',
   },
 
   'src/ios/third_party/earl_grey2/src': {
@@ -1423,7 +1423,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'DiayCMM-ne_KuNc7Q7jV2K9ZeN_Bu8dn_A6iUgRnfC8C',
+          'version': 'aqX5QiolLSZVjb86a0t8LaQVzy8B0yl06RDs1gmMjOYC',
       },
     ],
     'condition': 'checkout_android',
@@ -1685,7 +1685,7 @@
   # Tools used when building Chrome for Chrome OS. This affects both the Simple
   # Chrome workflow, as well as the chromeos-chrome ebuild.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'aae6a185626c2b51c2c07f5d17cf6aa554e4ad9f',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '7559f18d7844ac156ac74d49a4b5823218079a86',
       'condition': 'checkout_chromeos',
   },
 
@@ -1720,13 +1720,13 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '1d1f17af898bc5158fb1128952894ac061b06f56',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '66df2a3ec70d0628d47df1fdba69838a870a1303',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'c9b420694f06ed9657c694d3a39296b7bafcb592',
+      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '342adbf2db4473a5fcbc49fb9d7f7c4c017c74c8',
     'condition': 'checkout_src_internal',
   },
 
@@ -2216,7 +2216,7 @@
     Var('pdfium_git') + '/pdfium.git' + '@' +  Var('pdfium_revision'),
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '6f8d4eba872ebf682e638c7def3052e8cb6e4d75',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '1990573f6d71b581cb1fb48df3445883e93020a5',
 
   'src/base/tracing/test/data': {
     'bucket': 'perfetto',
@@ -2350,7 +2350,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/r8',
-              'version': 'dhoEB5vFXAD1JsD0RjBHaB3DLb1UbuHu0kptrpbcQA8C',
+              'version': 'BbsWCeVMT641FkMRNj4fbXc-wfImc7dl45HwKXWk0hsC',
           },
       ],
       'condition': 'checkout_android',
@@ -2477,14 +2477,14 @@
       'packages': [
           {
               'package': 'chromium/third_party/turbine',
-              'version': '1kLxPxWBXSIEOzQ1Zzi1M9XXu6pwfDbKCzQrNyGcCCEC',
+              'version': 's6-zuFNzLDZOl_FmPkk2_LENOqUKjkYmpqR9l0SDo94C',
           },
       ],
       'condition': 'checkout_android',
       'dep_type': 'cipd',
   },
 
-  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@897d900fc1b1a504302f1620e416cb7421fcbf7c',
+  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@7f05a36fb6d9c2c6283eaad78b0b9047e6eb19da',
   'src/third_party/glslang/src': '{chromium_git}/external/github.com/KhronosGroup/glslang@19efb4ec60febf569ad3cf2f2fd71bbd20ff4617',
   'src/third_party/spirv-cross/src': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Cross@b8fcf307f1f347089e3c46eb4451d27f32ebc8d3',
   'src/third_party/spirv-headers/src': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Headers@2acb319af38d43be3ea76bfabf3998e5281d8d12',
@@ -2493,7 +2493,7 @@
   'src/third_party/vulkan-loader/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Loader@f23f8b7ae5adc4979ad8466e7ccdf024ec7c0c93',
   'src/third_party/vulkan-tools/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Tools@345af476e583366352e014ee8e43fc5ddf421ab9',
   'src/third_party/vulkan-utility-libraries/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Utility-Libraries@1b07de9a3a174b853833f7f87a824f20604266b9',
-  'src/third_party/vulkan-validation-layers/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-ValidationLayers@9bb8d0513ee37db2a57abe8a8edd16ac95ae5bd9',
+  'src/third_party/vulkan-validation-layers/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-ValidationLayers@8f3d3736ce1c4167958882c2b69dd4ba753457ee',
 
   'src/third_party/vulkan_memory_allocator':
     Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + '56300b29fbfcc693ee6609ddad3fdd5b7a449a21',
@@ -2533,7 +2533,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'b5e1f1f256bca6762bb08e7fe9a10ff01af433ee',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '72302cc5e4ea5aa820e5fe3bc10440dbde2ba362',
+    Var('webrtc_git') + '/src.git' + '@' + 'feea82fad5d472cf787c54455f147d86b219196f',
 
   # Wuffs' canonical repository is at github.com/google/wuffs, but we use
   # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file.
@@ -2656,7 +2656,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/help_app/app',
-        'version': 'M4znk_eQ0CrqZdpKxWKeEpqUe0M_hKsiX3ahLwsWBoIC',
+        'version': 'HATHhOxYgDIiXsZ83I_VI4FxVqS-3YFzAn2bOGchDPgC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -2667,7 +2667,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'H6ZAelB9ss1d1waL2icKEMoE1cO0boV7ntOn0tEXEOoC',
+        'version': 'UhQm0xthdoW4L1V-3aPfw0ss7JqQO6Id-2-cx6cn19QC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -2700,7 +2700,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': '-NQelQmomREuQI7kd9NftadUmErjcG046BDJxMvAr00C',
+        'version': 'vT0SMxAuMSQLHiGz3QG4UOhXisGcsTlWbcEihsX1lKoC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -4687,7 +4687,7 @@
 
   'src/components/autofill/core/browser/form_parsing/internal_resources': {
       'url': Var('chrome_git') + '/chrome/components/autofill_regex_patterns.git' + '@' +
-        'd26e0d57f43c90fc762e58aef8f879fb02f28a68',
+        '5da272c05cbe43d762d7c4523e23f4e532564b8c',
       'condition': 'checkout_src_internal',
   },
 
@@ -4716,7 +4716,7 @@
 
   'src/components/plus_addresses/resources/internal': {
       'url': Var('chrome_git') + '/chrome/components/plus_addresses/resources.git' + '@' +
-        'e59966e228d0bf01a05ed48efb828a2900d639d0',
+        'a91fba0741b48a257081ec7f3ca3ec0f72101b4d',
       'condition': 'checkout_src_internal',
   },
 
@@ -4746,7 +4746,7 @@
 
   'src/components/test/data/autofill/heuristics-json/internal': {
       'url': Var('chrome_git') + '/chrome/test/autofill/structured_forms.git' + '@' +
-        '8fd2aef905fe4040b989aa45b40c545d0926b590',
+        '1a305f4778c0bde5f4b02e987a41e5df51217f82',
       'condition': 'checkout_chromium_autofill_test_dependencies',
   },
 
@@ -4770,7 +4770,7 @@
 
   'src/ios_internal':  {
       'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' +
-        '5effe237b43d0d5ec9c1fa2d85b806904da4858a',
+        '1bcfec0bcdfd92bbf39cddde202d6f63156cc6dd',
       'condition': 'checkout_ios and checkout_src_internal',
   },
 
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index cc47edf..a984faa 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -1057,6 +1057,7 @@
         r'services/network/web_transport\.cc',
         r'chrome/browser/ip_protection/.*',
         r'components/ip_protection/.*',
+        r'android_webview/browser/aw_ip_protection_config_provider.*',
         # Not an error in third_party folders.
         _THIRD_PARTY_EXCEPT_BLINK,
         # //base/numerics can't use base or absl.
@@ -1078,6 +1079,7 @@
         # Needed to use QUICHE API.
         r'chrome/browser/ip_protection/.*',
         r'components/ip_protection/.*',
+        r'android_webview/browser/aw_ip_protection_config_provider.*',
         # Needed to use MediaPipe API.
         r'components/media_effects/.*\.cc',
         # Not an error in third_party folders.
@@ -1120,7 +1122,7 @@
         # Needed to use QUICHE API.
         r'chrome/browser/ip_protection/.*',
         r'components/ip_protection/.*',
-        r'services/network/web_transport.*',
+        r'android_webview/browser/aw_ip_protection_config_provider.*',
         # Needed to integrate with //third_party/nearby
         r'components/cross_device/nearby/system_clock.cc',
         _THIRD_PARTY_EXCEPT_BLINK  # Not an error in third_party folders.
diff --git a/android_webview/DEPS b/android_webview/DEPS
index 49b364c..9166baba 100644
--- a/android_webview/DEPS
+++ b/android_webview/DEPS
@@ -16,6 +16,7 @@
   "+components/heap_profiling",
   "+components/keyed_service/content",
   "+components/google/core",
+  "+components/ip_protection",
   "+components/js_injection",
   "+components/network_session_configurator/common",
   "+components/metrics",
diff --git a/android_webview/browser/BUILD.gn b/android_webview/browser/BUILD.gn
index 7cc88c280..eb96809 100644
--- a/android_webview/browser/BUILD.gn
+++ b/android_webview/browser/BUILD.gn
@@ -79,6 +79,8 @@
     "aw_form_database_service.h",
     "aw_http_auth_handler.cc",
     "aw_http_auth_handler.h",
+    "aw_ip_protection_config_provider.cc",
+    "aw_ip_protection_config_provider.h",
     "aw_ip_protection_proxy_bypass_info.cc",
     "aw_ip_protection_proxy_bypass_info.h",
     "aw_javascript_dialog_manager.cc",
@@ -242,38 +244,34 @@
     "//components/component_updater/installer_policies",
     "//components/content_capture/android",
     "//components/content_capture/browser",
-    "//components/embedder_support:browser_util",
-    "//components/embedder_support:embedder_support",
-    "//components/embedder_support/android:util",
-    "//components/embedder_support/origin_trials",
-    "//components/favicon_base:favicon_base",
-    "//components/flags_ui",
-    "//components/history/core/browser:browser",
-    "//components/keyed_service/content",
-    "//components/optimization_guide/core:bloomfilter",
-    "//components/profile_metrics",
-    "//components/strings:components_strings_grit",
-    "//components/tpcd/metadata/browser",
-    "//components/translate/core/common",
-    "//components/url_matcher",
 
     # Called via JNI in CrashpadMain
     "//components/crash/android:crashpad_main",
     "//components/crash/content/browser",
     "//components/crash/core/app",
+    "//components/embedder_support:browser_util",
+    "//components/embedder_support:embedder_support",
+    "//components/embedder_support/android:util",
     "//components/embedder_support/android:web_contents_delegate",
     "//components/embedder_support/android/metrics",
+    "//components/embedder_support/origin_trials",
+    "//components/favicon_base:favicon_base",
+    "//components/flags_ui",
     "//components/google/core/common",
     "//components/heap_profiling/multi_process",
+    "//components/history/core/browser:browser",
+    "//components/ip_protection:ip_protection",
     "//components/js_injection/browser",
     "//components/js_injection/common",
     "//components/js_injection/common:common_mojom",
+    "//components/keyed_service/content",
     "//components/metrics",
     "//components/metrics:component_metrics",
     "//components/metrics:content",
     "//components/minidump_uploader",
     "//components/navigation_interception",
     "//components/network_hints/browser",
+    "//components/optimization_guide/core:bloomfilter",
     "//components/origin_trials:browser",
     "//components/origin_trials:common",
     "//components/os_crypt/async/browser",
@@ -284,6 +282,7 @@
     "//components/policy/core/browser",
     "//components/pref_registry",
     "//components/prefs",
+    "//components/profile_metrics",
     "//components/safe_browsing/android:remote_database_manager",
     "//components/safe_browsing/content/browser",
     "//components/safe_browsing/content/browser/triggers",
@@ -298,10 +297,14 @@
     "//components/security_interstitials/core",
     "//components/services/heap_profiling/public/cpp",
     "//components/spellcheck:buildflags",
+    "//components/strings:components_strings_grit",
+    "//components/tpcd/metadata/browser",
     "//components/tracing:background_tracing_metrics_provider",
     "//components/tracing:background_tracing_utils",
     "//components/tracing:startup_tracing",
+    "//components/translate/core/common",
     "//components/url_formatter",
+    "//components/url_matcher",
     "//components/user_prefs",
     "//components/variations",
     "//components/variations/service",
@@ -310,14 +313,21 @@
     "//components/visitedlink/browser",
     "//components/webdata/common",
     "//content/public/browser",
+    "//google_apis:google_apis",
     "//media/mojo:buildflags",
     "//media/mojo/mojom:web_speech_recognition",
     "//mojo/public/cpp/base:protobuf_support",
+    "//mojo/public/cpp/bindings:bindings",
+    "//net/third_party/quiche:blind_sign_auth",
     "//services/cert_verifier/public/mojom",
     "//services/device/public/cpp:device_feature_list",
     "//services/device/public/java:device_feature_list_jni",
+    "//services/network/public/cpp:cpp",
     "//services/network/public/mojom",
+    "//services/network/public/mojom:mojom",
+    "//services/network/public/mojom:url_loader_base",
     "//services/proxy_resolver:lib",
+    "//third_party/anonymous_tokens:anonymous_tokens_cc_proto",
     "//third_party/blink/public/common",
     "//third_party/blink/public/mojom:mojom_core",
     "//third_party/blink/public/mojom:mojom_platform",
diff --git a/android_webview/browser/DEPS b/android_webview/browser/DEPS
index a257745..30b4b73 100644
--- a/android_webview/browser/DEPS
+++ b/android_webview/browser/DEPS
@@ -162,4 +162,6 @@
   "+third_party/metrics_proto",
   # For Android WebView Media Integrity
   "+third_party/blink/public/mojom/webview/webview_media_integrity.mojom.h",
+  # For Chrome's API keys in WebView.
+  "+google_apis/google_api_keys.h",
 ]
diff --git a/android_webview/browser/aw_ip_protection_config_provider.cc b/android_webview/browser/aw_ip_protection_config_provider.cc
new file mode 100644
index 0000000..af3ad3c
--- /dev/null
+++ b/android_webview/browser/aw_ip_protection_config_provider.cc
@@ -0,0 +1,346 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "android_webview/browser/aw_ip_protection_config_provider.h"
+
+#include <memory>
+#include <optional>
+#include <string>
+#include <vector>
+
+#include "android_webview/browser/aw_browser_process.h"
+#include "base/check.h"
+#include "base/feature_list.h"
+#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/ranges/algorithm.h"
+#include "base/strings/strcat.h"
+#include "components/ip_protection/blind_sign_message_android_impl.h"
+#include "components/ip_protection/ip_protection_config_provider_helper.h"
+#include "components/version_info/android/channel_getter.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/storage_partition.h"
+#include "google_apis/google_api_keys.h"
+#include "mojo/public/cpp/bindings/message.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "net/base/features.h"
+#include "net/base/proxy_chain.h"
+#include "net/base/proxy_server.h"
+#include "net/base/proxy_string_util.h"
+#include "net/third_party/quiche/src/quiche/blind_sign_auth/blind_sign_auth.h"
+#include "net/third_party/quiche/src/quiche/blind_sign_auth/proto/blind_sign_auth_options.pb.h"
+#include "net/third_party/quiche/src/quiche/blind_sign_auth/proto/spend_token_data.pb.h"
+
+namespace {
+// TODO(crbug.com/40216037): Once `google_apis::GetAPIKey()` handles this
+// logic we can remove this helper.
+std::string GetAPIKey() {
+  version_info::Channel channel = version_info::android::GetChannel();
+  return channel == version_info::Channel::STABLE
+             ? google_apis::GetAPIKey()
+             : google_apis::GetNonStableAPIKey();
+}
+}  // namespace
+
+namespace android_webview {
+
+AwIpProtectionConfigProvider::AwIpProtectionConfigProvider(
+    AwBrowserContext* aw_browser_context)
+    : aw_browser_context_(aw_browser_context) {}
+
+AwIpProtectionConfigProvider::~AwIpProtectionConfigProvider() = default;
+
+void AwIpProtectionConfigProvider::SetUp() {
+  if (!blind_sign_message_android_impl_) {
+    blind_sign_message_android_impl_ =
+        std::make_unique<BlindSignMessageAndroidImpl>();
+  }
+
+  if (!ip_protection_proxy_config_retriever_) {
+    CHECK(aw_browser_context_);
+    ip_protection_proxy_config_retriever_ =
+        std::make_unique<IpProtectionProxyConfigRetriever>(
+            aw_browser_context_->GetDefaultStoragePartition()
+                ->GetURLLoaderFactoryForBrowserProcess()
+                .get(),
+            IpProtectionConfigProviderHelper::kWebViewIpBlinding, GetAPIKey());
+  }
+
+  if (!bsa_) {
+    if (!blind_sign_auth_) {
+      privacy::ppn::BlindSignAuthOptions bsa_options{};
+      bsa_options.set_enable_privacy_pass(true);
+
+      blind_sign_auth_ = std::make_unique<quiche::BlindSignAuth>(
+          blind_sign_message_android_impl_.get(), std::move(bsa_options));
+    }
+    bsa_ = blind_sign_auth_.get();
+  }
+}
+
+void AwIpProtectionConfigProvider::SetUpForTesting(
+    std::unique_ptr<IpProtectionProxyConfigRetriever>
+        ip_protection_proxy_config_retriever,
+    std::unique_ptr<BlindSignMessageAndroidImpl>
+        blind_sign_message_android_impl,
+    quiche::BlindSignAuthInterface* bsa) {
+  // Carefully destroy any existing values in the correct order.
+  bsa_ = nullptr;
+  blind_sign_auth_ = nullptr;
+  blind_sign_message_android_impl_ = nullptr;
+  ip_protection_proxy_config_retriever_ = nullptr;
+
+  ip_protection_proxy_config_retriever_ =
+      std::move(ip_protection_proxy_config_retriever);
+  blind_sign_message_android_impl_ = std::move(blind_sign_message_android_impl);
+  bsa_ = bsa;
+}
+
+void AwIpProtectionConfigProvider::GetProxyList(GetProxyListCallback callback) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  CHECK(!is_shutting_down_);
+  SetUp();
+
+  // If IP Protection is disabled then don't attempt to get a proxy list.
+  if (!IsIpProtectionEnabled()) {
+    std::move(callback).Run(std::nullopt);
+    return;
+  }
+
+  CallGetProxyConfig(std::move(callback));
+}
+
+void AwIpProtectionConfigProvider::CallGetProxyConfig(
+    GetProxyListCallback callback) {
+  ip_protection_proxy_config_retriever_->GetProxyConfig(
+      /*oauth_token=*/std::nullopt,
+      base::BindOnce(&AwIpProtectionConfigProvider::OnGetProxyConfigCompleted,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+}
+
+void AwIpProtectionConfigProvider::OnGetProxyConfigCompleted(
+    GetProxyListCallback callback,
+    base::expected<ip_protection::GetProxyConfigResponse, std::string>
+        response) {
+  if (!response.has_value()) {
+    VLOG(2) << "AwIpProtectionConfigProvider::GetProxyList failed: "
+            << response.error();
+    std::move(callback).Run(std::nullopt);
+    return;
+  }
+
+  std::vector<net::ProxyChain> proxy_list =
+      IpProtectionConfigProviderHelper::GetProxyListFromProxyConfigResponse(
+          response.value());
+  std::move(callback).Run(std::move(proxy_list));
+}
+
+void AwIpProtectionConfigProvider::TryGetAuthTokens(
+    uint32_t batch_size,
+    network::mojom::IpProtectionProxyLayer proxy_layer,
+    TryGetAuthTokensCallback callback) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  CHECK(!is_shutting_down_);
+  SetUp();
+
+  // The `batch_size` is cast to an `int` for use by BlindSignAuth, so check
+  // for overflow here.
+  if (!base::IsValueInRangeForNumericType<int>(batch_size)) {
+    receivers_.ReportBadMessage("Invalid batch_size");
+    return;
+  }
+
+  // If IP Protection is disabled then don't attempt to fetch tokens.
+  if (!IsIpProtectionEnabled()) {
+    TryGetAuthTokensComplete(
+        /*bsa_tokens=*/std::nullopt, std::move(callback),
+        AwIpProtectionTryGetAuthTokensResult::kFailedDisabled);
+    return;
+  }
+
+  FetchBlindSignedToken(base::checked_cast<int>(batch_size), proxy_layer,
+                        std::move(callback));
+}
+
+void AwIpProtectionConfigProvider::FetchBlindSignedToken(
+    int batch_size,
+    network::mojom::IpProtectionProxyLayer proxy_layer,
+    TryGetAuthTokensCallback callback) {
+  auto bsa_get_tokens_start_time = base::TimeTicks::Now();
+  auto quiche_proxy_layer =
+      proxy_layer == network::mojom::IpProtectionProxyLayer::kProxyA
+          ? quiche::ProxyLayer::kProxyA
+          : quiche::ProxyLayer::kProxyB;
+  bsa_->GetTokens(
+      /*oauth_token=*/std::nullopt, batch_size, quiche_proxy_layer,
+      quiche::BlindSignAuthServiceType::kWebviewIpBlinding,
+      [weak_ptr = weak_ptr_factory_.GetWeakPtr(), bsa_get_tokens_start_time,
+       callback = std::move(callback)](
+          absl::StatusOr<absl::Span<quiche::BlindSignToken>> tokens) mutable {
+        if (weak_ptr) {
+          weak_ptr->OnFetchBlindSignedTokenCompleted(
+              bsa_get_tokens_start_time, std::move(callback), tokens);
+        }
+      });
+}
+
+void AwIpProtectionConfigProvider::OnFetchBlindSignedTokenCompleted(
+    base::TimeTicks bsa_get_tokens_start_time,
+    TryGetAuthTokensCallback callback,
+    absl::StatusOr<absl::Span<quiche::BlindSignToken>> tokens) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  if (is_shutting_down_) {
+    return;
+  }
+  if (!tokens.ok()) {
+    AwIpProtectionTryGetAuthTokensResult result;
+    switch (tokens.status().code()) {
+      case absl::StatusCode::kUnavailable:
+        result = AwIpProtectionTryGetAuthTokensResult::kFailedBSATransient;
+        break;
+      case absl::StatusCode::kFailedPrecondition:
+        result = AwIpProtectionTryGetAuthTokensResult::kFailedBSAPersistent;
+        break;
+      default:
+        result = AwIpProtectionTryGetAuthTokensResult::kFailedBSAOther;
+        break;
+    }
+    VLOG(2) << "AwIpProtectionConfigProvider::OnFetchBlindSignedTokenCompleted "
+               "got an error: "
+            << static_cast<int>(result);
+    TryGetAuthTokensComplete(/*bsa_tokens=*/std::nullopt, std::move(callback),
+                             result);
+    return;
+  }
+
+  if (tokens.value().size() == 0) {
+    VLOG(2) << "AwIpProtectionConfigProvider::"
+               "OnFetchBlindSignedTokenCompleted called with no tokens";
+    TryGetAuthTokensComplete(
+        /*bsa_tokens=*/std::nullopt, std::move(callback),
+        AwIpProtectionTryGetAuthTokensResult::kFailedBSAOther);
+    return;
+  }
+
+  std::vector<network::mojom::BlindSignedAuthTokenPtr> bsa_tokens;
+  for (const quiche::BlindSignToken& token : tokens.value()) {
+    network::mojom::BlindSignedAuthTokenPtr converted_token =
+        IpProtectionConfigProviderHelper::CreateBlindSignedAuthToken(token);
+    if (converted_token->token.empty()) {
+      VLOG(2) << "AwIpProtectionConfigProvider::"
+                 "OnFetchBlindSignedTokenCompleted failed to convert "
+                 "`quiche::BlindSignAuth` token to a "
+                 "`network::mojom::BlindSignedAuthToken`";
+      TryGetAuthTokensComplete(
+          /*bsa_tokens=*/std::nullopt, std::move(callback),
+          AwIpProtectionTryGetAuthTokensResult::kFailedBSAOther);
+      return;
+    }
+    bsa_tokens.push_back(std::move(converted_token));
+  }
+
+  const base::TimeTicks current_time = base::TimeTicks::Now();
+  base::UmaHistogramTimes("NetworkService.AwIpProtection.TokenBatchRequestTime",
+                          current_time - bsa_get_tokens_start_time);
+
+  TryGetAuthTokensComplete(std::move(bsa_tokens), std::move(callback),
+                           AwIpProtectionTryGetAuthTokensResult::kSuccess);
+}
+
+void AwIpProtectionConfigProvider::TryGetAuthTokensComplete(
+    std::optional<std::vector<network::mojom::BlindSignedAuthTokenPtr>>
+        bsa_tokens,
+    TryGetAuthTokensCallback callback,
+    AwIpProtectionTryGetAuthTokensResult result) {
+  if (result == AwIpProtectionTryGetAuthTokensResult::kSuccess) {
+    CHECK(bsa_tokens.has_value() && !bsa_tokens->empty());
+  }
+
+  base::UmaHistogramEnumeration(
+      "NetworkService.AwIpProtection.TryGetAuthTokensResult", result);
+
+  std::optional<base::TimeDelta> backoff = CalculateBackoff(result);
+  std::optional<base::Time> try_again_after;
+  if (backoff) {
+    if (*backoff == base::TimeDelta::Max()) {
+      try_again_after = base::Time::Max();
+    } else {
+      try_again_after = base::Time::Now() + *backoff;
+    }
+  }
+  DCHECK(bsa_tokens.has_value() || try_again_after.has_value());
+  std::move(callback).Run(std::move(bsa_tokens), try_again_after);
+}
+
+std::optional<base::TimeDelta> AwIpProtectionConfigProvider::CalculateBackoff(
+    AwIpProtectionTryGetAuthTokensResult result) {
+  std::optional<base::TimeDelta> backoff;
+  switch (result) {
+    case AwIpProtectionTryGetAuthTokensResult::kSuccess:
+      break;
+    case AwIpProtectionTryGetAuthTokensResult::kFailedBSAPersistent:
+    case AwIpProtectionTryGetAuthTokensResult::kFailedDisabled:
+      backoff = base::TimeDelta::Max();
+      break;
+    case AwIpProtectionTryGetAuthTokensResult::kFailedBSATransient:
+    case AwIpProtectionTryGetAuthTokensResult::kFailedBSAOther:
+      backoff = IpProtectionConfigProviderHelper::kTransientBackoff;
+      // Note that we calculate the backoff assuming that we've waited for
+      // `last_try_get_auth_tokens_backoff_` time already, but this may not be
+      // the case when:
+      //  - Concurrent calls to `TryGetAuthTokens` from two network contexts are
+      //  made and both fail in the same way
+      //
+      //  - The network service restarts (the new network context(s) won't know
+      //  to backoff until after the first request(s))
+      //
+      // We can't do much about the first case, but for the others we could
+      // track the backoff time here and not request tokens again until
+      // afterward.
+      if (last_try_get_auth_tokens_backoff_ &&
+          last_try_get_auth_tokens_result_ == result) {
+        backoff = *last_try_get_auth_tokens_backoff_ * 2;
+      }
+      break;
+  }
+  last_try_get_auth_tokens_result_ = result;
+  last_try_get_auth_tokens_backoff_ = backoff;
+  return backoff;
+}
+
+void AwIpProtectionConfigProvider::Shutdown() {
+  if (is_shutting_down_) {
+    return;
+  }
+  is_shutting_down_ = true;
+  receivers_.Clear();
+
+  aw_browser_context_ = nullptr;
+  bsa_ = nullptr;
+  blind_sign_auth_ = nullptr;
+}
+
+void AwIpProtectionConfigProvider::AddNetworkService(
+    mojo::PendingReceiver<network::mojom::IpProtectionConfigGetter>
+        pending_receiver,
+    mojo::PendingRemote<network::mojom::IpProtectionProxyDelegate>
+        pending_remote) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  CHECK(!is_shutting_down_);
+  receivers_.Add(this, std::move(pending_receiver));
+  remotes_.Add(std::move(pending_remote));
+}
+
+// TODO(b/335420700): Update to return feature flag.
+bool AwIpProtectionConfigProvider::IsIpProtectionEnabled() {
+  if (is_shutting_down_) {
+    return false;
+  }
+  return base::FeatureList::IsEnabled(net::features::kEnableIpProtectionProxy);
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_ip_protection_config_provider.h b/android_webview/browser/aw_ip_protection_config_provider.h
new file mode 100644
index 0000000..b125c13
--- /dev/null
+++ b/android_webview/browser/aw_ip_protection_config_provider.h
@@ -0,0 +1,187 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ANDROID_WEBVIEW_BROWSER_AW_IP_PROTECTION_CONFIG_PROVIDER_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_IP_PROTECTION_CONFIG_PROVIDER_H_
+
+#include <memory>
+#include <optional>
+#include <string>
+#include <vector>
+
+#include "android_webview/browser/aw_browser_context.h"
+#include "base/functional/callback.h"
+#include "base/memory/raw_ptr.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
+#include "components/ip_protection/blind_sign_message_android_impl.h"
+#include "components/ip_protection/ip_protection_config_provider_helper.h"
+#include "components/ip_protection/ip_protection_proxy_config_retriever.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
+#include "mojo/public/cpp/bindings/remote_set.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/mojom/network_context.mojom.h"
+
+namespace quiche {
+class BlindSignAuthInterface;
+class BlindSignAuth;
+struct BlindSignToken;
+}  // namespace quiche
+
+namespace android_webview {
+
+// The result of a fetch of tokens from the IP Protection auth token server.
+//
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused. Keep this in sync with
+// AwIpProtectionTokenBatchRequestResult in enums.xml.
+enum class AwIpProtectionTryGetAuthTokensResult {
+  // The request was successful and resulted in new tokens.
+  kSuccess = 0,
+  // A transient error, implies that retrying the action (with backoff) is
+  // appropriate.
+  kFailedBSATransient = 1,
+  // A persistent error, implies that the action should not be retried.
+  kFailedBSAPersistent = 2,
+  // Any other issue calling BSA.
+  kFailedBSAOther = 3,
+  // The attempt to request tokens failed because IP Protection is disabled by
+  // WebView.
+  kFailedDisabled = 4,
+
+  kMaxValue = kFailedDisabled,
+};
+
+// Fetches IP protection tokens and proxy list on demand for the network
+// service.
+
+// TODO(b/346997109): Refactor AwIpProtectionConfigProvider to reduce code
+// duplication once a common implementation of IpProtectionConfigGetter is
+// added.
+class AwIpProtectionConfigProvider
+    : public KeyedService,
+      public network::mojom::IpProtectionConfigGetter {
+ public:
+  explicit AwIpProtectionConfigProvider(AwBrowserContext* aw_browser_context);
+
+  ~AwIpProtectionConfigProvider() override;
+
+  AwIpProtectionConfigProvider(const AwIpProtectionConfigProvider&) = delete;
+  AwIpProtectionConfigProvider& operator=(const AwIpProtectionConfigProvider&) =
+      delete;
+
+  // IpProtectionConfigGetter:
+  // Get a batch of blind-signed auth tokens.
+  void TryGetAuthTokens(uint32_t batch_size,
+                        network::mojom::IpProtectionProxyLayer proxy_layer,
+                        TryGetAuthTokensCallback callback) override;
+  // Get the list of IP Protection proxies.
+  void GetProxyList(GetProxyListCallback callback) override;
+
+  // KeyedService:
+
+  // We do not currently support destroying WebView's browser context. No
+  // shutdown code will be executed on termination of the browser process so
+  // this is not actually being tested yet. However, we would like to support
+  // destroying browser context in the future so this method contains an idea of
+  // how this could be done. Note that Shutdown should not be called more than
+  // once.
+  void Shutdown() override;
+
+  // Checks if IP Protection is disabled.
+  bool IsIpProtectionEnabled();
+
+  // Binds Mojo interfaces to be passed to a new network service.
+  void AddNetworkService(
+      mojo::PendingReceiver<network::mojom::IpProtectionConfigGetter>
+          pending_receiver,
+      mojo::PendingRemote<network::mojom::IpProtectionProxyDelegate>
+          pending_remote);
+
+  // Like `SetUp()`, but providing values for each of the member variables.
+  void SetUpForTesting(std::unique_ptr<IpProtectionProxyConfigRetriever>
+                           ip_protection_proxy_config_retriever,
+                       std::unique_ptr<BlindSignMessageAndroidImpl>
+                           blind_sign_message_android_impl,
+                       quiche::BlindSignAuthInterface* bsa);
+
+ private:
+  // Set up
+  // `blind_sign_message_android_impl_`,`ip_protection_proxy_config_retriever_`
+  // and `bsa_`, if not already initialized.
+  void SetUp();
+
+  // Get proxy configuration that is necessary for IP Protection from the
+  // server.
+  void CallGetProxyConfig(GetProxyListCallback callback);
+  void OnGetProxyConfigCompleted(
+      GetProxyListCallback callback,
+      base::expected<ip_protection::GetProxyConfigResponse, std::string>
+          response);
+
+  // `FetchBlindSignedToken()` calls into the `quiche::BlindSignAuth` library to
+  // request a blind-signed auth token for use at the IP Protection proxies.
+  void FetchBlindSignedToken(int batch_size,
+                             network::mojom::IpProtectionProxyLayer proxy_layer,
+                             TryGetAuthTokensCallback callback);
+  void OnFetchBlindSignedTokenCompleted(
+      base::TimeTicks bsa_get_tokens_start_time,
+      TryGetAuthTokensCallback callback,
+      absl::StatusOr<absl::Span<quiche::BlindSignToken>>);
+
+  // Finish a call to `TryGetAuthTokens()` by recording the result and invoking
+  // its callback.
+  void TryGetAuthTokensComplete(
+      std::optional<std::vector<network::mojom::BlindSignedAuthTokenPtr>>
+          bsa_tokens,
+      TryGetAuthTokensCallback callback,
+      AwIpProtectionTryGetAuthTokensResult result);
+
+  // Calculates the backoff time for the given result, based on
+  // `last_try_get_auth_tokens_..` fields, and updates those fields.
+  std::optional<base::TimeDelta> CalculateBackoff(
+      AwIpProtectionTryGetAuthTokensResult result);
+
+  std::unique_ptr<IpProtectionProxyConfigRetriever>
+      ip_protection_proxy_config_retriever_;
+  std::unique_ptr<BlindSignMessageAndroidImpl> blind_sign_message_android_impl_;
+  std::unique_ptr<quiche::BlindSignAuth> blind_sign_auth_;
+
+  // Injected browser context.
+  raw_ptr<AwBrowserContext> aw_browser_context_;
+
+  // For testing, BlindSignAuth is accessed via its interface. In production,
+  // this is the same pointer as `blind_sign_auth_`.
+  raw_ptr<quiche::BlindSignAuthInterface> bsa_ = nullptr;
+
+  // Whether `Shutdown()` has been called.
+  bool is_shutting_down_ = false;
+
+  // The result of the last call to `TryGetAuthTokens()`, and the
+  // backoff applied to `try_again_after`. `last_try_get_auth_tokens_backoff_`
+  // will be set to `base::TimeDelta::Max()` if no further attempts to get
+  // tokens should be made. These will be updated by calls from any receiver.
+  AwIpProtectionTryGetAuthTokensResult last_try_get_auth_tokens_result_ =
+      AwIpProtectionTryGetAuthTokensResult::kSuccess;
+  std::optional<base::TimeDelta> last_try_get_auth_tokens_backoff_;
+
+  // The `mojo::Receiver` objects allowing the network service to call methods
+  // on `this`.
+  mojo::ReceiverSet<network::mojom::IpProtectionConfigGetter> receivers_;
+
+  // Similar to `receivers_`, but containing remotes for all existing
+  // IpProtectionProxyDelegates.
+  mojo::RemoteSet<network::mojom::IpProtectionProxyDelegate> remotes_;
+
+  // This must be the last member in this class.
+  base::WeakPtrFactory<AwIpProtectionConfigProvider> weak_ptr_factory_{this};
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_IP_PROTECTION_CONFIG_PROVIDER_H_
diff --git a/android_webview/browser/aw_ip_protection_config_provider_unittest.cc b/android_webview/browser/aw_ip_protection_config_provider_unittest.cc
new file mode 100644
index 0000000..df3d5ed
--- /dev/null
+++ b/android_webview/browser/aw_ip_protection_config_provider_unittest.cc
@@ -0,0 +1,502 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "android_webview/browser/aw_ip_protection_config_provider.h"
+
+#include <memory>
+#include <optional>
+
+#include "base/memory/scoped_refptr.h"
+#include "base/notreached.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/test/test_future.h"
+#include "base/time/time.h"
+#include "base/types/expected.h"
+#include "components/ip_protection/blind_sign_message_android_impl.h"
+#include "components/ip_protection/ip_protection_config_provider_helper.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/test/browser_task_environment.h"
+#include "net/third_party/quiche/src/quiche/blind_sign_auth/blind_sign_auth_interface.h"
+#include "net/third_party/quiche/src/quiche/blind_sign_auth/proto/spend_token_data.pb.h"
+#include "services/network/test/test_shared_url_loader_factory.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace android_webview {
+namespace {
+constexpr char kTryGetAuthTokensResultHistogram[] =
+    "NetworkService.AwIpProtection.TryGetAuthTokensResult";
+constexpr char kTokenBatchHistogram[] =
+    "NetworkService.AwIpProtection.TokenBatchRequestTime";
+
+class MockBlindSignAuth : public quiche::BlindSignAuthInterface {
+ public:
+  void GetTokens(std::optional<std::string> oauth_token,
+                 int num_tokens,
+                 quiche::ProxyLayer proxy_layer,
+                 quiche::BlindSignAuthServiceType /*service_type*/,
+                 quiche::SignedTokenCallback callback) override {
+    get_tokens_called_ = true;
+    oauth_token_ = oauth_token;
+    num_tokens_ = num_tokens;
+    proxy_layer_ = proxy_layer;
+
+    absl::StatusOr<absl::Span<quiche::BlindSignToken>> result;
+    if (status_.ok()) {
+      result = absl::Span<quiche::BlindSignToken>(tokens_);
+    } else {
+      result = status_;
+    }
+
+    content::GetUIThreadTaskRunner({})->PostTask(
+        FROM_HERE,
+        base::BindOnce(
+            [](quiche::SignedTokenCallback callback,
+               absl::StatusOr<absl::Span<quiche::BlindSignToken>> result) {
+              std::move(callback)(std::move(result));
+            },
+            std::move(callback), std::move(result)));
+  }
+
+  // True if `GetTokens()` was called.
+  bool get_tokens_called_;
+
+  // The token with which `GetTokens()` was called.
+  std::optional<std::string> oauth_token_;
+
+  // The num_tokens with which `GetTokens()` was called.
+  int num_tokens_;
+
+  // The proxy for which the tokens are intended for.
+  quiche::ProxyLayer proxy_layer_;
+
+  // If not Ok, the status that will be returned from `GetTokens()`.
+  absl::Status status_ = absl::OkStatus();
+
+  // The tokens that will be returned from `GetTokens()` , if `status_` is not
+  // `OkStatus`.
+  std::vector<quiche::BlindSignToken> tokens_;
+};
+
+class MockIpProtectionProxyConfigRetriever
+    : public IpProtectionProxyConfigRetriever {
+ public:
+  explicit MockIpProtectionProxyConfigRetriever(
+      std::optional<ip_protection::GetProxyConfigResponse>
+          proxy_config_response)
+      : IpProtectionProxyConfigRetriever(
+            base::MakeRefCounted<network::TestSharedURLLoaderFactory>(),
+            "test_service_type",
+            "test_api_key"),
+        proxy_config_response_(proxy_config_response) {}
+
+  void GetProxyConfig(
+      std::optional<std::string> oauth_token,
+      IpProtectionProxyConfigRetriever::GetProxyConfigCallback callback,
+      bool for_testing) override {
+    if (!proxy_config_response_.has_value()) {
+      std::move(callback).Run(base::unexpected("uhoh"));
+      return;
+    }
+    std::move(callback).Run(*proxy_config_response_);
+  }
+
+ private:
+  std::optional<ip_protection::GetProxyConfigResponse> proxy_config_response_;
+};
+
+}  // namespace
+
+class AwIpProtectionConfigProviderTest : public testing::Test {
+ protected:
+  AwIpProtectionConfigProviderTest()
+      : expiration_time_(base::Time::Now() + base::Hours(1)) {}
+
+  void SetUp() override {
+    getter_ = std::make_unique<AwIpProtectionConfigProvider>(
+        /*aw_browser_context=*/nullptr);
+    bsa_ = std::make_unique<MockBlindSignAuth>();
+    getter_->SetUpForTesting(
+        std::make_unique<MockIpProtectionProxyConfigRetriever>(std::nullopt),
+        std::make_unique<BlindSignMessageAndroidImpl>(), bsa_.get());
+  }
+
+  void TearDown() override { getter_->Shutdown(); }
+
+  // Call `TryGetAuthTokens()` and run until it completes.
+  void TryGetAuthTokens(int num_tokens,
+                        network::mojom::IpProtectionProxyLayer proxy_layer) {
+    getter_->TryGetAuthTokens(num_tokens, proxy_layer,
+                              tokens_future_.GetCallback());
+    ASSERT_TRUE(tokens_future_.Wait()) << "TryGetAuthTokens did not call back";
+  }
+
+  // Expect that the TryGetAuthTokens call returned the given tokens.
+  void ExpectTryGetAuthTokensResult(
+      std::vector<network::mojom::BlindSignedAuthTokenPtr> bsa_tokens) {
+    EXPECT_EQ(std::get<0>(tokens_future_.Get()), bsa_tokens);
+  }
+
+  // Expect that the TryGetAuthTokens call returned nullopt, with
+  // `try_again_after` at the given delta from the current time.
+  void ExpectTryGetAuthTokensResultFailed(base::TimeDelta try_again_delta) {
+    auto& [bsa_tokens, try_again_after] = tokens_future_.Get();
+    EXPECT_EQ(bsa_tokens, std::nullopt);
+    if (!bsa_tokens) {
+      EXPECT_EQ(*try_again_after, base::Time::Now() + try_again_delta);
+    }
+  }
+
+  // Run on the UI thread.
+  content::BrowserTaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+  base::test::TestFuture<
+      std::optional<std::vector<network::mojom::BlindSignedAuthTokenPtr>>,
+      std::optional<base::Time>>
+      tokens_future_;
+
+ protected:
+  base::test::TestFuture<const std::optional<std::vector<net::ProxyChain>>&>
+      proxy_list_future_;
+
+  // A convenient expiration time for fake tokens, in the future.
+  base::Time expiration_time_;
+
+  base::HistogramTester histogram_tester_;
+
+  std::unique_ptr<AwIpProtectionConfigProvider> getter_;
+  // Note: In the real implementation, `AwIpProtectionConfigProvider()` owns the
+  // BSA implementation and can't be destroyed before it, which is important
+  // because BSA takes a pointer to `AwIpProtectionConfigProvider()` when
+  // requesting tokens and calls back with it once tokens are available. Here,
+  // `getter_` doesn't own the BSA implementation, so it's important to ensure
+  // that `bsa_` gets destroyed before `getter_` when the test class is
+  // destroyed so that `bsa_` doesn't call back into a destroyed `getter_`.
+  std::unique_ptr<MockBlindSignAuth> bsa_;
+
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+// BSA gets tokens.
+TEST_F(AwIpProtectionConfigProviderTest, Success) {
+  scoped_feature_list_.InitAndEnableFeature(
+      net::features::kEnableIpProtectionProxy);
+
+  bsa_->tokens_ = {
+      IpProtectionConfigProviderHelper::CreateBlindSignTokenForTesting(
+          "single-use-1", expiration_time_),
+      IpProtectionConfigProviderHelper::CreateBlindSignTokenForTesting(
+          "single-use-2", expiration_time_)};
+
+  TryGetAuthTokens(2, network::mojom::IpProtectionProxyLayer::kProxyB);
+
+  EXPECT_TRUE(bsa_->get_tokens_called_);
+  EXPECT_EQ(bsa_->oauth_token_, std::nullopt);
+  EXPECT_EQ(bsa_->num_tokens_, 2);
+  EXPECT_EQ(bsa_->proxy_layer_, quiche::ProxyLayer::kProxyB);
+
+  std::vector<network::mojom::BlindSignedAuthTokenPtr> expected;
+  expected.push_back(IpProtectionConfigProviderHelper::
+                         CreateMockBlindSignedAuthTokenForTesting(
+                             "single-use-1", expiration_time_));
+  expected.push_back(IpProtectionConfigProviderHelper::
+                         CreateMockBlindSignedAuthTokenForTesting(
+                             "single-use-2", expiration_time_));
+
+  ExpectTryGetAuthTokensResult(std::move(expected));
+  histogram_tester_.ExpectUniqueSample(
+      kTryGetAuthTokensResultHistogram,
+      AwIpProtectionTryGetAuthTokensResult::kSuccess, 1);
+  histogram_tester_.ExpectTotalCount(kTokenBatchHistogram, 1);
+}
+
+// BSA returns no tokens.
+TEST_F(AwIpProtectionConfigProviderTest, NoTokens) {
+  scoped_feature_list_.InitAndEnableFeature(
+      net::features::kEnableIpProtectionProxy);
+
+  TryGetAuthTokens(1, network::mojom::IpProtectionProxyLayer::kProxyA);
+
+  EXPECT_TRUE(bsa_->get_tokens_called_);
+  EXPECT_EQ(bsa_->num_tokens_, 1);
+  EXPECT_EQ(bsa_->proxy_layer_, quiche::ProxyLayer::kProxyA);
+  EXPECT_EQ(bsa_->oauth_token_, std::nullopt);
+  ExpectTryGetAuthTokensResultFailed(
+      IpProtectionConfigProviderHelper::kTransientBackoff);
+  histogram_tester_.ExpectUniqueSample(
+      kTryGetAuthTokensResultHistogram,
+      AwIpProtectionTryGetAuthTokensResult::kFailedBSAOther, 1);
+  histogram_tester_.ExpectTotalCount(kTokenBatchHistogram, 0);
+}
+
+// BSA returns malformed tokens.
+TEST_F(AwIpProtectionConfigProviderTest, MalformedTokens) {
+  scoped_feature_list_.InitAndEnableFeature(
+      net::features::kEnableIpProtectionProxy);
+
+  bsa_->tokens_ = {{"invalid-token-proto-data", absl::Now() + absl::Hours(1)}};
+
+  TryGetAuthTokens(1, network::mojom::IpProtectionProxyLayer::kProxyB);
+
+  EXPECT_TRUE(bsa_->get_tokens_called_);
+  EXPECT_EQ(bsa_->num_tokens_, 1);
+  EXPECT_EQ(bsa_->proxy_layer_, quiche::ProxyLayer::kProxyB);
+  EXPECT_EQ(bsa_->oauth_token_, std::nullopt);
+  ExpectTryGetAuthTokensResultFailed(
+      IpProtectionConfigProviderHelper::kTransientBackoff);
+  histogram_tester_.ExpectUniqueSample(
+      kTryGetAuthTokensResultHistogram,
+      AwIpProtectionTryGetAuthTokensResult::kFailedBSAOther, 1);
+  histogram_tester_.ExpectTotalCount(kTokenBatchHistogram, 0);
+}
+
+// BSA returns a transient error.
+TEST_F(AwIpProtectionConfigProviderTest, BlindSignedAuthTransientError) {
+  scoped_feature_list_.InitAndEnableFeature(
+      net::features::kEnableIpProtectionProxy);
+
+  bsa_->status_ = absl::UnavailableError("uhoh");
+
+  TryGetAuthTokens(1, network::mojom::IpProtectionProxyLayer::kProxyA);
+
+  EXPECT_TRUE(bsa_->get_tokens_called_);
+  EXPECT_EQ(bsa_->num_tokens_, 1);
+  EXPECT_EQ(bsa_->proxy_layer_, quiche::ProxyLayer::kProxyA);
+  EXPECT_EQ(bsa_->oauth_token_, std::nullopt);
+  ExpectTryGetAuthTokensResultFailed(
+      IpProtectionConfigProviderHelper::kTransientBackoff);
+  histogram_tester_.ExpectUniqueSample(
+      kTryGetAuthTokensResultHistogram,
+      AwIpProtectionTryGetAuthTokensResult::kFailedBSATransient, 1);
+  histogram_tester_.ExpectTotalCount(kTokenBatchHistogram, 0);
+}
+
+// BSA returns a persistent error.
+TEST_F(AwIpProtectionConfigProviderTest, BlindSignedAuthPersistentError) {
+  scoped_feature_list_.InitAndEnableFeature(
+      net::features::kEnableIpProtectionProxy);
+
+  bsa_->status_ = absl::FailedPreconditionError("uhoh");
+
+  TryGetAuthTokens(1, network::mojom::IpProtectionProxyLayer::kProxyB);
+
+  EXPECT_TRUE(bsa_->get_tokens_called_);
+  EXPECT_EQ(bsa_->num_tokens_, 1);
+  EXPECT_EQ(bsa_->proxy_layer_, quiche::ProxyLayer::kProxyB);
+  EXPECT_EQ(bsa_->oauth_token_, std::nullopt);
+  ExpectTryGetAuthTokensResultFailed(base::TimeDelta::Max());
+  histogram_tester_.ExpectUniqueSample(
+      kTryGetAuthTokensResultHistogram,
+      AwIpProtectionTryGetAuthTokensResult::kFailedBSAPersistent, 1);
+  histogram_tester_.ExpectTotalCount(kTokenBatchHistogram, 0);
+}
+
+// BSA returns some other error.
+TEST_F(AwIpProtectionConfigProviderTest, BlindSignedTokenErrorOther) {
+  scoped_feature_list_.InitAndEnableFeature(
+      net::features::kEnableIpProtectionProxy);
+
+  bsa_->status_ = absl::UnknownError("uhoh");
+
+  TryGetAuthTokens(1, network::mojom::IpProtectionProxyLayer::kProxyB);
+
+  EXPECT_TRUE(bsa_->get_tokens_called_);
+  EXPECT_EQ(bsa_->num_tokens_, 1);
+  EXPECT_EQ(bsa_->proxy_layer_, quiche::ProxyLayer::kProxyB);
+  EXPECT_EQ(bsa_->oauth_token_, std::nullopt);
+  ExpectTryGetAuthTokensResultFailed(
+      IpProtectionConfigProviderHelper::kTransientBackoff);
+  histogram_tester_.ExpectUniqueSample(
+      kTryGetAuthTokensResultHistogram,
+      AwIpProtectionTryGetAuthTokensResult::kFailedBSAOther, 1);
+  histogram_tester_.ExpectTotalCount(kTokenBatchHistogram, 0);
+}
+
+// TryGetAuthTokens() fails because IP Protection is disabled.
+TEST_F(AwIpProtectionConfigProviderTest,
+       TryGetAuthTokens_IpProtectionDisabled) {
+  scoped_feature_list_.InitAndDisableFeature(
+      net::features::kEnableIpProtectionProxy);
+
+  TryGetAuthTokens(1, network::mojom::IpProtectionProxyLayer::kProxyA);
+
+  EXPECT_FALSE(bsa_->get_tokens_called_);
+  ExpectTryGetAuthTokensResultFailed(base::TimeDelta::Max());
+  histogram_tester_.ExpectTotalCount(kTokenBatchHistogram, 0);
+}
+
+TEST_F(AwIpProtectionConfigProviderTest, GetProxyListProxyChains) {
+  scoped_feature_list_.InitAndEnableFeature(
+      net::features::kEnableIpProtectionProxy);
+
+  ip_protection::GetProxyConfigResponse response;
+  auto* chain = response.add_proxy_chain();
+  chain->set_proxy_a("proxy1");
+  chain->set_proxy_b("proxy1b");
+  chain->set_chain_id(1);
+  chain = response.add_proxy_chain();
+  chain->set_proxy_a("proxy2");
+  chain->set_proxy_b("proxy2b");
+  chain->set_chain_id(2);
+  getter_->SetUpForTesting(
+      std::make_unique<MockIpProtectionProxyConfigRetriever>(response),
+      std::make_unique<BlindSignMessageAndroidImpl>(), bsa_.get());
+
+  getter_->GetProxyList(proxy_list_future_.GetCallback());
+  ASSERT_TRUE(proxy_list_future_.Wait()) << "GetProxyList did not call back";
+  std::vector<net::ProxyChain> exp_proxy_list = {
+      IpProtectionConfigProviderHelper::MakeChainForTesting(
+          {"proxy1", "proxy1b"}, 1),
+      IpProtectionConfigProviderHelper::MakeChainForTesting(
+          {"proxy2", "proxy2b"}, 2)};
+  EXPECT_THAT(proxy_list_future_.Get(),
+              testing::Optional(testing::ElementsAreArray(exp_proxy_list)));
+}
+
+TEST_F(AwIpProtectionConfigProviderTest, GetProxyListProxyChainsWithPorts) {
+  scoped_feature_list_.InitAndEnableFeature(
+      net::features::kEnableIpProtectionProxy);
+
+  ip_protection::GetProxyConfigResponse response;
+  auto* chain = response.add_proxy_chain();
+  chain->set_proxy_a("proxy1");
+  chain->set_proxy_b("proxy1b");
+  chain = response.add_proxy_chain();
+  chain->set_proxy_a("proxy2:80");
+  chain->set_proxy_b("proxy2");
+  chain = response.add_proxy_chain();
+  chain->set_proxy_a("proxy3:0");
+  chain->set_proxy_b("proxy4:443");
+  chain->set_chain_id(3);
+  getter_->SetUpForTesting(
+      std::make_unique<MockIpProtectionProxyConfigRetriever>(response),
+      std::make_unique<BlindSignMessageAndroidImpl>(), bsa_.get());
+
+  getter_->GetProxyList(proxy_list_future_.GetCallback());
+  ASSERT_TRUE(proxy_list_future_.Wait()) << "GetProxyList did not call back";
+  std::vector<net::ProxyChain> exp_proxy_list = {
+      IpProtectionConfigProviderHelper::MakeChainForTesting(
+          {"proxy1", "proxy1b"})};
+  exp_proxy_list.push_back(net::ProxyChain::ForIpProtection(
+      {net::ProxyServer::FromSchemeHostAndPort(net::ProxyServer::SCHEME_HTTPS,
+                                               "proxy2", 80),
+       net::ProxyServer::FromSchemeHostAndPort(net::ProxyServer::SCHEME_HTTPS,
+                                               "proxy2", std::nullopt)}));
+  exp_proxy_list.push_back(net::ProxyChain::ForIpProtection(
+      {net::ProxyServer::FromSchemeHostAndPort(net::ProxyServer::SCHEME_HTTPS,
+                                               "proxy3", "0"),
+       net::ProxyServer::FromSchemeHostAndPort(net::ProxyServer::SCHEME_HTTPS,
+                                               "proxy4", "443")},
+      3));
+  EXPECT_THAT(proxy_list_future_.Get(),
+              testing::Optional(testing::ElementsAreArray(exp_proxy_list)));
+}
+
+TEST_F(AwIpProtectionConfigProviderTest, GetProxyListProxyInvalid) {
+  scoped_feature_list_.InitAndEnableFeature(
+      net::features::kEnableIpProtectionProxy);
+
+  ip_protection::GetProxyConfigResponse response;
+  auto* chain = response.add_proxy_chain();
+  chain->set_proxy_a("]INVALID[");
+  chain->set_proxy_b("not-invalid");
+  chain = response.add_proxy_chain();
+  chain->set_proxy_a("valid");
+  chain->set_proxy_b("valid");
+  getter_->SetUpForTesting(
+      std::make_unique<MockIpProtectionProxyConfigRetriever>(response),
+      std::make_unique<BlindSignMessageAndroidImpl>(), bsa_.get());
+
+  getter_->GetProxyList(proxy_list_future_.GetCallback());
+  ASSERT_TRUE(proxy_list_future_.Wait()) << "GetProxyList did not call back";
+  std::vector<net::ProxyChain> exp_proxy_list = {
+      IpProtectionConfigProviderHelper::MakeChainForTesting(
+          {"valid", "valid"})};
+  EXPECT_THAT(proxy_list_future_.Get(),
+              testing::Optional(testing::ElementsAreArray(exp_proxy_list)));
+}
+
+TEST_F(AwIpProtectionConfigProviderTest, GetProxyListProxyInvalidChainId) {
+  scoped_feature_list_.InitAndEnableFeature(
+      net::features::kEnableIpProtectionProxy);
+
+  ip_protection::GetProxyConfigResponse response;
+  auto* chain = response.add_proxy_chain();
+  chain->set_proxy_a("proxya");
+  chain->set_proxy_b("proxyb");
+  chain->set_chain_id(999);
+  getter_->SetUpForTesting(
+      std::make_unique<MockIpProtectionProxyConfigRetriever>(response),
+      std::make_unique<BlindSignMessageAndroidImpl>(), bsa_.get());
+
+  getter_->GetProxyList(proxy_list_future_.GetCallback());
+  ASSERT_TRUE(proxy_list_future_.Wait()) << "GetProxyList did not call back";
+  // The proxy chain is still used, but the chain ID is set to the default.
+  std::vector<net::ProxyChain> exp_proxy_list = {
+      IpProtectionConfigProviderHelper::MakeChainForTesting(
+          {"proxya", "proxyb"}, net::ProxyChain::kDefaultIpProtectionChainId)};
+  EXPECT_THAT(proxy_list_future_.Get(),
+              testing::Optional(testing::ElementsAreArray(exp_proxy_list)));
+}
+
+TEST_F(AwIpProtectionConfigProviderTest, ProxyOverrideFlagsAll) {
+  std::vector<net::ProxyChain> proxy_override_list = {
+      IpProtectionConfigProviderHelper::MakeChainForTesting(
+          {"proxyAOverride", "proxyBOverride"}),
+      IpProtectionConfigProviderHelper::MakeChainForTesting(
+          {"proxyAOverride", "proxyBOverride"}),
+  };
+  scoped_feature_list_.InitAndEnableFeatureWithParameters(
+      net::features::kEnableIpProtectionProxy,
+      {
+          {net::features::kIpPrivacyProxyAHostnameOverride.name,
+           "proxyAOverride"},
+          {net::features::kIpPrivacyProxyBHostnameOverride.name,
+           "proxyBOverride"},
+      });
+  std::vector<std::vector<std::string>> proxy_list = {{"proxyA1", "proxyB1"},
+                                                      {"proxyA2", "proxyB2"}};
+  ip_protection::GetProxyConfigResponse response;
+  auto* chain = response.add_proxy_chain();
+  chain->set_proxy_a("proxyA1");
+  chain->set_proxy_b("proxyB1");
+  chain = response.add_proxy_chain();
+  chain->set_proxy_a("proxyA2");
+  chain->set_proxy_b("proxyB2");
+  getter_->SetUpForTesting(
+      std::make_unique<MockIpProtectionProxyConfigRetriever>(response),
+      std::make_unique<BlindSignMessageAndroidImpl>(), bsa_.get());
+  getter_->GetProxyList(proxy_list_future_.GetCallback());
+  ASSERT_TRUE(proxy_list_future_.Wait()) << "GetProxyList did not call back";
+  EXPECT_THAT(
+      proxy_list_future_.Get(),
+      testing::Optional(testing::ElementsAreArray(proxy_override_list)));
+}
+
+TEST_F(AwIpProtectionConfigProviderTest, GetProxyListFailure) {
+  getter_->GetProxyList(proxy_list_future_.GetCallback());
+  ASSERT_TRUE(proxy_list_future_.Wait()) << "GetProxyList did not call back";
+  EXPECT_EQ(proxy_list_future_.Get(), std::nullopt);
+}
+
+TEST_F(AwIpProtectionConfigProviderTest, GetProxyList_IpProtectionDisabled) {
+  scoped_feature_list_.InitAndDisableFeature(
+      net::features::kEnableIpProtectionProxy);
+
+  ip_protection::GetProxyConfigResponse response;
+  auto* chain = response.add_proxy_chain();
+  chain->set_proxy_a("proxy1");
+  chain->set_proxy_b("proxy1b");
+  chain->set_chain_id(1);
+  getter_->SetUpForTesting(
+      std::make_unique<MockIpProtectionProxyConfigRetriever>(response),
+      std::make_unique<BlindSignMessageAndroidImpl>(), bsa_.get());
+
+  getter_->GetProxyList(proxy_list_future_.GetCallback());
+
+  ASSERT_TRUE(proxy_list_future_.Wait()) << "GetProxyList did not call back";
+  EXPECT_EQ(proxy_list_future_.Get(), std::nullopt);
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc b/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc
index 45cd5741..b03685a19 100644
--- a/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc
+++ b/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.cc
@@ -82,11 +82,10 @@
     const security_interstitials::UnsafeResource& resource,
     const std::string& method,
     const net::HttpRequestHeaders& headers,
-    bool is_outermost_main_frame,
     bool has_user_gesture) {
   AwWebResourceRequest request(resource.url.spec(), method,
-                               is_outermost_main_frame, has_user_gesture,
-                               headers);
+                               /*in_is_outermost_main_frame=*/true,
+                               has_user_gesture, headers);
 
   content::GetUIThreadTaskRunner({})->PostTask(
       FROM_HERE,
@@ -96,8 +95,7 @@
 
 void AwUrlCheckerDelegateImpl::
     StartObservingInteractionsForDelayedBlockingPageHelper(
-        const security_interstitials::UnsafeResource& resource,
-        bool is_main_frame) {
+        const security_interstitials::UnsafeResource& resource) {
   NOTREACHED_IN_MIGRATION() << "Delayed warnings not implemented for WebView";
 }
 
diff --git a/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.h b/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.h
index 36dc34b..6650400 100644
--- a/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.h
+++ b/android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.h
@@ -47,11 +47,9 @@
       const security_interstitials::UnsafeResource& resource,
       const std::string& method,
       const net::HttpRequestHeaders& headers,
-      bool is_main_frame,
       bool has_user_gesture) override;
   void StartObservingInteractionsForDelayedBlockingPageHelper(
-      const security_interstitials::UnsafeResource& resource,
-      bool is_main_frame) override;
+      const security_interstitials::UnsafeResource& resource) override;
   bool IsUrlAllowlisted(const GURL& url) override;
   void SetPolicyAllowlistDomains(
       const std::vector<std::string>& allowlist_domains) override;
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
index fdacc89..dd679a9 100644
--- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
+++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -641,9 +641,6 @@
                 "When enabled, the real time Safe Browsing check will be called asynchronously,"
                         + " along with an additional v4 check which will be synchronous."),
         Flag.baseFeature(
-                "SafeBrowsingSkipSubResources2",
-                "When enabled, Safe Browsing will skip WebTransport and WebSockets"),
-        Flag.baseFeature(
                 "AddWarningShownTSToClientSafeBrowsingReport",
                 "When enabled, client reports will include a timestamp of when the warning was "
                         + "shown to the user"),
@@ -1031,6 +1028,7 @@
         Flag.baseFeature(
                 BlinkFeatures.STANDARDIZED_BROWSER_ZOOM,
                 "Enable conformance to the new HTML specification for CSS zoom."),
+        Flag.baseFeature("UseContextSnapshot"),
         // Add new commandline switches and features above. The final entry should have a
         // trailing comma for cleaner diffs.
     };
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidProtocolHandlerTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidProtocolHandlerTest.java
index 3f63a2b45a..34cccf1 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidProtocolHandlerTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidProtocolHandlerTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import androidx.test.filters.SmallTest;
 
 import org.junit.Assert;
@@ -23,6 +25,7 @@
 
 /** Test AndroidProtocolHandler. */
 @RunWith(Parameterized.class)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 @UseParametersRunnerFactory(AwJUnit4ClassRunnerWithParameters.Factory.class)
 public class AndroidProtocolHandlerTest extends AwParameterizedTest {
     @Rule public AwActivityTestRule mActivityTestRule;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsOriginMatcherTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsOriginMatcherTest.java
index 8468110..5b11ce22 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsOriginMatcherTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsOriginMatcherTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import android.net.Uri;
 
 import androidx.test.filters.SmallTest;
@@ -23,6 +25,7 @@
 
 /** AwContentsOriginMatcher tests. */
 @RunWith(AwJUnit4ClassRunner.class)
+@OnlyRunIn(EITHER_PROCESS) // These are unit tests
 @DoNotBatch(reason = "Shared dependencies among the tests cause conflicts during batch testing.")
 public class AwContentsOriginMatcherTest {
     @Rule public AwActivityTestRule mActivityTestRule = new AwActivityTestRule();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsStaticsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsStaticsTest.java
index c943f0abb..1f5a6e2 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsStaticsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsStaticsTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
@@ -54,6 +56,7 @@
     @Test
     @Feature({"AndroidWebView"})
     @SmallTest
+    @OnlyRunIn(EITHER_PROCESS) // This test doesn't use the renderer process
     public void testClearClientCertPreferences() throws Throwable {
         mActivityTestRule.startBrowserProcess();
         final ClearClientCertCallbackHelper callbackHelper = new ClearClientCertCallbackHelper();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwCrashyClassUtilsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwCrashyClassUtilsTest.java
index 8422a6b6..8e01f7d 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwCrashyClassUtilsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwCrashyClassUtilsTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import androidx.test.filters.SmallTest;
 
 import org.junit.Assert;
@@ -28,6 +30,7 @@
  */
 @RunWith(Parameterized.class)
 @UseParametersRunnerFactory(AwJUnit4ClassRunnerWithParameters.Factory.class)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process, they test browser crashes
 @DoNotBatch(reason = "needsBrowserProcessStarted false and @Batch are incompatible")
 public class AwCrashyClassUtilsTest extends AwParameterizedTest {
 
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwMediaIntegrityApiStatusConfigTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwMediaIntegrityApiStatusConfigTest.java
index 765885d2..ac3d1a1f 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwMediaIntegrityApiStatusConfigTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwMediaIntegrityApiStatusConfigTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import android.net.Uri;
 
 import androidx.test.filters.MediumTest;
@@ -21,6 +23,7 @@
 
 /** {@link org.chromium.android_webview.AwMediaIntegrityApiStatusConfig} tests. */
 @RunWith(AwJUnit4ClassRunner.class)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 public class AwMediaIntegrityApiStatusConfigTest {
     @Rule public AwActivityTestRule mActivityTestRule = new AwActivityTestRule();
 
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwMetricsLogUploaderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwMetricsLogUploaderTest.java
index 1007197..357384e 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwMetricsLogUploaderTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwMetricsLogUploaderTest.java
@@ -9,6 +9,8 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import androidx.test.filters.MediumTest;
 
 import org.hamcrest.Matchers;
@@ -36,6 +38,7 @@
  */
 @RunWith(AwJUnit4ClassRunner.class)
 @MediumTest
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 @Batch(Batch.PER_CLASS)
 public class AwMetricsLogUploaderTest {
     private static final ChromeUserMetricsExtension SAMPLE_TEST_METRICS_LOG =
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwPacProcessorTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwPacProcessorTest.java
index 395f44a..cfd33951 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwPacProcessorTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwPacProcessorTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import android.os.Build;
 
 import androidx.annotation.RequiresApi;
@@ -29,6 +31,7 @@
 @UseParametersRunnerFactory(AwJUnit4ClassRunnerWithParameters.Factory.class)
 @MinAndroidSdkLevel(Build.VERSION_CODES.P)
 @RequiresApi(Build.VERSION_CODES.P)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 public class AwPacProcessorTest extends AwParameterizedTest {
     private AwPacProcessor mProcessor;
 
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwSecondBrowserProcessTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwSecondBrowserProcessTest.java
index 0d2c4be..3ad72b2 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwSecondBrowserProcessTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwSecondBrowserProcessTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -33,11 +35,12 @@
 import java.util.concurrent.TimeUnit;
 
 /**
- * Tests to ensure that it is impossible to launch two browser processes within
- * the same application. Chromium is not designed for that, and attempting to do that
- * can cause data files corruption.
+ * Tests to ensure that it is impossible to launch two browser processes within the same
+ * application. Chromium is not designed for that, and attempting to do that can cause data files
+ * corruption.
  */
 @RunWith(Parameterized.class)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 @UseParametersRunnerFactory(AwJUnit4ClassRunnerWithParameters.Factory.class)
 public class AwSecondBrowserProcessTest extends AwParameterizedTest {
     @Rule public AwActivityTestRule mActivityTestRule;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwVariationsSeedFetcherTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwVariationsSeedFetcherTest.java
index 88ebfe3..8d44781d 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwVariationsSeedFetcherTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwVariationsSeedFetcherTest.java
@@ -8,7 +8,7 @@
 import static org.mockito.Mockito.when;
 import static org.mockito.MockitoAnnotations.initMocks;
 
-import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.SINGLE_PROCESS;
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
 
 import android.annotation.SuppressLint;
 import android.app.job.JobInfo;
@@ -55,7 +55,7 @@
 
 /** Test AwVariationsSeedFetcher. */
 @RunWith(AwJUnit4ClassRunner.class)
-@OnlyRunIn(SINGLE_PROCESS)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 public class AwVariationsSeedFetcherTest {
     private static final int HTTP_OK = 200;
     private static final int HTTP_NOT_FOUND = 404;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java
index f6dfad7..a6d39b55 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import android.os.Looper;
 
 import androidx.test.InstrumentationRegistry;
@@ -135,6 +137,7 @@
 
     @Test
     @SmallTest
+    @OnlyRunIn(EITHER_PROCESS) // This test doesn't use the renderer process
     @Feature({"AndroidWebView", "Privacy"})
     public void testAllowFileSchemeCookies() {
         AwCookieManager cookieManager = new AwCookieManager();
@@ -147,6 +150,7 @@
 
     @Test
     @SmallTest
+    @OnlyRunIn(EITHER_PROCESS) // This test doesn't use the renderer process
     @Feature({"AndroidWebView", "Privacy"})
     public void testAllowCookies() {
         AwCookieManager cookieManager = new AwCookieManager();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/DisableOriginTrialsSafeModeTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/DisableOriginTrialsSafeModeTest.java
index b3fa057..7a4982d 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/DisableOriginTrialsSafeModeTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/DisableOriginTrialsSafeModeTest.java
@@ -7,6 +7,8 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import androidx.test.filters.SmallTest;
 
 import org.jni_zero.JNINamespace;
@@ -29,6 +31,7 @@
 /** Tests for WebView DisableOriginTrialsSafeMode. */
 @JNINamespace("android_webview")
 @RunWith(Parameterized.class)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 @UseParametersRunnerFactory(AwJUnit4ClassRunnerWithParameters.Factory.class)
 public class DisableOriginTrialsSafeModeTest extends AwParameterizedTest {
     public static final String TAG = "DisableOriginTrialsSafeModeTest";
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/HttpAuthDatabaseTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/HttpAuthDatabaseTest.java
index 5a5caa1c..03d44b1 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/HttpAuthDatabaseTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/HttpAuthDatabaseTest.java
@@ -4,7 +4,7 @@
 
 package org.chromium.android_webview.test;
 
-import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.SINGLE_PROCESS;
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
@@ -20,7 +20,7 @@
 
 /** Test suite for HttpAuthDatabase. */
 @RunWith(AwJUnit4ClassRunner.class)
-@OnlyRunIn(SINGLE_PROCESS)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 public class HttpAuthDatabaseTest {
     private static final String TEST_DATABASE = "http_auth_for_HttpAuthDatabaseTest.db";
 
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/MetricsFilteringDecoratorTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/MetricsFilteringDecoratorTest.java
index a3d27f49..0047cfff 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/MetricsFilteringDecoratorTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/MetricsFilteringDecoratorTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import androidx.test.filters.MediumTest;
 
 import org.junit.Assert;
@@ -32,6 +34,7 @@
 /** Instrumentation tests for {@link MetricsFilteringDecorator}. */
 @RunWith(Parameterized.class)
 @UseParametersRunnerFactory(AwJUnit4ClassRunnerWithParameters.Factory.class)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 @MediumTest
 @Batch(Batch.PER_CLASS)
 public class MetricsFilteringDecoratorTest extends AwParameterizedTest {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/OnDiskFileTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/OnDiskFileTest.java
index a51af92c..e500a4e6 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/OnDiskFileTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/OnDiskFileTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import android.content.Context;
 
 import androidx.test.InstrumentationRegistry;
@@ -83,6 +85,7 @@
 
     @Test
     @SmallTest
+    @OnlyRunIn(EITHER_PROCESS) // This test doesn't use the renderer process
     @Feature({"AndroidWebView"})
     public void testCookiePathIsInsideDataDir() {
         File webViewCookiePath =
@@ -105,6 +108,7 @@
 
     @Test
     @SmallTest
+    @OnlyRunIn(EITHER_PROCESS) // This test doesn't use the renderer process
     @Feature({"AndroidWebView"})
     public void testProfilesHaveSeparateDirectories() throws Throwable {
         mActivityTestRule.startBrowserProcess();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingSafeModeTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingSafeModeTest.java
index 23a6a8b..d051119 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingSafeModeTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/SafeBrowsingSafeModeTest.java
@@ -7,6 +7,8 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import android.content.Context;
 
 import androidx.annotation.NonNull;
@@ -102,6 +104,7 @@
     }
 
     @Test
+    @OnlyRunIn(EITHER_PROCESS) // This test doesn't use the renderer process
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testSafeModeActionSavesState() throws Throwable {
@@ -111,6 +114,7 @@
     }
 
     @Test
+    @OnlyRunIn(EITHER_PROCESS) // This test doesn't use the renderer process
     @SmallTest
     @Feature({"AndroidWebView"})
     public void testInitSafeBrowsingSkipsGMSCoreCommunication() throws Throwable {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/SafeModeTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/SafeModeTest.java
index 2482506..c316098 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/SafeModeTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/SafeModeTest.java
@@ -8,6 +8,8 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import android.app.job.JobInfo;
 import android.app.job.JobScheduler;
 import android.app.job.JobWorkItem;
@@ -73,6 +75,7 @@
 /** Test WebView SafeMode. */
 @RunWith(Parameterized.class)
 @UseParametersRunnerFactory(AwJUnit4ClassRunnerWithParameters.Factory.class)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 public class SafeModeTest extends AwParameterizedTest {
     // The package name of the test shell. This is acting both as the client app and the WebView
     // provider.
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/StandaloneAwQuotaManagerBridgeTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/StandaloneAwQuotaManagerBridgeTest.java
index 892cd06..8a010607d 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/StandaloneAwQuotaManagerBridgeTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/StandaloneAwQuotaManagerBridgeTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import androidx.test.filters.SmallTest;
 
 import org.junit.Assert;
@@ -18,11 +20,12 @@
 import org.chromium.android_webview.test.util.AwQuotaManagerBridgeTestUtil;
 
 /**
- * This class tests AwQuotaManagerBridge runs without AwContents etc. It simulates
- * use case that user calls WebStorage getInstance() without WebView.
+ * This class tests AwQuotaManagerBridge runs without AwContents etc. It simulates use case that
+ * user calls WebStorage getInstance() without WebView.
  */
 @RunWith(Parameterized.class)
 @UseParametersRunnerFactory(AwJUnit4ClassRunnerWithParameters.Factory.class)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 public class StandaloneAwQuotaManagerBridgeTest extends AwParameterizedTest {
     @Rule public AwActivityTestRule mActivityTestRule;
 
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsHeadersTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/VariationsHeadersTest.java
index fecbcbf..98d4082 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsHeadersTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/VariationsHeadersTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import androidx.test.filters.MediumTest;
 
 import org.junit.Assert;
@@ -21,6 +23,7 @@
 /** Tests that the variations headers are correctly set. */
 @RunWith(Parameterized.class)
 @UseParametersRunnerFactory(AwJUnit4ClassRunnerWithParameters.Factory.class)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 @CommandLineFlags.Add({
     VariationsSwitches.DISABLE_FIELD_TRIAL_TESTING_CONFIG,
     VariationsSwitches.FORCE_VARIATION_IDS + "=4,10,34"
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsSeedHolderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/VariationsSeedHolderTest.java
index 45d4eed..9943c2a1 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsSeedHolderTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/VariationsSeedHolderTest.java
@@ -7,7 +7,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.SINGLE_PROCESS;
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
 
 import android.os.ParcelFileDescriptor;
 
@@ -37,7 +37,7 @@
 
 /** Test VariationsSeedHolder. */
 @RunWith(AwJUnit4ClassRunner.class)
-@OnlyRunIn(SINGLE_PROCESS)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 public class VariationsSeedHolderTest {
     private class TestHolder extends VariationsSeedHolder {
         private final CallbackHelper mWriteFinished; // notified after each writeSeedIfNewer
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsSeedLoaderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/VariationsSeedLoaderTest.java
index 824565d..863653b 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsSeedLoaderTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/VariationsSeedLoaderTest.java
@@ -4,7 +4,7 @@
 
 package org.chromium.android_webview.test;
 
-import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.SINGLE_PROCESS;
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
 
 import android.content.Intent;
 import android.os.Bundle;
@@ -41,7 +41,7 @@
 /** Test VariationsSeedLoader. */
 @RunWith(Parameterized.class)
 @UseParametersRunnerFactory(AwJUnit4ClassRunnerWithParameters.Factory.class)
-@OnlyRunIn(SINGLE_PROCESS)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 public class VariationsSeedLoaderTest extends AwParameterizedTest {
     private static final long CURRENT_TIME_MILLIS = 1234567890;
     private static final long EXPIRED_TIMESTAMP = 0;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/VariationsTest.java
index 0e55ac4..6cf47d01 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/VariationsTest.java
@@ -4,7 +4,7 @@
 
 package org.chromium.android_webview.test;
 
-import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.SINGLE_PROCESS;
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
 
 import androidx.test.filters.MediumTest;
 
@@ -37,7 +37,7 @@
 /** Tests that seeds saved to disk get loaded correctly on WebView startup. */
 @RunWith(Parameterized.class)
 @UseParametersRunnerFactory(AwJUnit4ClassRunnerWithParameters.Factory.class)
-@OnlyRunIn(SINGLE_PROCESS)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 public class VariationsTest extends AwParameterizedTest {
     @Rule public AwActivityTestRule mActivityTestRule;
 
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/common/services/ServiceConnectionDelayRecorderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/common/services/ServiceConnectionDelayRecorderTest.java
index 8a81c4b..b7ebecd 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/common/services/ServiceConnectionDelayRecorderTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/common/services/ServiceConnectionDelayRecorderTest.java
@@ -28,7 +28,7 @@
 
 /** Unit tests for {@link ServiceConnectionDelayRecorder}. */
 @RunWith(AwJUnit4ClassRunner.class)
-@OnlyRunIn(EITHER_PROCESS)
+@OnlyRunIn(EITHER_PROCESS) // These are unit tests
 @DoNotBatch(reason = "To make sure all bound services are properly killed between tests.")
 public class ServiceConnectionDelayRecorderTest {
     // Test class that increments time with multiples of 1000 ms.
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/component_updater/EmbeddedComponentLoaderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/component_updater/EmbeddedComponentLoaderTest.java
index 043bf95b..7c91d2a 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/component_updater/EmbeddedComponentLoaderTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/component_updater/EmbeddedComponentLoaderTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test.component_updater;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import android.content.Intent;
 
 import androidx.test.filters.MediumTest;
@@ -25,6 +27,7 @@
 import org.chromium.android_webview.test.AwJUnit4ClassRunnerWithParameters;
 import org.chromium.android_webview.test.AwParameterizedTest;
 import org.chromium.android_webview.test.AwSettingsMutation;
+import org.chromium.android_webview.test.OnlyRunIn;
 import org.chromium.android_webview.test.util.EmbeddedComponentLoaderFactory;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.FileUtils;
@@ -41,9 +44,10 @@
  * Test for {@link EmbeddedComponentLoader}. It's an integeration-like test where it uses mock
  * native loaders and connect to {@link MockComponentProviderService}.
  *
- * Some test assertion are made in test/browser/embedded_component_loader_test_helper.cc
+ * <p>Some test assertion are made in test/browser/embedded_component_loader_test_helper.cc
  */
 @RunWith(Parameterized.class)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 @UseParametersRunnerFactory(AwJUnit4ClassRunnerWithParameters.Factory.class)
 @JNINamespace("component_updater")
 public class EmbeddedComponentLoaderTest extends AwParameterizedTest {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/devui/util/ComponentsInfoLoaderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/devui/util/ComponentsInfoLoaderTest.java
index 39d967f..0b49dabd 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/devui/util/ComponentsInfoLoaderTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/devui/util/ComponentsInfoLoaderTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test.devui.util;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import androidx.test.filters.SmallTest;
 
 import org.junit.Assert;
@@ -15,6 +17,7 @@
 import org.chromium.android_webview.devui.util.ComponentInfo;
 import org.chromium.android_webview.devui.util.ComponentsInfoLoader;
 import org.chromium.android_webview.test.AwJUnit4ClassRunner;
+import org.chromium.android_webview.test.OnlyRunIn;
 import org.chromium.base.test.util.Batch;
 
 import java.io.File;
@@ -23,6 +26,7 @@
 
 /** Unit tests for ComponentsInfoLoader. */
 @RunWith(AwJUnit4ClassRunner.class)
+@OnlyRunIn(EITHER_PROCESS) // These are unit tests
 @Batch(Batch.UNIT_TESTS)
 public class ComponentsInfoLoaderTest {
     @Rule public TemporaryFolder mTempDir = new TemporaryFolder();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/AwComponentUpdateServiceTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/AwComponentUpdateServiceTest.java
index 09bd8c7..38f08b68 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/services/AwComponentUpdateServiceTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/AwComponentUpdateServiceTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test.services;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import android.content.Context;
 import android.content.SharedPreferences;
 
@@ -18,6 +20,7 @@
 import org.chromium.android_webview.nonembedded.AwComponentUpdateService;
 import org.chromium.android_webview.nonembedded.AwNonembeddedUmaRecorder;
 import org.chromium.android_webview.test.AwJUnit4ClassRunner;
+import org.chromium.android_webview.test.OnlyRunIn;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.metrics.UmaRecorderHolder;
@@ -27,6 +30,7 @@
 
 /** Tests for {@link org.chromium.android_webview.nonembedded.AwComponentUpdateService}. */
 @RunWith(AwJUnit4ClassRunner.class)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 @Batch(Batch.PER_CLASS)
 public class AwComponentUpdateServiceTest {
     private CallbackHelper mCallbackHelper = new CallbackHelper();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/AwNetLogServiceTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/AwNetLogServiceTest.java
index b2c88919..e5b9156 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/services/AwNetLogServiceTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/AwNetLogServiceTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test.services;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import android.content.Context;
 import android.content.Intent;
 import android.os.ParcelFileDescriptor;
@@ -19,6 +21,7 @@
 import org.chromium.android_webview.common.services.INetLogService;
 import org.chromium.android_webview.services.AwNetLogService;
 import org.chromium.android_webview.test.AwJUnit4ClassRunner;
+import org.chromium.android_webview.test.OnlyRunIn;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
 import org.chromium.base.test.util.Batch;
@@ -32,6 +35,7 @@
  * services are properly killed between tests.
  */
 @RunWith(AwJUnit4ClassRunner.class)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 @Batch(Batch.PER_CLASS)
 public class AwNetLogServiceTest {
     private static final String TAG = "AwNetLogServiceTest";
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/ComponentsProviderServiceTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/ComponentsProviderServiceTest.java
index 59746cc..cbb99da 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/services/ComponentsProviderServiceTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/ComponentsProviderServiceTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test.services;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import android.app.job.JobScheduler;
 import android.content.ComponentName;
 import android.content.Context;
@@ -30,6 +32,7 @@
 import org.chromium.android_webview.services.SafeModeService;
 import org.chromium.android_webview.test.AwActivityTestRule;
 import org.chromium.android_webview.test.AwJUnit4ClassRunner;
+import org.chromium.android_webview.test.OnlyRunIn;
 import org.chromium.android_webview.variations.VariationsSeedSafeModeAction;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.FileUtils;
@@ -77,6 +80,7 @@
      * service is unbound and killed, and the process is restarted between tests.
      */
     @RunWith(AwJUnit4ClassRunner.class)
+    @OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
     public static class AutoBindServiceTests {
         private ServiceConnectionHelper mConnection;
         private IComponentsProviderService mService;
@@ -283,11 +287,12 @@
     }
 
     /**
-     * This subclass groups tests that manually create the service object, unlike tests that
-     * bind the service (see {@link AutoBindServiceTests}). Since these tests don't rely on
-     * binding the service, they can be ran as unit tests.
+     * This subclass groups tests that manually create the service object, unlike tests that bind
+     * the service (see {@link AutoBindServiceTests}). Since these tests don't rely on binding the
+     * service, they can be ran as unit tests.
      */
     @RunWith(AwJUnit4ClassRunner.class)
+    @OnlyRunIn(EITHER_PROCESS) // These are unit tests
     @Batch(Batch.UNIT_TESTS)
     public static class ServiceOnCreateTests {
         private final ComponentsProviderService mService = new ComponentsProviderService();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/CrashLoggingUtilsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/CrashLoggingUtilsTest.java
index cc3d69e..44c93381 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/services/CrashLoggingUtilsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/CrashLoggingUtilsTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test.services;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import androidx.test.filters.MediumTest;
 
 import org.json.JSONException;
@@ -16,6 +18,7 @@
 import org.chromium.android_webview.nonembedded.crash.CrashInfo;
 import org.chromium.android_webview.services.CrashLoggingUtils;
 import org.chromium.android_webview.test.AwJUnit4ClassRunner;
+import org.chromium.android_webview.test.OnlyRunIn;
 import org.chromium.base.test.util.Batch;
 
 import java.io.File;
@@ -26,6 +29,7 @@
 
 /** Tests for {@link CrashLoggingUtils}. */
 @RunWith(AwJUnit4ClassRunner.class)
+@OnlyRunIn(EITHER_PROCESS) // These are unit tests
 @Batch(Batch.UNIT_TESTS)
 public class CrashLoggingUtilsTest {
     private static final String TEST_CRASH_LOCAL_ID = "abc1234";
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/CrashReceiverServiceTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/CrashReceiverServiceTest.java
index 24b44a7..a54a8df1 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/services/CrashReceiverServiceTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/CrashReceiverServiceTest.java
@@ -4,7 +4,7 @@
 
 package org.chromium.android_webview.test.services;
 
-import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.SINGLE_PROCESS;
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
 
 import android.os.ParcelFileDescriptor;
 
@@ -30,10 +30,12 @@
  * they don't actually launch any services or other components.
  */
 @RunWith(AwJUnit4ClassRunner.class)
-@OnlyRunIn(SINGLE_PROCESS)
+@OnlyRunIn(EITHER_PROCESS) // These are unit tests
 @Batch(Batch.UNIT_TESTS)
 public class CrashReceiverServiceTest {
-    /** Ensure that the minidump copying doesn't trigger when we pass it invalid file descriptors. */
+    /**
+     * Ensure that the minidump copying doesn't trigger when we pass it invalid file descriptors.
+     */
     @Test
     @MediumTest
     public void testCopyingAbortsForInvalidFds() {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/MetricsBridgeServiceTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/MetricsBridgeServiceTest.java
index 338ef5d..f09c112 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/services/MetricsBridgeServiceTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/MetricsBridgeServiceTest.java
@@ -4,7 +4,7 @@
 
 package org.chromium.android_webview.test.services;
 
-import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.SINGLE_PROCESS;
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
 import static org.chromium.android_webview.test.services.MetricsBridgeServiceUnitTest.RETRIEVE_METRICS_TASK_STATUS_SUCCESS_RECORD;
 
 import android.content.Context;
@@ -31,7 +31,7 @@
  * services are properly killed between tests.
  */
 @RunWith(AwJUnit4ClassRunner.class)
-@OnlyRunIn(SINGLE_PROCESS)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 public class MetricsBridgeServiceTest {
     @Test
     @MediumTest
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/MetricsBridgeServiceUnitTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/MetricsBridgeServiceUnitTest.java
index 7b4362db..36644d35 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/services/MetricsBridgeServiceUnitTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/MetricsBridgeServiceUnitTest.java
@@ -4,7 +4,7 @@
 
 package org.chromium.android_webview.test.services;
 
-import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.SINGLE_PROCESS;
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
 
 import android.os.IBinder;
 
@@ -40,7 +40,7 @@
  * they don't actually launch any services or other components.
  */
 @RunWith(AwJUnit4ClassRunner.class)
-@OnlyRunIn(SINGLE_PROCESS)
+@OnlyRunIn(EITHER_PROCESS) // These are unit tests
 @Batch(Batch.UNIT_TESTS)
 public class MetricsBridgeServiceUnitTest {
     public static final byte[] PARSING_LOG_RESULT_SUCCESS_RECORD =
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/MetricsUploadServiceTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/MetricsUploadServiceTest.java
index 4f174b2..9eb52746 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/services/MetricsUploadServiceTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/MetricsUploadServiceTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.android_webview.test.services;
 
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
+
 import android.content.Context;
 import android.content.Intent;
 
@@ -19,6 +21,7 @@
 import org.chromium.android_webview.services.MetricsUploadService;
 import org.chromium.android_webview.test.AwJUnit4ClassRunner;
 import org.chromium.android_webview.test.MetricsTestPlatformServiceBridge;
+import org.chromium.android_webview.test.OnlyRunIn;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.test.util.Batch;
 import org.chromium.components.metrics.ChromeUserMetricsExtensionProtos.ChromeUserMetricsExtension;
@@ -30,6 +33,7 @@
  * services are properly killed between tests.
  */
 @RunWith(AwJUnit4ClassRunner.class)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 @Batch(Batch.PER_CLASS)
 @MediumTest
 public class MetricsUploadServiceTest {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/MinidumpUploadJobTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/MinidumpUploadJobTest.java
index 8f03524..d598384 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/services/MinidumpUploadJobTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/MinidumpUploadJobTest.java
@@ -4,7 +4,7 @@
 
 package org.chromium.android_webview.test.services;
 
-import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.SINGLE_PROCESS;
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
 
 import android.os.ParcelFileDescriptor;
@@ -59,7 +59,7 @@
  * to leave them unbatched to avoid possible state leaking between tests.
  */
 @RunWith(AwJUnit4ClassRunner.class)
-@OnlyRunIn(SINGLE_PROCESS)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 @DoNotBatch(reason = "These tests load the native library so batching might leak state")
 public class MinidumpUploadJobTest {
     @Rule
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/VariationsSeedServerTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/VariationsSeedServerTest.java
index 6a07918..98818cc 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/services/VariationsSeedServerTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/VariationsSeedServerTest.java
@@ -4,7 +4,7 @@
 
 package org.chromium.android_webview.test.services;
 
-import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.SINGLE_PROCESS;
+import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.EITHER_PROCESS;
 
 import android.content.Context;
 import android.content.Intent;
@@ -41,7 +41,7 @@
  * properly killed between tests.
  */
 @RunWith(AwJUnit4ClassRunner.class)
-@OnlyRunIn(SINGLE_PROCESS)
+@OnlyRunIn(EITHER_PROCESS) // These tests don't use the renderer process
 public class VariationsSeedServerTest {
     private File mTempFile;
 
diff --git a/android_webview/test/BUILD.gn b/android_webview/test/BUILD.gn
index 109d83b..21c793aa 100644
--- a/android_webview/test/BUILD.gn
+++ b/android_webview/test/BUILD.gn
@@ -576,6 +576,7 @@
     "//components/embedder_support/android:util",
     "//components/embedder_support/android/metrics:metrics",
     "//components/flags_ui:flags_ui",
+    "//components/ip_protection:ip_protection",
     "//components/metrics",
     "//components/metrics:component_metrics",
     "//components/metrics:content",
@@ -595,8 +596,10 @@
     "//mojo/core/embedder",
     "//net:net",
     "//net:test_support",
+    "//net/third_party/quiche:blind_sign_auth",
     "//services/cert_verifier/public/mojom",
     "//services/network:test_support",
+    "//third_party/anonymous_tokens:anonymous_tokens_cc_proto",
     "//ui/base:ui_base_jni_headers",
     "//ui/gl",
     "//ui/gl:test_support",
@@ -619,6 +622,7 @@
     "../browser/aw_feature_entries_unittest.cc",
     "../browser/aw_field_trials_unittest.cc",
     "../browser/aw_form_database_service_unittest.cc",
+    "../browser/aw_ip_protection_config_provider_unittest.cc",
     "../browser/aw_media_url_interceptor_unittest.cc",
     "../browser/aw_pac_processor_unittest.cc",
     "../browser/aw_permission_manager_unittest.cc",
diff --git a/ash/ash_prefs.cc b/ash/ash_prefs.cc
index 3e20984..d57f1e90 100644
--- a/ash/ash_prefs.cc
+++ b/ash/ash_prefs.cc
@@ -43,6 +43,7 @@
 #include "ash/shelf/shelf_controller.h"
 #include "ash/style/color_palette_controller.h"
 #include "ash/style/dark_light_mode_controller_impl.h"
+#include "ash/system/bluetooth/bluetooth_device_status_ui_handler.h"
 #include "ash/system/brightness/brightness_controller_chromeos.h"
 #include "ash/system/camera/autozoom_controller_impl.h"
 #include "ash/system/camera/autozoom_nudge_controller.h"
@@ -242,6 +243,7 @@
   PowerNotificationController::RegisterLocalStatePrefs(registry);
   quick_pair::ScanningEnabledProvider::RegisterLocalStatePrefs(registry);
   InputDeviceSettingsMetadataManager::RegisterLocalStatePrefs(registry);
+  BluetoothDeviceStatusUiHandler::RegisterLocalStatePrefs(registry);
 
   if (for_test) {
     registry->RegisterBooleanPref(prefs::kOwnerPrimaryMouseButtonRight, false);
diff --git a/ash/assistant/assistant_alarm_timer_controller_impl.cc b/ash/assistant/assistant_alarm_timer_controller_impl.cc
index ad171cd..1e931c8 100644
--- a/ash/assistant/assistant_alarm_timer_controller_impl.cc
+++ b/ash/assistant/assistant_alarm_timer_controller_impl.cc
@@ -247,7 +247,7 @@
   notification.grouping_key = kTimerNotificationGroupingKey;
   notification.priority = CreateTimerNotificationPriority(timer);
   notification.remove_on_click = false;
-  notification.is_pinned = true;
+  notification.is_pinned = false;
 
   // If we are creating a notification to replace an |existing_notification| and
   // our new notification has higher priority, we want the system to "renotify"
diff --git a/ash/assistant/assistant_alarm_timer_controller_unittest.cc b/ash/assistant/assistant_alarm_timer_controller_unittest.cc
index 276713be..bdc8456 100644
--- a/ash/assistant/assistant_alarm_timer_controller_unittest.cc
+++ b/ash/assistant/assistant_alarm_timer_controller_unittest.cc
@@ -720,17 +720,4 @@
             notification_model_observer.last_notification());
 }
 
-// Tests that a notification is added for a timer and is pinned.
-TEST_F(AssistantAlarmTimerControllerTest, TimerNotificationIsPinned) {
-  // Observe notifications.
-  ScopedNotificationModelObserver observer;
-
-  // Schedule a timer.
-  ScheduleTimer{kTimerId};
-
-  // Make assertions about the notification.
-  EXPECT_EQ(ExpectedNotification().WithClientId(kClientId).WithIsPinned(true),
-            observer.last_notification());
-}
-
 }  // namespace ash
diff --git a/ash/constants/ash_pref_names.h b/ash/constants/ash_pref_names.h
index ef6372f..6e7006f 100644
--- a/ash/constants/ash_pref_names.h
+++ b/ash/constants/ash_pref_names.h
@@ -1421,6 +1421,16 @@
 inline constexpr char kSystemBluetoothAdapterEnabled[] =
     "ash.system.bluetooth.adapter_enabled";
 
+// An integer pref counting the number of times bluetooth connection toast has
+// been displayed.
+inline constexpr char kBluetoothConnectionToastShownCount[] =
+    "ash.bluetooth.connection_toast_shown_count";
+
+// A time pref storing the start time for counting the number of times the
+// bluetooth connection toast has been displayed.
+inline constexpr char kBluetoothToastCountStartTime[] =
+    "ash.bluetooth.toast_count_start_time";
+
 // A boolean pref indicating whether the camera is allowed to be used.
 inline constexpr char kUserCameraAllowed[] = "ash.user.camera_allowed";
 
diff --git a/ash/shell.cc b/ash/shell.cc
index f0fe7ba8..8ea6d37 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -1733,7 +1733,7 @@
       std::make_unique<VideoActivityNotifier>(video_detector_.get());
   bluetooth_state_cache_ = std::make_unique<BluetoothStateCache>();
   bluetooth_device_status_ui_handler_ =
-      std::make_unique<BluetoothDeviceStatusUiHandler>();
+      std::make_unique<BluetoothDeviceStatusUiHandler>(local_state_);
   bluetooth_notification_controller_ =
       std::make_unique<BluetoothNotificationController>(
           message_center::MessageCenter::Get());
diff --git a/ash/strings/ash_strings_bs.xtb b/ash/strings/ash_strings_bs.xtb
index 17a3b340..6779098a9 100644
--- a/ash/strings/ash_strings_bs.xtb
+++ b/ash/strings/ash_strings_bs.xtb
@@ -899,6 +899,7 @@
 <translation id="4381031910344220229">Ovo omogućava pristup mikrofonu za aplikaciju <ph name="APP_NAME" /> te sve druge aplikacije i web lokacije koje imaju odobrenje za njega</translation>
 <translation id="4382340674111381977">Povratak na prethodnu stranicu</translation>
 <translation id="4389184120735010762">Pritisnuli ste prečicu na tastaturi za lupu priključne stanice. Želite li je uključiti?</translation>
+<translation id="4394466652057229831">Kliknite desnom tipkom radi sažimanja</translation>
 <translation id="439598569299422042">Pauzirano, <ph name="SIZE_INFO" /></translation>
 <translation id="440113666232554208">Nije moguće sačuvati snimanje ekrana</translation>
 <translation id="4405151984121254935">Vrsta povezanog perifernog uređaja nije podržana</translation>
@@ -1933,6 +1934,7 @@
 <translation id="8113423164597455979">Uključeno, sve</translation>
 <translation id="8113515504791187892">Dugme Odaberite za govor</translation>
 <translation id="8120151603115102514">Vaš telefon nema zaključani ekran. Da otključate Chromebook, unesite lozinku.</translation>
+<translation id="8120249852906205273">Ponovno pokreni</translation>
 <translation id="8127095419621171197">Otvorite aplikaciju Kalkulator</translation>
 <translation id="8129620843620772246"><ph name="TEMPERATURE_C" /> °C</translation>
 <translation id="8130528849632411619">Vraćanje na početak dokumenta</translation>
@@ -2027,6 +2029,7 @@
 <translation id="85123341071060231">Bluetooth na vašem Chromebooku je isključen. Da otključate Chromebook, unesite lozinku.</translation>
 <translation id="8513108775083588393">Aut. rotiranje</translation>
 <translation id="851458219935658693">Prikazivanje prozora s trenutne radne površine, odabrano je dugme za izbor</translation>
+<translation id="851660987304951246">Upotrijebite značajku Pomozi mi čitati da biste brzo saželi sadržaj ili postavili pitanja</translation>
 <translation id="8517041960877371778">Moguće je da se vaš uređaj <ph name="DEVICE_TYPE" /> neće puniti dok je uključen.</translation>
 <translation id="852060496139946719">{NUM_APPS,plural, =1{Ulazom mikrofona upravlja aplikacija <ph name="APP_NAME" />}one{Ulazom mikrofona upravlja # aplikacija}few{Ulazom mikrofona upravljaju # aplikacije}other{Ulazom mikrofona upravlja # aplikacija}}</translation>
 <translation id="8535393432370007982">Poništavanje načina sortiranja po boji</translation>
diff --git a/ash/strings/ash_strings_hr.xtb b/ash/strings/ash_strings_hr.xtb
index 10d75819..2cd35ea 100644
--- a/ash/strings/ash_strings_hr.xtb
+++ b/ash/strings/ash_strings_hr.xtb
@@ -899,6 +899,7 @@
 <translation id="4381031910344220229">Omogućuje pristup mikrofonu za aplikaciju <ph name="APP_NAME" /> i sve aplikacije i web-lokacije s dopuštenjem za mikrofon</translation>
 <translation id="4382340674111381977">Povratak na prethodnu stranicu</translation>
 <translation id="4389184120735010762">Pritisnuli ste tipkovni prečac za usidreno povećalo. Želite li ga uključiti?</translation>
+<translation id="4394466652057229831">Kliknite desnom tipkom radi sažimanja</translation>
 <translation id="439598569299422042">Pauzirano, <ph name="SIZE_INFO" /></translation>
 <translation id="440113666232554208">Spremanje zaslonske prezentacije nije uspjelo</translation>
 <translation id="4405151984121254935">Povezani periferni uređaj nije podržan</translation>
@@ -1933,6 +1934,7 @@
 <translation id="8113423164597455979">Uklj., sve ap.</translation>
 <translation id="8113515504791187892">Gumb odabira za govor</translation>
 <translation id="8120151603115102514">Telefon nema zaključani zaslon. Da biste otključali Chromebook, unesite zaporku.</translation>
+<translation id="8120249852906205273">Ponovno pokreni</translation>
 <translation id="8127095419621171197">Otvaranje aplikacije Kalkulator</translation>
 <translation id="8129620843620772246"><ph name="TEMPERATURE_C" />° C</translation>
 <translation id="8130528849632411619">Prelazak na početak dokumenta</translation>
@@ -2027,6 +2029,7 @@
 <translation id="85123341071060231">Bluetooth na Chromebooku je isključen. Da biste otključali Chromebook, unesite zaporku.</translation>
 <translation id="8513108775083588393">Autom. zakret.</translation>
 <translation id="851458219935658693">Prikaži prozore s trenutačne radne površine, odabran je izborni gumb</translation>
+<translation id="851660987304951246">Upotrijebite značajku Pomozi mi čitati da biste brzo saželi sadržaj ili postavili pitanja</translation>
 <translation id="8517041960877371778">Uređaj <ph name="DEVICE_TYPE" /> možda se neće puniti dok je uključen.</translation>
 <translation id="852060496139946719">{NUM_APPS,plural, =1{Ulazom mikrofona upravlja aplikacija <ph name="APP_NAME" />}one{Ulazom mikrofona upravlja # aplikacija}few{Ulazom mikrofona upravlja # aplikacije}other{Ulazom mikrofona upravlja # aplikacija}}</translation>
 <translation id="8535393432370007982">Poništavanje poretka po boji</translation>
diff --git a/ash/strings/ash_strings_hy.xtb b/ash/strings/ash_strings_hy.xtb
index f4836555..de83d1f 100644
--- a/ash/strings/ash_strings_hy.xtb
+++ b/ash/strings/ash_strings_hy.xtb
@@ -119,6 +119,7 @@
 <translation id="1383876407941801731">Որոնում</translation>
 <translation id="1391102559483454063">Միացված է</translation>
 <translation id="1394698770495054737">Լրիվ շաղում</translation>
+<translation id="1395878931462960119">{DAYS,plural, =1{1 օր առաջ}one{# օր առաջ}other{# օր առաջ}}</translation>
 <translation id="1404963891829069586">Առանց շեղումների ռեժիմի ձայներ</translation>
 <translation id="1407069428457324124">Մուգ թեմա</translation>
 <translation id="1410568680128842168"><ph name="DATE_CELL_TOOL_TIP" />։ Մի ամսաթվից մյուսին անցնելու համար օգտագործեք սլաքի ստեղները։</translation>
@@ -209,6 +210,7 @@
 <translation id="174102739345480129">Նշիչն անջատված է։</translation>
 <translation id="1743570585616704562">Չճանաչվեց</translation>
 <translation id="1743927604032653654">Ծալել «<ph name="NOTIFICATION_TITLE" />» ծանուցումը</translation>
+<translation id="1744435831291625602">{HOURS,plural, =0{1 ժամվա ընթացքում}=1{1 ժամ առաջ}one{# ժ առաջ}other{# ժ առաջ}}</translation>
 <translation id="1746730358044914197">Ներածման եղանակները կարգավորվում են ձեր ադմինիստրատորի կողմից:</translation>
 <translation id="1747336645387973286">վերջնաժամկետը՝ <ph name="DUE_DATE" /></translation>
 <translation id="1747827819627189109">Էկրանի ստեղնաշարը միացված է</translation>
@@ -346,6 +348,7 @@
 <translation id="2359808026110333948">Շարունակել</translation>
 <translation id="2360398059912971776">մարտկոց</translation>
 <translation id="2361210043495191221">Միացնել/անջատել Wi-Fi-ը։ <ph name="STATE" />։</translation>
+<translation id="236574664504281623">Ուղարկվել է <ph name="SESSION_NAME" />-ից</translation>
 <translation id="2367186422933365202">Չհաջողվեց մուտք գործել Chromebook</translation>
 <translation id="2367972762794486313">Ցույց տալ հավելվածները</translation>
 <translation id="2368828502825385061">Տեղորոշել</translation>
@@ -506,6 +509,7 @@
 <translation id="2963773877003373896">mod3</translation>
 <translation id="2965227184985674128">Միացնե՞լ խոսափողի օգտագործման թույլտվությունը</translation>
 <translation id="296762781903199866">Չհաջողվեց ներբեռնել <ph name="LANGUAGE" /> լեզվով խոսքի ճանաչման ֆայլերը</translation>
+<translation id="2968761508099987738">Ձեր ընթացիկ տեղադրությունը ներկայումս չի աջակցվում։</translation>
 <translation id="2970920913501714344">Տեղադրել հավելվածներ, ընդլայնումներ և թեմաներ</translation>
 <translation id="2977598380246111477">Հաջորդ համարը</translation>
 <translation id="2985148236010982088">Տեսնել բոլոր հավելվածները</translation>
@@ -979,6 +983,7 @@
 <translation id="468293128311738995">Հավելվածներ ձեր հեռախոսից</translation>
 <translation id="4690510401873698237">Դարակը ներքևում է</translation>
 <translation id="4696813013609194136">Մուտքագրեք ծնողի մուտքի կոդը</translation>
+<translation id="4697357603686181098">Այս հարցով չեմ կարող օգնել։ Փորձեք մեկ այլ հարցում։</translation>
 <translation id="4702647871202761252">Գաղտնիության էկրանն անջատված է</translation>
 <translation id="4706121060329443414">Ավելի ուշ մենք կփորձենք նորից ներբեռնել ֆայլերը։ Իսկ հիմա խոսքի ձայնագրությունը կփոխանցվի Google-ին՝ մշակման համար։</translation>
 <translation id="470644585772471629">Գունաշրջում</translation>
@@ -1901,6 +1906,7 @@
 <translation id="7982878511129296052">Անջատվում է…</translation>
 <translation id="7984197416080286869">Մատնահետքով ապակողպման փորձերը չափից շատ են</translation>
 <translation id="798779949890829624">Այս կարգավորումը կառավարվում է ձեր ադմինիստրատորի կողմից</translation>
+<translation id="7989206653429884947">Հաճախ է բացվում</translation>
 <translation id="799296642788192631">Դուք կարող եք ամրացնել կարևոր ֆայլերը։ Ամրացնելու համար պահեք մկնիկի նշորդը տարրի վրա կամ բացեք «Ֆայլեր» հավելվածը և սեղմեք մկնիկի աջ կոճակը տարրի վրա։</translation>
 <translation id="7994370417837006925">Բազմակի մուտք</translation>
 <translation id="7995804128062002838">Չհաջողվեց լուսանկարել էկրանը</translation>
@@ -2085,6 +2091,7 @@
 <translation id="8747464587821437069"><ph name="CAMERA_AND_MICROPHONE_ACCESS_STATUS" />,
         <ph name="SCREEN_SHARE_STATUS" /></translation>
 <translation id="8749787185286745219">Ժամանակը սպառվել է։ Կեցցե՛ք։ 🎉</translation>
+<translation id="8753368202781196133">Այս լեզուն ներկայումս չի աջակցվում։</translation>
 <translation id="8755498163081687682"><ph name="ORIGIN_NAME" /> կայքին/հավելվածին անհրաժեշտ է, որ հաստատեք ձեր ինքնությունը</translation>
 <translation id="875593634123171288">Ցուցադրել VPN-ի կարգավորումները</translation>
 <translation id="8756799553341497810">Այս դիտակերպից դուրս գալուց հետո կարող եք սկսել հարմարեցնել ձեր հավելվածների դասավորությունը։</translation>
diff --git a/ash/strings/ash_strings_iw.xtb b/ash/strings/ash_strings_iw.xtb
index 92bd77c..0361db0 100644
--- a/ash/strings/ash_strings_iw.xtb
+++ b/ash/strings/ash_strings_iw.xtb
@@ -80,6 +80,7 @@
 <translation id="1247519845643687288">אפליקציות אחרונות</translation>
 <translation id="1252999807265626933">טעינה מ-<ph name="POWER_SOURCE" /></translation>
 <translation id="1255033239764210633">מה מזג האוויר?</translation>
+<translation id="1256734167083229794">‏לחצת על מקש הקיצור של 'מגדיל למסך מלא'. אפשר להשתמש ב-<ph name="ZOOM_IN_ACCELERATOR" /> כדי להגדיל את התצוגה וב-<ph name="ZOOM_OUT_ACCELERATOR" /> כדי להקטין את התצוגה. כדי לזוז במסך כשמגדילים את התצוגה, משתמשים ב-Ctrl‏ + Alt + מקשי החיצים.</translation>
 <translation id="1269405891096105529">אין תמיכה בציוד היקפי במצב אורח</translation>
 <translation id="1270290102613614947">המקלדת שמופיעה במסך מושבתת</translation>
 <translation id="1272079795634619415">הפסקה</translation>
@@ -262,6 +263,7 @@
 <translation id="1969011864782743497">‏<ph name="DEVICE_NAME" />‏ (USB)</translation>
 <translation id="1971815855639997522">‏שולחן העבודה הווירטואלי והחלונות הוסרו. כדי לבטל את הפעולה, מקישים על Control + Z.</translation>
 <translation id="1972950159383891558">שלום, <ph name="USERNAME" /></translation>
+<translation id="1977686871076551563">התכונה 'מצב היפוך צבעים' מופעלת. אפשר להקיש שוב על <ph name="ACCELERATOR" /> כדי להשבית אותה.</translation>
 <translation id="1978498689038657292">קלט טקסט</translation>
 <translation id="1980808257969311265">הצטרפות ל-'<ph name="EVENT_SUMMARY" />'</translation>
 <translation id="1982717156487272186">הצגת השבוע הקודם</translation>
@@ -1179,6 +1181,7 @@
 <translation id="5377367976106153749">להפעיל את הגישה למצלמה?</translation>
 <translation id="5379115545237091094">יותר מדי ניסיונות</translation>
 <translation id="5391307769715781764">להחליף את שולחן העבודה השמור?</translation>
+<translation id="5392327145184648521">מתבצע חישוב של אחוז הטעינה...</translation>
 <translation id="5393156353051693207">לוחצים לחיצה ארוכה במקום כלשהו כדי למיין מחדש את האפליקציות</translation>
 <translation id="5395308026110844773"><ph name="DRAGGED_APP_NAME" /> מעל <ph name="IN_PLACE_APP" />. יש לשחרר כדי ליצור תיקייה.</translation>
 <translation id="5397578532367286026">‏המנהל (<ph name="MANAGER_EMAIL" />) יכול לבדוק את השימוש וההיסטוריה של משתמש זה ב-chrome.com.</translation>
@@ -1233,6 +1236,7 @@
 <translation id="5577281275355252094">‏יש לבדוק שה-Bluetooth פועל בטלפון כדי להשתמש ב-Phone Hub</translation>
 <translation id="5578188167649348993">זיכרון</translation>
 <translation id="5580000943347215299">ספרייה</translation>
+<translation id="5586388332127302891">התכונה 'זכוכית מגדלת במצב מעוגן' מופעלת. אפשר להקיש שוב על <ph name="ACCELERATOR" /> כדי להשבית אותה.</translation>
 <translation id="5587506661873751671">ההורדה מתבצעת <ph name="DOWNLOAD_PERCENT" />%</translation>
 <translation id="558849140439112033">יש לגרור כדי לבחור אזור לצילום</translation>
 <translation id="5590609058453685222">התזכורת שהמיקרופון מושתק פועלת. תתקבל הודעה במקרים של דיבור כשההשתקה פועלת.</translation>
@@ -1444,6 +1448,7 @@
 <translation id="6319503618073410818">לצפייה בפרטים בדפדפן</translation>
 <translation id="6324916366299863871">עריכת קיצור דרך</translation>
 <translation id="6330012934079202188">מוצגים החלונות מכל שולחנות העבודה הווירטואליים. ניתן להקיש על מקש החץ למעלה כדי להציג את החלונות משולחן העבודה הווירטואלי הנוכחי</translation>
+<translation id="6337159624125741244">התכונה 'מגדיל למסך מלא' פועלת</translation>
 <translation id="6338485349199627913"><ph name="DISPLAY_NAME" /> הוא סשן מנוהל שמנוהל על ידי <ph name="MANAGER" /></translation>
 <translation id="6344138931392227467"><ph name="DEVICE_NAME" /> מחובר</translation>
 <translation id="6348449481487610270"><ph name="MODIFIER_ONE" /><ph name="MODIFIER_TWO" /><ph name="KEY_ONE" /> ואז <ph name="MODIFIER_THREE" /><ph name="KEY_TWO" /> או <ph name="KEY_THREE" /></translation>
@@ -1510,6 +1515,7 @@
 <translation id="6574587113394758819">ההתראה מ-<ph name="APP_TITLE" /> מוסתרת כי מופעלת הגנה על תצוגה</translation>
 <translation id="6574622320167699133">הנעילה בוטלה על ידי הטלפון שלך. כדי להיכנס, צריך להקיש או ללחוץ.</translation>
 <translation id="6578407462441924264">ללא שם</translation>
+<translation id="6582034443359256692">מתבצע חישוב של רמת הטעינה של הסוללה.</translation>
 <translation id="6585808820553845416">הפעילות באתר תסתיים בעוד <ph name="SESSION_TIME_REMAINING" />.</translation>
 <translation id="6593850935013518327"><ph name="PRIMARY_TEXT" />, <ph name="SECONDARY_TEXT" /></translation>
 <translation id="6597278316891651699">המצלמה מוצמדת לפינה הימנית התחתונה. התנגשות עם תצוגת המערכת.</translation>
@@ -1571,6 +1577,7 @@
 <translation id="6790428901817661496">הפעלה</translation>
 <translation id="679368458793552943">הגדלת התצוגה כשמפעילים זכוכית מגדלת</translation>
 <translation id="6794287755901682422">פרטי המשימה הזו: <ph name="GLANCEABLES_TASK_ITEM_METADATA" />.</translation>
+<translation id="6797745268063125932">להשאיר פועל</translation>
 <translation id="6801878137098616817">נערך לאחרונה</translation>
 <translation id="6802687695197837794">הפעולה הזו מאפשרת גישה לאפליקציות <ph name="APP1_NAME" /> וגם <ph name="APP2_NAME" />, ולכל האפליקציות והאתרים שיש להם הרשאות גישה למצלמה ולמיקרופון</translation>
 <translation id="6803622936009808957">לא ניתן היה לשקף מסכים מכיוון שלא נמצאה רזולוציה נתמכת. במקום זאת התצוגה עברה למצב שולחן עבודה מורחב.</translation>
@@ -1884,6 +1891,7 @@
 <translation id="7947798320695032612">האפליקציה <ph name="APP_NAME" /> מבקשת להשתמש ב<ph name="DEVICE_NAME" /></translation>
 <translation id="7951630946012935453">עמעום המקלדת</translation>
 <translation id="7953994493035617347">לאשר את הרזולוציה החדשה?</translation>
+<translation id="795958884516058160">התכונה 'מגדיל למסך מלא' מופעלת. אפשר להקיש שוב על <ph name="ACCELERATOR" /> כדי להשבית אותה.</translation>
 <translation id="7963689218131240420">המצב 'נא לא להפריע' מושבת.</translation>
 <translation id="7963992254934562106">מ-<ph name="PHONE_NAME" /></translation>
 <translation id="7968693143708939792">בחירת תיקייה…</translation>
@@ -2135,6 +2143,7 @@
 <translation id="894774083269346314">התיבה <ph name="PROFILE_NAME" /> ‏<ph name="EMAIL" /> לא מסומנת.</translation>
 <translation id="8949925099261528566">יש חיבור, אין אינטרנט</translation>
 <translation id="8951539504029375108">‏רק מכשירי Thunderbolt מאושרים תואמים ל-Chromebook</translation>
+<translation id="8959380109429710384">‏לחצת על מקש הקיצור של 'מגדיל למסך מלא'. כדי לזוז במסך כשמגדילים את התצוגה, משתמשים ב-Ctrl‏ + Alt + מקשי החיצים.</translation>
 <translation id="8964525410783593407">שעה אחת</translation>
 <translation id="8973885907461690937">העברת המיקוד לסמל התפריט</translation>
 <translation id="8980862970816311842">העברה של סמל אפליקציה אל תיקייה או מחוץ לה בתצוגת האפליקציות</translation>
diff --git a/ash/strings/ash_strings_mr.xtb b/ash/strings/ash_strings_mr.xtb
index 200bce0..2cb0f0a 100644
--- a/ash/strings/ash_strings_mr.xtb
+++ b/ash/strings/ash_strings_mr.xtb
@@ -119,6 +119,7 @@
 <translation id="1383876407941801731">शोधा</translation>
 <translation id="1391102559483454063">सुरू</translation>
 <translation id="1394698770495054737">पूर्ण ब्लर</translation>
+<translation id="1395878931462960119">{DAYS,plural, =1{१ दिवसापूर्वी}other{# दिवसांपूर्वी}}</translation>
 <translation id="1404963891829069586">फोकसचा आवाज</translation>
 <translation id="1407069428457324124">गडद थीम</translation>
 <translation id="1410568680128842168"><ph name="DATE_CELL_TOOL_TIP" />. तारखांदरम्यान नेव्हिगेट करण्यासाठी अ‍ॅरो की वापरा.</translation>
@@ -209,6 +210,7 @@
 <translation id="174102739345480129">मार्कर बंद आहे.</translation>
 <translation id="1743570585616704562">ओळखले नाही</translation>
 <translation id="1743927604032653654"><ph name="NOTIFICATION_TITLE" /> ही सूचना कोलॅप्स करा</translation>
+<translation id="1744435831291625602">{HOURS,plural, =0{Within 1 hr}=1{१ तासापूर्वी}other{# तासांपूर्वी}}</translation>
 <translation id="1746730358044914197">तुमच्या ॲडमिनिस्ट्रेटरद्वारे कॉन्फिगर केलेल्या इनपुट पद्धती.</translation>
 <translation id="1747336645387973286">शेवटची तारीख <ph name="DUE_DATE" /></translation>
 <translation id="1747827819627189109">ऑन-स्क्रीन कीबोर्ड सक्षम</translation>
@@ -346,6 +348,7 @@
 <translation id="2359808026110333948">सुरू ठेवा</translation>
 <translation id="2360398059912971776">बॅटरी</translation>
 <translation id="2361210043495191221">वाय-फाय टॉगल करा. <ph name="STATE" />.</translation>
+<translation id="236574664504281623"><ph name="SESSION_NAME" /> वरून पाठवले</translation>
 <translation id="2367186422933365202">तुमच्या Chromebook मध्ये साइन इन करू शकत नाही</translation>
 <translation id="2367972762794486313">अ‍ॅप्स दर्शवा</translation>
 <translation id="2368828502825385061">शोधा</translation>
@@ -506,6 +509,7 @@
 <translation id="2963773877003373896">mod3</translation>
 <translation id="2965227184985674128">मायक्रोफोनचा अ‍ॅक्सेस सुरू करायचा आहे का?</translation>
 <translation id="296762781903199866"><ph name="LANGUAGE" /> च्या स्पीच फाइल डाउनलोड करता आल्या नाहीत</translation>
+<translation id="2968761508099987738">तुमच्या सद्य स्थानाला यावेळी सपोर्ट नाही.</translation>
 <translation id="2970920913501714344">ॲप्स, एक्स्टेंशन आणि थीम इंस्टॉल करा</translation>
 <translation id="2977598380246111477">पुढील नंबर</translation>
 <translation id="2985148236010982088">सर्व अ‍ॅप्स पहा</translation>
@@ -979,6 +983,7 @@
 <translation id="468293128311738995">तुमच्या फोनवरील अ‍ॅप्स</translation>
 <translation id="4690510401873698237">शेल्फ तळाशी आहे</translation>
 <translation id="4696813013609194136">पालक कोडने डिव्हाइस अनलॉक करा</translation>
+<translation id="4697357603686181098">या बाबतीत मदत करू शकत नाही. दुसरी विनंती करून पहा.</translation>
 <translation id="4702647871202761252">गोपनीयता स्क्रीन बंद आहे</translation>
 <translation id="4706121060329443414">नंतर डाउनलोड करण्याचा प्रयत्न केला जाईल. सध्या प्रक्रिया करण्यासाठी स्पीच Google ला पाठवली जाईल.</translation>
 <translation id="470644585772471629">कलर इन्व्हर्जन</translation>
@@ -1901,6 +1906,7 @@
 <translation id="7982878511129296052">बंद करत आहे...</translation>
 <translation id="7984197416080286869">खूप जास्त फिंगरप्रिंट प्रयत्न</translation>
 <translation id="798779949890829624">हे सेटिंग तुमच्या अ‍ॅडमिनिस्ट्रेटरद्वारे व्यवस्थापित केले जाते</translation>
+<translation id="7989206653429884947">वारंवार उघडलेल्या</translation>
 <translation id="799296642788192631">तुम्ही महत्त्वाच्या फाइल पिन करू शकता. पिन करण्यासाठी, आयटमवर कर्सर फिरवा किंवा Files उघडा आणि आयटमवर राइट-क्लिक करा.</translation>
 <translation id="7994370417837006925">मल्टिपल साइन इन</translation>
 <translation id="7995804128062002838">स्क्रीन कॅप्चर करता आली नाही</translation>
@@ -2085,6 +2091,7 @@
 <translation id="8747464587821437069"><ph name="CAMERA_AND_MICROPHONE_ACCESS_STATUS" />,
         <ph name="SCREEN_SHARE_STATUS" /></translation>
 <translation id="8749787185286745219">वेळ संपली. उत्तम कामगिरी! 🎉</translation>
+<translation id="8753368202781196133">या वेळी या भाषेला सपोर्ट नाही.</translation>
 <translation id="8755498163081687682">तुमच्या ओळखीची पडताळणी करा: हे तुम्हीच असल्याची <ph name="ORIGIN_NAME" /> ला खात्री करायची आहे</translation>
 <translation id="875593634123171288">VPN सेटिंग्ज दाखवा</translation>
 <translation id="8756799553341497810">तुम्ही या दृश्यामधून बाहेर पडल्यानंतर तुमचा अ‍ॅप लेआउट कस्टमाइझ करणे सुरू करू शकता.</translation>
diff --git a/ash/strings/ash_strings_ms.xtb b/ash/strings/ash_strings_ms.xtb
index 3915727f..1475cf08 100644
--- a/ash/strings/ash_strings_ms.xtb
+++ b/ash/strings/ash_strings_ms.xtb
@@ -119,6 +119,7 @@
 <translation id="1383876407941801731">Carian</translation>
 <translation id="1391102559483454063">Dihidupkan</translation>
 <translation id="1394698770495054737">Kabur Penuh</translation>
+<translation id="1395878931462960119">{DAYS,plural, =1{1 hari yang lalu}other{# hari yang lalu}}</translation>
 <translation id="1404963891829069586">Bunyi fokus</translation>
 <translation id="1407069428457324124">Tema gelap</translation>
 <translation id="1410568680128842168"><ph name="DATE_CELL_TOOL_TIP" />. Gunakan kekunci anak panah untuk menavigasi antara tarikh.</translation>
@@ -209,6 +210,7 @@
 <translation id="174102739345480129">Penanda dimatikan.</translation>
 <translation id="1743570585616704562">Tidak dikenali</translation>
 <translation id="1743927604032653654">Kuncupkan pemberitahuan <ph name="NOTIFICATION_TITLE" /></translation>
+<translation id="1744435831291625602">{HOURS,plural, =0{Dalam masa 1 jam}=1{1 jam yang lalu}other{# jam yang lalu}}</translation>
 <translation id="1746730358044914197">Kaedah masukan dikonfigurasi oleh pentadbir anda.</translation>
 <translation id="1747336645387973286">tarikh tamat <ph name="DUE_DATE" /></translation>
 <translation id="1747827819627189109">Papan kekunci pada skrin didayakan</translation>
@@ -346,6 +348,7 @@
 <translation id="2359808026110333948">Teruskan</translation>
 <translation id="2360398059912971776">bateri</translation>
 <translation id="2361210043495191221">Togol Wi-Fi. <ph name="STATE" />.</translation>
+<translation id="236574664504281623">Dihantar daripada <ph name="SESSION_NAME" /></translation>
 <translation id="2367186422933365202">Tidak dapat log masuk ke Chromebook anda</translation>
 <translation id="2367972762794486313">Paparkan apl</translation>
 <translation id="2368828502825385061">Cari</translation>
@@ -506,6 +509,7 @@
 <translation id="2963773877003373896">mod3</translation>
 <translation id="2965227184985674128">Hidupkan akses mikrofon?</translation>
 <translation id="296762781903199866">Tidak dapat memuat turun fail pertuturan <ph name="LANGUAGE" /></translation>
+<translation id="2968761508099987738">Lokasi semasa anda tidak disokong pada masa ini.</translation>
 <translation id="2970920913501714344">Pasang apl, sambungan dan tema</translation>
 <translation id="2977598380246111477">Nombor seterusnya</translation>
 <translation id="2985148236010982088">Lihat semua apl</translation>
@@ -979,6 +983,7 @@
 <translation id="468293128311738995">Apl daripada telefon anda</translation>
 <translation id="4690510401873698237">Rak di bahagian bawah</translation>
 <translation id="4696813013609194136">Buka kunci peranti menggunakan kod ibu bapa</translation>
+<translation id="4697357603686181098">Tidak dapat membantu dengan gesaan ini. Cuba permintaan lain.</translation>
 <translation id="4702647871202761252">Skrin privasi dimatikan</translation>
 <translation id="4706121060329443414">Muat turun akan cuba dilakukan kemudian. Buat masa sekarang, pertuturan akan dihantar kepada Google untuk diproses.</translation>
 <translation id="470644585772471629">Penyongsangan warna</translation>
@@ -1901,6 +1906,7 @@
 <translation id="7982878511129296052">Mematikan...</translation>
 <translation id="7984197416080286869">Terlalu banyak percubaan cap jari</translation>
 <translation id="798779949890829624">Tetapan ini diurus oleh pentadbir anda</translation>
+<translation id="7989206653429884947">Kerap dibuka</translation>
 <translation id="799296642788192631">Anda boleh menyemat fail penting. Untuk menyemat, tuding pada item atau buka Fail dan klik kanan item.</translation>
 <translation id="7994370417837006925">Log masuk berbilang</translation>
 <translation id="7995804128062002838">Gagal untuk menangkap skrin</translation>
@@ -2085,6 +2091,7 @@
 <translation id="8747464587821437069"><ph name="CAMERA_AND_MICROPHONE_ACCESS_STATUS" />,
         <ph name="SCREEN_SHARE_STATUS" /></translation>
 <translation id="8749787185286745219">Masa tamat. Syabas! 🎉</translation>
+<translation id="8753368202781196133">Bahasa ini tidak disokong pada masa ini.</translation>
 <translation id="8755498163081687682">Sahkan identiti anda: <ph name="ORIGIN_NAME" /> ingin mengesahkan orang itu ialah anda</translation>
 <translation id="875593634123171288">Tunjukkan tetapan VPN</translation>
 <translation id="8756799553341497810">Anda boleh mula menyesuaikan reka letak apl anda setelah anda keluar daripada paparan ini.</translation>
diff --git a/ash/strings/ash_strings_nl.xtb b/ash/strings/ash_strings_nl.xtb
index 6187859..d7869c3 100644
--- a/ash/strings/ash_strings_nl.xtb
+++ b/ash/strings/ash_strings_nl.xtb
@@ -119,6 +119,7 @@
 <translation id="1383876407941801731">Zoeken</translation>
 <translation id="1391102559483454063">Aan</translation>
 <translation id="1394698770495054737">Volledige vervaging</translation>
+<translation id="1395878931462960119">{DAYS,plural, =1{1 dag geleden}other{# dagen geleden}}</translation>
 <translation id="1404963891829069586">Focusgeluiden</translation>
 <translation id="1407069428457324124">Donker thema</translation>
 <translation id="1410568680128842168"><ph name="DATE_CELL_TOOL_TIP" />. Gebruik de pijltoetsen om tussen datums te navigeren.</translation>
@@ -209,6 +210,7 @@
 <translation id="174102739345480129">Stift staat uit.</translation>
 <translation id="1743570585616704562">Niet herkend</translation>
 <translation id="1743927604032653654">Vouw de melding <ph name="NOTIFICATION_TITLE" /> samen</translation>
+<translation id="1744435831291625602">{HOURS,plural, =0{Binnen 1 u}=1{1 u geleden}other{# u geleden}}</translation>
 <translation id="1746730358044914197">Invoermethoden worden ingesteld door je beheerder.</translation>
 <translation id="1747336645387973286">deadline <ph name="DUE_DATE" /></translation>
 <translation id="1747827819627189109">Schermtoetsenbord staat aan</translation>
@@ -346,6 +348,7 @@
 <translation id="2359808026110333948">Doorgaan</translation>
 <translation id="2360398059912971776">batterij</translation>
 <translation id="2361210043495191221">Wifi aan-/uitzetten. <ph name="STATE" />.</translation>
+<translation id="236574664504281623">Verstuurd vanaf <ph name="SESSION_NAME" /></translation>
 <translation id="2367186422933365202">Kan niet inloggen op je Chromebook</translation>
 <translation id="2367972762794486313">Apps bekijken</translation>
 <translation id="2368828502825385061">Zoeken</translation>
@@ -506,6 +509,7 @@
 <translation id="2963773877003373896">mod3</translation>
 <translation id="2965227184985674128">Microfoontoegang aanzetten?</translation>
 <translation id="296762781903199866">Kan spraakbestanden in het <ph name="LANGUAGE" /> niet downloaden</translation>
+<translation id="2968761508099987738">Je huidige locatie wordt op dit moment niet ondersteund.</translation>
 <translation id="2970920913501714344">Apps, extensies en thema's installeren</translation>
 <translation id="2977598380246111477">Volgend cijfer</translation>
 <translation id="2985148236010982088">Alle apps bekijken</translation>
@@ -979,6 +983,7 @@
 <translation id="468293128311738995">Apps op je telefoon</translation>
 <translation id="4690510401873698237">Plank aan onderkant</translation>
 <translation id="4696813013609194136">Apparaat ontgrendelen met oudercode</translation>
+<translation id="4697357603686181098">Daarbij kunnen we niet helpen. Probeer een ander verzoek.</translation>
 <translation id="4702647871202761252">Privacyscherm staat uit</translation>
 <translation id="4706121060329443414">Download wordt later geprobeerd. Voorlopig wordt spraak naar Google gestuurd voor verwerking.</translation>
 <translation id="470644585772471629">Kleurinversie</translation>
@@ -1901,6 +1906,7 @@
 <translation id="7982878511129296052">Uitzetten...</translation>
 <translation id="7984197416080286869">Te veel vingerafdrukpogingen</translation>
 <translation id="798779949890829624">Deze instelling wordt beheerd door je beheerder</translation>
+<translation id="7989206653429884947">Vaak geopend</translation>
 <translation id="799296642788192631">Je kunt belangrijke bestanden vastzetten. Als je een item wilt vastzetten, plaats je de cursor op het item of open je Bestanden en klik je met de rechtermuisknop op het item.</translation>
 <translation id="7994370417837006925">Toegang tot meerdere accounts</translation>
 <translation id="7995804128062002838">Schermopname mislukt</translation>
@@ -2085,6 +2091,7 @@
 <translation id="8747464587821437069"><ph name="CAMERA_AND_MICROPHONE_ACCESS_STATUS" />,
 <ph name="SCREEN_SHARE_STATUS" /></translation>
 <translation id="8749787185286745219">De tijd is om. Goed gedaan! 🎉</translation>
+<translation id="8753368202781196133">Deze taal wordt op dit moment niet ondersteund.</translation>
 <translation id="8755498163081687682">Je identiteit verifiëren: <ph name="ORIGIN_NAME" /> wil bevestigen dat jij het bent</translation>
 <translation id="875593634123171288">VPN-instellingen bekijken</translation>
 <translation id="8756799553341497810">Nadat je deze weergave hebt gesloten, kun je de indeling van je app aanpassen.</translation>
diff --git a/ash/strings/ash_strings_si.xtb b/ash/strings/ash_strings_si.xtb
index 07d243e4..eb1b963 100644
--- a/ash/strings/ash_strings_si.xtb
+++ b/ash/strings/ash_strings_si.xtb
@@ -903,6 +903,7 @@
 <translation id="4381031910344220229">මෙය <ph name="APP_NAME" /> සඳහා මයික්‍රෆෝන ප්‍රවේශයට සහ මයික්‍රෆෝන අවසරය ඇති සියලු යෙදුම් සහ වෙබ් අඩවිවලට ඉඩ දෙයි</translation>
 <translation id="4382340674111381977">පෙර පිටුවට ආපසු යන්න</translation>
 <translation id="4389184120735010762">ඔබ ඩොක් කළ විශාලකය සඳහා යතුරුපුවරු කෙටිමඟ ඔබා ඇත. ඔබට එය සක්‍රීය කළ යුතුද?</translation>
+<translation id="4394466652057229831">සාරාංශ කිරීමට දකුණු ක්ලික් කරන්න</translation>
 <translation id="439598569299422042"><ph name="SIZE_INFO" />, විරාම කරන ලදි</translation>
 <translation id="440113666232554208">තිරසටහන සුරැකිය නොහැකිය</translation>
 <translation id="4405151984121254935">සම්බන්ධිත උපාංග වර්ගයට සහාය නොදක්වයි</translation>
@@ -1939,6 +1940,7 @@
 <translation id="8113423164597455979">සියලු යෙදුම් සක්‍රිය.</translation>
 <translation id="8113515504791187892">කථා-කිරීමට-තෝරන්න බොත්තම</translation>
 <translation id="8120151603115102514">ඔබගේ දුරකථනයට අගුලු තිරයක් නොමැත. ඔබගේ Chromebook අගුලු හැරීමට, මුරපදය ඇතුළු කරන්න.</translation>
+<translation id="8120249852906205273">යළි අරඹන්න</translation>
 <translation id="8127095419621171197">ගණක යෙදුම විවෘත කරන්න</translation>
 <translation id="8129620843620772246"><ph name="TEMPERATURE_C" />° C</translation>
 <translation id="8130528849632411619">ලේඛනයේ ආරම්භයට යන්න</translation>
@@ -2033,6 +2035,7 @@
 <translation id="85123341071060231">ඔබගේ Chromebook හි බ්ලූටූත් ක්‍රියාවිරහිතයි. ඔබගේ Chromebook අගුලු හැරීමට, මුරපදය ඇතුළු කරන්න.</translation>
 <translation id="8513108775083588393">ස්වයංක්‍රීය කරකැවීම</translation>
 <translation id="851458219935658693">වත්මන් මේසයෙන් කවුළු පෙන්වයි, රේඩියෝ බොත්තම තෝරා ගන්නා ලදී</translation>
+<translation id="851660987304951246">අන්තර්ගතය ක්‍ෂණිකව සාරාංශ කිරීමට හෝ ප්‍රශ්න ඇසීමට මට කියවීමට උදවු කරන්න භාවිත කරන්න</translation>
 <translation id="8517041960877371778">ඔබගේ <ph name="DEVICE_TYPE" /> සක්‍රියව පවතින විට එය ආරෝපණය නොවනු ඇත.</translation>
 <translation id="852060496139946719">{NUM_APPS,plural, =1{මයික් ආදානය <ph name="APP_NAME" /> මගින් පාලනය වේ}one{මයික් ආදානය යෙදුම් #කින් පාලනය වේ}other{මයික් ආදානය යෙදුම් #කින් පාලනය වේ}}</translation>
 <translation id="8535393432370007982">වර්ණය අනුව අනුපිළිවෙලට සැකසීමේ පිළිවෙළ පසුගමනය කරන්න</translation>
diff --git a/ash/strings/ash_strings_sr-Latn.xtb b/ash/strings/ash_strings_sr-Latn.xtb
index 8c4c5c1..40817bca 100644
--- a/ash/strings/ash_strings_sr-Latn.xtb
+++ b/ash/strings/ash_strings_sr-Latn.xtb
@@ -900,6 +900,7 @@
 <translation id="4381031910344220229">Ovo dozvoljava pristup mikrofonu za aplikaciju <ph name="APP_NAME" /> i sve aplikacije i veb-sajtove sa dozvolom za mikrofon</translation>
 <translation id="4382340674111381977">Vratite se na prethodnu stranicu</translation>
 <translation id="4389184120735010762">Pritisnuli ste tastersku prečicu za montiranu lupu ekrana. Želite li da je uključite?</translation>
+<translation id="4394466652057229831">Kliknite desnim tasterom da biste rezimirali</translation>
 <translation id="439598569299422042">Pauzirano, <ph name="SIZE_INFO" /></translation>
 <translation id="440113666232554208">Čuvanje video snimka ekrana nije uspelo</translation>
 <translation id="4405151984121254935">Tip povezanog perifernog uređaja nije podržan</translation>
@@ -1935,6 +1936,7 @@
 <translation id="8113423164597455979">Uključeno, sve</translation>
 <translation id="8113515504791187892">Dugme Izaberite za govor</translation>
 <translation id="8120151603115102514">Telefon nema zaključani ekran. Da biste otključali Chromebook, unesite lozinku.</translation>
+<translation id="8120249852906205273">Restartuj</translation>
 <translation id="8127095419621171197">Otvori aplikaciju Kalkulator</translation>
 <translation id="8129620843620772246"><ph name="TEMPERATURE_C" /> °C</translation>
 <translation id="8130528849632411619">Idite na početak dokumenta</translation>
@@ -2029,6 +2031,7 @@
 <translation id="85123341071060231">Bluetooth na Chromebook-u je isključen. Da biste otključali Chromebook, unesite lozinku.</translation>
 <translation id="8513108775083588393">Autom. rotir.</translation>
 <translation id="851458219935658693">Prikazujte prozore sa aktuelne radne površine, dugme za izbor je izabrano</translation>
+<translation id="851660987304951246">Koristite Pomozi mi da čitam da biste brzo rezimirali sadržaj ili postavljali pitanja</translation>
 <translation id="8517041960877371778"><ph name="DEVICE_TYPE" /> se možda neće puniti dok je uključen.</translation>
 <translation id="852060496139946719">{NUM_APPS,plural, =1{Unos preko mikrofona kontroliše <ph name="APP_NAME" />}one{Unos preko mikrofona kontroliše # aplikacija}few{Unos preko mikrofona kontrolišu # aplikacije}other{Unos preko mikrofona kontroliše # aplikacija}}</translation>
 <translation id="8535393432370007982">Opozovite redosled sortiranja prema boji</translation>
diff --git a/ash/strings/ash_strings_sr.xtb b/ash/strings/ash_strings_sr.xtb
index f49c260..b1dbb2ea 100644
--- a/ash/strings/ash_strings_sr.xtb
+++ b/ash/strings/ash_strings_sr.xtb
@@ -900,6 +900,7 @@
 <translation id="4381031910344220229">Ово дозвољава приступ микрофону за апликацију <ph name="APP_NAME" /> и све апликације и веб-сајтове са дозволом за микрофон</translation>
 <translation id="4382340674111381977">Вратите се на претходну страницу</translation>
 <translation id="4389184120735010762">Притиснули сте тастерску пречицу за монтирану лупу екрана. Желите ли да је укључите?</translation>
+<translation id="4394466652057229831">Кликните десним тастером да бисте резимирали</translation>
 <translation id="439598569299422042">Паузирано, <ph name="SIZE_INFO" /></translation>
 <translation id="440113666232554208">Чување видео снимка екрана није успело</translation>
 <translation id="4405151984121254935">Тип повезаног периферног уређаја није подржан</translation>
@@ -1935,6 +1936,7 @@
 <translation id="8113423164597455979">Укључено, све</translation>
 <translation id="8113515504791187892">Дугме Изаберите за говор</translation>
 <translation id="8120151603115102514">Телефон нема закључани екран. Да бисте откључали Chromebook, унесите лозинку.</translation>
+<translation id="8120249852906205273">Рестартуј</translation>
 <translation id="8127095419621171197">Отвори апликацију Калкулатор</translation>
 <translation id="8129620843620772246"><ph name="TEMPERATURE_C" /> °C</translation>
 <translation id="8130528849632411619">Идите на почетак документа</translation>
@@ -2029,6 +2031,7 @@
 <translation id="85123341071060231">Bluetooth на Chromebook-у је искључен. Да бисте откључали Chromebook, унесите лозинку.</translation>
 <translation id="8513108775083588393">Аутом. ротир.</translation>
 <translation id="851458219935658693">Приказујте прозоре са актуелне радне површине, дугме за избор је изабрано</translation>
+<translation id="851660987304951246">Користите Помози ми да читам да бисте брзо резимирали садржај или постављали питања</translation>
 <translation id="8517041960877371778"><ph name="DEVICE_TYPE" /> се можда неће пунити док је укључен.</translation>
 <translation id="852060496139946719">{NUM_APPS,plural, =1{Унос преко микрофона контролише <ph name="APP_NAME" />}one{Унос преко микрофона контролише # апликација}few{Унос преко микрофона контролишу # апликације}other{Унос преко микрофона контролише # апликација}}</translation>
 <translation id="8535393432370007982">Опозовите редослед сортирања према боји</translation>
diff --git a/ash/strings/ash_strings_uz.xtb b/ash/strings/ash_strings_uz.xtb
index 88e4ccf..1627411 100644
--- a/ash/strings/ash_strings_uz.xtb
+++ b/ash/strings/ash_strings_uz.xtb
@@ -119,6 +119,7 @@
 <translation id="1383876407941801731">Qidiruv</translation>
 <translation id="1391102559483454063">Yoniq</translation>
 <translation id="1394698770495054737">Toʻliq fokus</translation>
+<translation id="1395878931462960119">{DAYS,plural, =1{1 kun oldin}other{# kun oldin}}</translation>
 <translation id="1404963891829069586">Fokus tovushlari</translation>
 <translation id="1407069428457324124">Tungi mavzu</translation>
 <translation id="1410568680128842168"><ph name="DATE_CELL_TOOL_TIP" />. Sanalarga oʻtish uchun strelka tugmalaridan foydalaning.</translation>
@@ -209,6 +210,7 @@
 <translation id="174102739345480129">Marker oʻchiq.</translation>
 <translation id="1743570585616704562">Barmoq izi aniqlanmadi</translation>
 <translation id="1743927604032653654">Bildirishnomani (<ph name="NOTIFICATION_TITLE" />) yigʻish</translation>
+<translation id="1744435831291625602">{HOURS,plural, =0{1 soat ichida}=1{1 soat oldin}other{# soat oldin}}</translation>
 <translation id="1746730358044914197">Matn kiritish usuli administratoringiz tomonidan sozlangan.</translation>
 <translation id="1747336645387973286">bajarish muddati: <ph name="DUE_DATE" /></translation>
 <translation id="1747827819627189109">Ekran klaviaturasi yoqildi</translation>
@@ -346,6 +348,7 @@
 <translation id="2359808026110333948">Davom etish</translation>
 <translation id="2360398059912971776">batareya</translation>
 <translation id="2361210043495191221">Wi-Fi tugmasi. <ph name="STATE" />.</translation>
+<translation id="236574664504281623"><ph name="SESSION_NAME" /> orqali yuborilgan</translation>
 <translation id="2367186422933365202">Chromebook hisobiga kirilmadi</translation>
 <translation id="2367972762794486313">Ilovalarni ko‘rsatish</translation>
 <translation id="2368828502825385061">Topish</translation>
@@ -506,6 +509,7 @@
 <translation id="2963773877003373896">mod3</translation>
 <translation id="2965227184985674128">Mikrofondan foydalanishga ruxsat berilsinmi?</translation>
 <translation id="296762781903199866"><ph name="LANGUAGE" /> nutq fayllari yuklab olinmadi</translation>
+<translation id="2968761508099987738">Joriy joylashuvingiz hozirda dastaklanmaydi.</translation>
 <translation id="2970920913501714344">Ilovalar, kengaytmalar va mavzularni oʻrnating</translation>
 <translation id="2977598380246111477">Keyingi raqam</translation>
 <translation id="2985148236010982088">Barcha ilovalar</translation>
@@ -571,6 +575,7 @@
 <translation id="3226991577105957773">yana <ph name="COUNT" /> ta</translation>
 <translation id="3227137524299004712">Mikrofon</translation>
 <translation id="3233611303007751344">Quvvat tejalishi faolsizlantirildi</translation>
+<translation id="3238409143297336341">Ilovalar uchun ota-ona nazoratini sozlang</translation>
 <translation id="324366796737464147">Shovqinsizlantirish</translation>
 <translation id="3249513730522716925"><ph name="WINDOW_TITLE" /> oynasi <ph name="ACTIVE_DESK" /> ish stolidan <ph name="TARGET_DESK" /> ish stoliga koʻchirildi</translation>
 <translation id="3253743281242075461">Sinf ishi turi: <ph name="GLANCEABLES_CLASSROOM_LIST_NAME" /></translation>
@@ -978,6 +983,7 @@
 <translation id="468293128311738995">Telefondagi ilovalar</translation>
 <translation id="4690510401873698237">Javon pastda</translation>
 <translation id="4696813013609194136">Ota-ona kodi bilan qurilmani qulfdan chiqarish</translation>
+<translation id="4697357603686181098">Bu masalada yordam bera olmayman. Boshqa soʻrov yuboring.</translation>
 <translation id="4702647871202761252">Maxfiylik ekrani yoniq emas</translation>
 <translation id="4706121060329443414">Keyinroq yuklab olinadi. Hozir nutq qayta ishlanishi uchun Googlega yuboriladi.</translation>
 <translation id="470644585772471629">Ranglarni akslantirish</translation>
@@ -1399,6 +1405,7 @@
 <translation id="6141205840878048728">Nima maqsadda fokus qilishni istaysiz?</translation>
 <translation id="6141988275892716286">Yuklanishni tasdiqlang</translation>
 <translation id="6143578372829139382">YouTubega ulashish</translation>
+<translation id="6147182561428020853">Mazkur <ph name="DEVICE_TYPE" /> qurilmasida oʻrnatilgan ilovalarni bloklash mumkin</translation>
 <translation id="6154006699632741460">Tashqi qurilmalar ishlamaydi</translation>
 <translation id="6156960295318603523">Til sozlamalari</translation>
 <translation id="615957422585914272">Ekran klaviaturasini ko‘rsatish</translation>
@@ -1899,6 +1906,7 @@
 <translation id="7982878511129296052">Oʻchirilmoqda...</translation>
 <translation id="7984197416080286869">Siz juda koʻp marta urindingiz</translation>
 <translation id="798779949890829624">Bu sozlama administrator tomonidan boshqariladi</translation>
+<translation id="7989206653429884947">Koʻp marta ochilgan</translation>
 <translation id="799296642788192631">Muhim fayllarni mahkamlash mumkin. Mahkamlash uchun sichqonchani fayl ustiga suring yoki Fayllar ilovasini ochib, unga oʻng klik bosing.</translation>
 <translation id="7994370417837006925">Bir nechta hisobdan kirish</translation>
 <translation id="7995804128062002838">Ekran suratga olinmadi</translation>
@@ -2083,6 +2091,7 @@
 <translation id="8747464587821437069"><ph name="CAMERA_AND_MICROPHONE_ACCESS_STATUS" />,
         <ph name="SCREEN_SHARE_STATUS" /></translation>
 <translation id="8749787185286745219">Vaqt tugadi. Barakalla! 🎉</translation>
+<translation id="8753368202781196133">Bu til hozirda dastaklanmaydi.</translation>
 <translation id="8755498163081687682">Shaxsingizni tasdiqlang: <ph name="ORIGIN_NAME" /> bu siz ekanligingizni tasdiqlamoqchi</translation>
 <translation id="875593634123171288">VPN sozlamalarini ochish</translation>
 <translation id="8756799553341497810">Darslik yopilganda ilova dizaynini moslashni boshlash mumkin.</translation>
diff --git a/ash/system/bluetooth/bluetooth_device_status_ui_handler.cc b/ash/system/bluetooth/bluetooth_device_status_ui_handler.cc
index 0cb28c1..777143f6 100644
--- a/ash/system/bluetooth/bluetooth_device_status_ui_handler.cc
+++ b/ash/system/bluetooth/bluetooth_device_status_ui_handler.cc
@@ -4,11 +4,13 @@
 
 #include "ash/system/bluetooth/bluetooth_device_status_ui_handler.h"
 
+#include "ash/constants/ash_pref_names.h"
 #include "ash/constants/notifier_catalogs.h"
 #include "ash/public/cpp/bluetooth_config_service.h"
 #include "ash/public/cpp/hats_bluetooth_revamp_trigger.h"
 #include "ash/public/cpp/system/toast_data.h"
 #include "ash/public/cpp/system/toast_manager.h"
+#include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "base/check.h"
 #include "base/functional/bind.h"
@@ -16,6 +18,7 @@
 #include "base/task/single_thread_task_runner.h"
 #include "chromeos/ash/services/bluetooth_config/public/cpp/cros_bluetooth_config_util.h"
 #include "components/device_event_log/device_event_log.h"
+#include "components/prefs/pref_service.h"
 #include "device/bluetooth/chromeos/bluetooth_utils.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -30,17 +33,33 @@
 
 }  // namespace
 
-BluetoothDeviceStatusUiHandler::BluetoothDeviceStatusUiHandler() {
+BluetoothDeviceStatusUiHandler::BluetoothDeviceStatusUiHandler(
+    PrefService* local_state)
+    : local_state_(local_state) {
   // Asynchronously bind to CrosBluetoothConfig so that we don't want to attempt
   // to bind to it before it has initialized.
   base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
       FROM_HERE,
       base::BindOnce(&BluetoothDeviceStatusUiHandler::BindToCrosBluetoothConfig,
                      weak_ptr_factory_.GetWeakPtr()));
+  // `local_state` may be null in tests.
+  if (!local_state_) {
+    return;
+  }
+  device::MaybeRecordConnectionToastShownCount(local_state_,
+                                               /*triggered_by_connect=*/false);
 }
 
 BluetoothDeviceStatusUiHandler::~BluetoothDeviceStatusUiHandler() = default;
 
+// static:
+void BluetoothDeviceStatusUiHandler::RegisterLocalStatePrefs(
+    PrefRegistrySimple* registry) {
+  registry->RegisterIntegerPref(prefs::kBluetoothConnectionToastShownCount, 0);
+  registry->RegisterTimePref(prefs::kBluetoothToastCountStartTime,
+                             base::Time::Now().LocalMidnight());
+}
+
 void BluetoothDeviceStatusUiHandler::OnDevicePaired(
     PairedBluetoothDevicePropertiesPtr device) {
   BLUETOOTH_LOG(EVENT) << "Notifying device was paired: "
@@ -89,6 +108,8 @@
   ShowToast(std::move(toast_data));
   device::RecordUiSurfaceDisplayed(
       device::BluetoothUiSurface::kConnectionToast);
+  device::MaybeRecordConnectionToastShownCount(local_state_,
+                                               /*triggered_by_connect=*/true);
 
   if (last_connection_timestamp_.has_value()) {
     device::RecordTimeIntervalBetweenConnections(
diff --git a/ash/system/bluetooth/bluetooth_device_status_ui_handler.h b/ash/system/bluetooth/bluetooth_device_status_ui_handler.h
index ed86702c..a965f88 100644
--- a/ash/system/bluetooth/bluetooth_device_status_ui_handler.h
+++ b/ash/system/bluetooth/bluetooth_device_status_ui_handler.h
@@ -8,6 +8,8 @@
 #include "ash/ash_export.h"
 #include "ash/public/cpp/system/toast_manager.h"
 #include "chromeos/ash/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
 
@@ -19,13 +21,15 @@
 class ASH_EXPORT BluetoothDeviceStatusUiHandler
     : public bluetooth_config::mojom::BluetoothDeviceStatusObserver {
  public:
-  BluetoothDeviceStatusUiHandler();
+  explicit BluetoothDeviceStatusUiHandler(PrefService* local_state);
   BluetoothDeviceStatusUiHandler(const BluetoothDeviceStatusUiHandler&) =
       delete;
   BluetoothDeviceStatusUiHandler& operator=(
       const BluetoothDeviceStatusUiHandler&) = delete;
   ~BluetoothDeviceStatusUiHandler() override;
 
+  static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
+
  private:
   // bluetooth_config::mojom::BluetoothDeviceStatusObserver:
   void OnDevicePaired(
@@ -50,6 +54,8 @@
 
   std::optional<base::TimeTicks> last_connection_timestamp_;
 
+  raw_ptr<PrefService> local_state_;  // unowned.
+
   mojo::Remote<bluetooth_config::mojom::CrosBluetoothConfig>
       remote_cros_bluetooth_config_;
   mojo::Receiver<bluetooth_config::mojom::BluetoothDeviceStatusObserver>
diff --git a/ash/system/bluetooth/bluetooth_device_status_ui_handler_unittest.cc b/ash/system/bluetooth/bluetooth_device_status_ui_handler_unittest.cc
index be3d207..3f5712db 100644
--- a/ash/system/bluetooth/bluetooth_device_status_ui_handler_unittest.cc
+++ b/ash/system/bluetooth/bluetooth_device_status_ui_handler_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "ash/system/bluetooth/bluetooth_device_status_ui_handler.h"
 
+#include "ash/constants/ash_pref_names.h"
 #include "ash/public/cpp/fake_hats_bluetooth_revamp_trigger_impl.h"
 #include "ash/public/cpp/hats_bluetooth_revamp_trigger.h"
 #include "ash/public/cpp/system/toast_data.h"
@@ -11,6 +12,7 @@
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/test/ash_test_helper.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "chromeos/ash/services/bluetooth_config/fake_bluetooth_device_status_notifier.h"
 #include "chromeos/ash/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -24,9 +26,15 @@
 using bluetooth_config::mojom::PairedBluetoothDevicePropertiesPtr;
 using ::testing::NiceMock;
 
+constexpr char kConnectionToastShownLast24HoursCountHistogramName[] =
+    "Bluetooth.ChromeOS.ConnectionToastShownIn24Hours.Count";
+
 class MockBluetoothDeviceStatusUiHandler
     : public BluetoothDeviceStatusUiHandler {
  public:
+  explicit MockBluetoothDeviceStatusUiHandler(PrefService* local_state)
+      : BluetoothDeviceStatusUiHandler(local_state) {}
+  ~MockBluetoothDeviceStatusUiHandler() override = default;
   MOCK_METHOD(void, ShowToast, (ash::ToastData toast_data), (override));
 };
 
@@ -39,11 +47,30 @@
 
     fake_trigger_impl_ = std::make_unique<FakeHatsBluetoothRevampTriggerImpl>();
 
+    local_state_ = std::make_unique<TestingPrefServiceSimple>();
+    local_state_->registry()->RegisterIntegerPref(
+        prefs::kBluetoothConnectionToastShownCount, 0);
+    // Manually set the prefs to be 25 hours earlier.
+    local_state_->registry()->RegisterTimePref(
+        prefs::kBluetoothToastCountStartTime,
+        base::Time::Now().LocalMidnight() - base::Hours(25));
+
+    histogram_tester_ = std::make_unique<base::HistogramTester>();
+
     device_status_ui_handler_ =
-        std::make_unique<NiceMock<MockBluetoothDeviceStatusUiHandler>>();
+        std::make_unique<NiceMock<MockBluetoothDeviceStatusUiHandler>>(
+            local_state_.get());
     base::RunLoop().RunUntilIdle();
   }
 
+  void TearDown() override {
+    histogram_tester_.reset();
+    device_status_ui_handler_.reset();
+    local_state_.reset();
+    fake_trigger_impl_.reset();
+    AshTestBase::TearDown();
+  }
+
   MockBluetoothDeviceStatusUiHandler& device_status_ui_handler() {
     return *device_status_ui_handler_;
   }
@@ -76,6 +103,9 @@
     return fake_trigger_impl_->try_to_show_survey_count();
   }
 
+ protected:
+  std::unique_ptr<base::HistogramTester> histogram_tester_;
+
  private:
   bluetooth_config::FakeBluetoothDeviceStatusNotifier*
   fake_device_status_notifier() {
@@ -86,6 +116,7 @@
 
   std::unique_ptr<FakeHatsBluetoothRevampTriggerImpl> fake_trigger_impl_;
   std::unique_ptr<MockBluetoothDeviceStatusUiHandler> device_status_ui_handler_;
+  std::unique_ptr<TestingPrefServiceSimple> local_state_;
 };
 
 TEST_F(BluetoothDeviceStatusUiHandlerTest, PairedDevice) {
@@ -105,4 +136,49 @@
   SetDisconnectedDevice(GetPairedDevice());
 }
 
+TEST_F(BluetoothDeviceStatusUiHandlerTest,
+       ConnectionToastShownCount24HoursMetric) {
+  // Expect there is on metric already because we manually set time to be 25
+  // hours before local midnight, and the metric is emitted on start up.
+  histogram_tester_->ExpectTotalCount(
+      kConnectionToastShownLast24HoursCountHistogramName, 1);
+
+  // Verify that the prefs are reset.
+  EXPECT_EQ(
+      0, local_state()->GetInteger(prefs::kBluetoothConnectionToastShownCount));
+  EXPECT_EQ(base::Time::Now().LocalMidnight(),
+            local_state()->GetTime(prefs::kBluetoothToastCountStartTime));
+
+  // Connect a device and check that the toast shown count increments by one.
+  SetConnectedDevice(GetPairedDevice());
+  EXPECT_EQ(
+      1, local_state()->GetInteger(prefs::kBluetoothConnectionToastShownCount));
+
+  // Check that no additional histogram entries are logged since it's within 24
+  // hours.
+  histogram_tester_->ExpectTotalCount(
+      kConnectionToastShownLast24HoursCountHistogramName, 1);
+
+  // Simulate the passing of more than 24 hours.
+  local_state()->SetTime(prefs::kBluetoothToastCountStartTime,
+                         base::Time::Now().LocalMidnight() - base::Hours(25));
+  SetConnectedDevice(GetPairedDevice());
+
+  // Verify that the metrics is emitted after the 24-hour threshold is crossed.
+  histogram_tester_->ExpectTotalCount(
+      kConnectionToastShownLast24HoursCountHistogramName, 2);
+  histogram_tester_->ExpectBucketCount(
+      kConnectionToastShownLast24HoursCountHistogramName, /*sample=*/0,
+      /*expected_count=*/1);
+  histogram_tester_->ExpectBucketCount(
+      kConnectionToastShownLast24HoursCountHistogramName, /*sample=*/1,
+      /*expected_count=*/1);
+
+  // Verify the system resets the prefs, but this time, toast count is 1.
+  EXPECT_EQ(
+      1, local_state()->GetInteger(prefs::kBluetoothConnectionToastShownCount));
+  EXPECT_EQ(base::Time::Now().LocalMidnight(),
+            local_state()->GetTime(prefs::kBluetoothToastCountStartTime));
+}
+
 }  // namespace ash
diff --git a/ash/system/input_device_settings/input_device_settings_metadata_manager.cc b/ash/system/input_device_settings/input_device_settings_metadata_manager.cc
index 214fbc5..b28bb33 100644
--- a/ash/system/input_device_settings/input_device_settings_metadata_manager.cc
+++ b/ash/system/input_device_settings/input_device_settings_metadata_manager.cc
@@ -6,6 +6,7 @@
 
 #include "ash/system/input_device_settings/input_device_settings_metadata.h"
 #include "ash/system/input_device_settings/input_device_settings_pref_names.h"
+#include "base/containers/contains.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/scoped_user_pref_update.h"
 
@@ -54,10 +55,15 @@
                                               device_image.data_url());
   }
   auto it = device_callback_map_.find(device_key);
-  if (it != device_callback_map_.end()) {
-    std::move(it->second).Run(device_image);
-    device_callback_map_.erase(it);
+
+  if (it == device_callback_map_.end()) {
+    return;
   }
+
+  for (auto& callback : it->second) {
+    std::move(callback).Run(device_image);
+  }
+  device_callback_map_.erase(it);
 }
 
 std::optional<std::string>
@@ -76,7 +82,7 @@
     std::move(callback).Run(DeviceImage(device_key, device_image.value()));
     return;
   }
-  device_callback_map_[device_key] = std::move(callback);
+  device_callback_map_[device_key].push_back(std::move(callback));
   image_downloader_->DownloadImage(
       device_key, account_id, destination,
       base::BindOnce(&InputDeviceSettingsMetadataManager::OnDeviceImageFetched,
diff --git a/ash/system/input_device_settings/input_device_settings_metadata_manager.h b/ash/system/input_device_settings/input_device_settings_metadata_manager.h
index 795a587..8d5bdfaa4 100644
--- a/ash/system/input_device_settings/input_device_settings_metadata_manager.h
+++ b/ash/system/input_device_settings/input_device_settings_metadata_manager.h
@@ -69,7 +69,8 @@
   std::unique_ptr<DeviceImageStorage> device_image_storage_;
   // Tracks image download requests for input devices. Maps a device's unique
   // key to the callback that should be executed when the image is downloaded.
-  base::flat_map<std::string, ImageDownloadCallback> device_callback_map_;
+  base::flat_map<std::string, std::vector<ImageDownloadCallback>>
+      device_callback_map_;
   base::WeakPtrFactory<InputDeviceSettingsMetadataManager> weak_ptr_factory_{
       this};
 };
diff --git a/ash/webui/common/resources/accessibility/macro_names.ts b/ash/webui/common/resources/accessibility/macro_names.ts
index 32206ec1..829458c 100644
--- a/ash/webui/common/resources/accessibility/macro_names.ts
+++ b/ash/webui/common/resources/accessibility/macro_names.ts
@@ -161,6 +161,10 @@
   // Generates a synthetic long click event.
   MOUSE_LONG_CLICK_LEFT = 45,
 
+  // Pauses or resumes FaceGaze mouse movement and gesture detection if
+  // FaceGaze is already running.
+  TOGGLE_FACEGAZE = 46,
+
   // Any new actions should match with Voice Access's semantic tags where
   // possible.
 }
diff --git a/ash/webui/common/resources/sea_pen/sea_pen_template_query_element.ts b/ash/webui/common/resources/sea_pen/sea_pen_template_query_element.ts
index 57f5968..c2272f1 100644
--- a/ash/webui/common/resources/sea_pen/sea_pen_template_query_element.ts
+++ b/ash/webui/common/resources/sea_pen/sea_pen_template_query_element.ts
@@ -142,7 +142,6 @@
 
   // TODO(b/319719709) this should be SeaPenTemplateId.
   templateId: string|null;
-  private inspireMeAnimation_: LottieRenderer|null|undefined;
   private seaPenTemplate_: SeaPenTemplate;
   private seaPenQuery_: SeaPenQuery|null;
   private selectedOptions_: Map<SeaPenTemplateChip, SeaPenOption>;
@@ -179,10 +178,9 @@
         new ResizeObserver(() => this.animateContainerHeight());
 
     beforeNextRender(this, () => {
-      this.inspireMeAnimation_ =
-          this.shadowRoot?.querySelector<LottieRenderer>('#inspireMeAnimation');
-      if (this.inspireMeAnimation_) {
-        this.inspireMeAnimation_.autoplay = false;
+      const inspireMeAnimation = this.getInspireMeAnimationElement_();
+      if (inspireMeAnimation) {
+        inspireMeAnimation.autoplay = false;
       }
 
       this.containerOriginalHeight_ = this.$.container.scrollHeight;
@@ -235,14 +233,13 @@
   }
 
   private startInspireIconAnimation_() {
-    this.inspireMeAnimation_?.play();
+    this.getInspireMeAnimationElement_()?.play();
   }
 
   private stopInspireIconAnimation_() {
-    this.inspireMeAnimation_?.stop();
+    this.getInspireMeAnimationElement_()?.stop();
   }
 
-
   private clearSelectedChipState_() {
     if (this.selectedChip_) {
       this.selectedChip_ = null;
@@ -371,6 +368,11 @@
     };
   }
 
+  private getInspireMeAnimationElement_(): LottieRenderer|null|undefined {
+    return this.shadowRoot?.querySelector<LottieRenderer>(
+        '#inspireMeAnimation');
+  }
+
   private onClickSearchButton_(event: Event) {
     this.clearSelectedChipState_();
     getSeaPenThumbnails(
diff --git a/ash/webui/sanitize_ui/BUILD.gn b/ash/webui/sanitize_ui/BUILD.gn
index 9729d09..e3e4a8d 100644
--- a/ash/webui/sanitize_ui/BUILD.gn
+++ b/ash/webui/sanitize_ui/BUILD.gn
@@ -22,7 +22,7 @@
     "//ash/webui/common:chrome_os_webui_config",
     "//ash/webui/common:trusted_types_util",
     "//ash/webui/sanitize_ui/resources:resources",
-    "//chromeos/strings:strings_grit",
+    "//chromeos/strings/",
     "//content/public/browser:browser",
     "//ui/base",
     "//ui/resources",
diff --git a/ash/webui/sanitize_ui/resources/BUILD.gn b/ash/webui/sanitize_ui/resources/BUILD.gn
index 62e052a..602a78b4 100644
--- a/ash/webui/sanitize_ui/resources/BUILD.gn
+++ b/ash/webui/sanitize_ui/resources/BUILD.gn
@@ -8,14 +8,26 @@
 assert(is_chromeos_ash, "Non-ChromeOS builds cannot depend on //ash")
 
 build_webui("build") {
-  static_files = [ "index.html" ]
+  static_files = [
+    "index.html",
+    "svg/card_chrome_product.svg",
+    "svg/card_settings.svg",
+    "svg/extension_off_32.svg",
+    "svg/finished_32.svg",
+  ]
+
+  css_files = [ "sanitize_shared.css" ]
 
   web_component_files = [ "sanitize_done.ts" ]
 
   ts_composite = true
   ts_deps = [
+    "//ash/webui/common/resources/cr_elements:build_ts",
+    "//third_party/cros-components:cros_components_ts",
     "//third_party/polymer/v3_0:library",
+    "//ui/webui/resources/cr_components/color_change_listener:build_ts",
     "//ui/webui/resources/js:build_ts",
+    "//ui/webui/resources/mojo:build_ts",
   ]
 
   webui_context_type = "trusted"
diff --git a/ash/webui/sanitize_ui/resources/index.html b/ash/webui/sanitize_ui/resources/index.html
index 04b7d83..a970a3fd 100644
--- a/ash/webui/sanitize_ui/resources/index.html
+++ b/ash/webui/sanitize_ui/resources/index.html
@@ -5,11 +5,24 @@
 <html dir="$i18n{textdirection}" lang="$i18n{language}">
   <head>
     <title></title>
-    <meta charset="utf-8">
+    <link rel="stylesheet" href="chrome://theme/typography.css">
+    <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
+    <link rel="stylesheet" href="chrome://resources/css/md_colors.css">
+    <link rel="stylesheet" href="chrome://theme/colors.css?sets=legacy,sys">
+    <style>
+      body {
+        height: 100vh;
+        margin: 0;
+        overflow: hidden;
+      }
+
+      html {
+        background-color: var(--cros-sys-app_base_shaded);
+      }
+    </style>
   </head>
-  <body>
+  <body class="jelly-enabled">
     <sanitize-done></sanitize-done>
     <script type="module" src="sanitize_done.js"></script>
   </body>
 </html>
-
diff --git a/ash/webui/sanitize_ui/resources/sanitize_done.html b/ash/webui/sanitize_ui/resources/sanitize_done.html
index 743263b..8093bd0 100644
--- a/ash/webui/sanitize_ui/resources/sanitize_done.html
+++ b/ash/webui/sanitize_ui/resources/sanitize_done.html
@@ -1 +1,256 @@
-<div id="header"></div>
+<style include="cr-shared-style sanitize-shared">
+  :host {
+    padding: 12px;
+    position: absolute;
+    background-color: var(--cros-sys-base_elevated);
+    height: 640px;
+    width: 680px;
+  }
+
+  .completed-icon {
+    height: 32px;
+    width: 32px;
+  }
+
+  .expand-container-icon {
+    height: 24px;
+    width: 24px;
+    margin-right: 12px;
+  }
+
+  div[slot="body"] {
+    border-radius: 20px;
+    padding: 32px;
+  }
+
+  .title {
+    margin-top: 16px;
+    margin-bottom: 16px;
+    font-family: var(--cros-display-5-font-family);
+    font-size: var(--cros-display-5-font-size);
+    font: var(--cros-display-5-font);
+    font-weight: var(--cros-display-5-font-weight);
+    line-height: var(--cros-display-5-line-height);
+    color: var(--cros-sys-on_surface);
+  }
+
+  .sanitize-done-description {
+    margin-bottom: 24px;
+    font-family: var(--cros-body-2-font-family);
+    font-size: var(--cros-body-2-font-size);
+    font: var(--cros-body-2-font);
+    font-weight: var(--cros-body-2-font-weight);
+    line-height: var(--cros-body-2-line-height);
+    color: var(--cros-sys-on_surface_variant);
+  }
+
+  .sanitize-done-info {
+    border-radius: 16px;
+    background-color: var(--cros-sys-secondary_container);
+  }
+
+  .sanitize-done-rollback {
+    font-family: var(--cros-button-2-font-family);
+    font-size: var(--cros-button-2-font-size);
+    font: var(--cros-button-2-font);
+    font-weight: var(--cros-button-2-font-weight);
+    line-height: var(--cros-button-2-line-height);
+    color: var(--cros-sys-on_secondary_container);
+    padding: 12px 12px 16px 12px;
+  }
+
+  .expand-buttons {
+    background-color: var(--cros-sys-app_base_shaded);
+    padding: 12px;
+    border-bottom-left-radius: 16px;
+    border-bottom-right-radius: 16px;
+    height: 290px;
+    overflow-y:scroll;
+  }
+
+  .secondary-button-container {
+    margin-left: auto;
+  }
+
+  .done-button-container {
+    text-align: right;
+    margin-top: 24px;
+  }
+
+  cr-expand-button {
+    background-color: var(--cros-sys-app_base);
+    margin-bottom:8px;
+    border-radius: var(--cr-card-border-radius);
+    padding: 14px 16px 16px 14px;
+  }
+
+  .expand-title {
+    font-family: var(--cros-button-1-font-family);
+    font-size: var(--cros-button-1-font-size);
+    font: var(--cros-button-1-font);
+    font-weight: var(--cros-button-1-font-weight);
+    line-height: var(--cros-button-1-line-height);
+    color: var(--cros-sys-on_surface);
+  }
+
+  .expand-div {
+    display: inline-flex;
+    align-items: center;
+  }
+
+  .list-container {
+    font-family: var(--cros-button-1-font-family);
+    font-size: var(--cros-button-1-font-size);
+    font: var(--cros-button-1-font);
+    font-weight: var(--cros-button-1-font-weight);
+    line-height: var(--cros-button-1-line-height);
+    color: var(--cros-sys-on_surface);
+    padding-top: 4px;
+    border-top: var(--cr-separator-line);
+    min-height: var(--settings-row-min-height);
+    display: flex;
+    align-items: center;
+  }
+
+  .list-container:not(:last-child) {
+    padding-bottom: 4px;
+  }
+</style>
+<div slot="body">
+  <div class="completed-icon-div">
+    <svg class="completed-icon"
+        preserveAspectRatio="xMidYMid meet" role="img" viewBox="0 0 32 32">
+      <use href="svg/finished_32.svg#finished_32"></use>
+    </svg>
+  </div>
+  <div id="title" class="title">$i18n{sanitizeDoneTitle}</div>
+  <div class="sanitize-done-description">
+    $i18n{sanitizeDoneExplanation}
+  </div>
+  <div class="sanitize-done-info">
+    <div class="sanitize-done-rollback">
+      $i18n{sanitizeDoneRollback}
+    </div>
+    <div class="expand-buttons">
+      <cr-expand-button class="expand-container"
+          expanded="{{extensionsExpanded_}}"
+          id="expandExtensions">
+        <div class="expand-div">
+          <svg class="expand-container-icon extensions-icon"
+               preserveAspectRatio="xMidYMid meet"
+               role="img" viewBox="0 0 32 32">
+            <use href="svg/extension_off_32.svg#extension_off_32"></use>
+          </svg>
+          <span class="expand-title">
+            $i18n{sanitizeDoneAccordionExtensionsTitle}
+          </span>
+        </div>
+        <template is="dom-if" if="[[extensionsExpanded_]]">
+          <div>
+            <div class="list-container">
+              $i18n{sanitizeDoneAccordionExtensionsReenable}
+              <span class="secondary-button-container">
+                <cros-button button-style="secondary" id="extensionsButton"
+                    on-click="onExtensionsButtonClick_" label="Extensions">
+                </cros-button>
+              </span>
+            </div>
+          </div>
+        </template>
+      </cr-expand-button>
+      <cr-expand-button
+          class="expand-container"
+          expanded="{{chromeOSSettingsInfoExpanded_}}"
+          id="expandChromeOsSettingsInfo">
+        <div class="expand-div">
+          <svg class="expand-container-icon chromeos-icon"
+              preserveAspectRatio="xMidYMid meet"
+              role="img" viewBox="0 0 24 24">
+            <use href="svg/card_settings.svg#card_settings"></use>
+          </svg>
+          <span class="expand-title">
+            $i18n{sanitizeDoneAccordionChromeOsTitle}
+          </span>
+        </div>
+        <template is="dom-if" if="[[chromeOSSettingsInfoExpanded_]]">
+          <div>
+            <div class="list-container">
+              $i18n{sanitizeDoneAccordionChromeOsInput}
+              <span class="secondary-button-container">
+                <cros-button button-style="secondary" id="chromeOsInputButton"
+                    on-click="onChromeOsInputClick_" label="ChromeOS Input">
+                </cros-button>
+              </span>
+            </div>
+            <div class="list-container">
+              $i18n{sanitizeDoneAccordionChromeOsNetwork}
+              <span class="secondary-button-container">
+                <cros-button button-style="secondary" id="chromeOsNetworkButton"
+                    on-click="onChromeOsNetworkClick_" label="ChromeOS Network">
+                </cros-button>
+              </span>
+            </div>
+          </div>
+        </template>
+      </cr-expand-button>
+      <cr-expand-button
+          class="expand-container"
+          expanded="{{chromeSettingsInfoExpanded_}}"
+          id="expandChromeSettingsInfo">
+        <div class="expand-div">
+          <svg class="expand-container-icon chrome-icon"
+              preserveAspectRatio="xMidYMid meet"
+              role="img" viewBox="0 0 24 24">
+            <use href="svg/card_chrome_product.svg#card_chrome_product"></use>
+          </svg>
+          <span class="expand-title">
+            $i18n{sanitizeDoneAccordionChromeTitle}
+          </span>
+        </div>
+        <template is="dom-if" if="[[chromeSettingsInfoExpanded_]]">
+          <div>
+            <div class="list-container">
+              $i18n{sanitizeDoneAccordionChromeSiteContent}
+              <span class="secondary-button-container">
+                <cros-button button-style="secondary"
+                    id="chromeSiteContentButton"
+                    on-click="onChromeSiteContentClick_"
+                    label="Chrome Site Content">
+                </cros-button>
+              </span>
+            </div>
+            <div class="list-container">
+              $i18n{sanitizeDoneAccordionChromeStartup}
+              <span class="secondary-button-container">
+                <cros-button button-style="secondary" id="chromeStartupButton"
+                    on-click="onChromeStartupClick_" label="Chrome Startup">
+                </cros-button>
+              </span>
+            </div>
+            <div class="list-container">
+              $i18n{sanitizeDoneAccordionChromeHomepage}
+              <span class="secondary-button-container">
+                <cros-button button-style="secondary" id="chromeHomepageButton"
+                    on-click="onChromeHomepageClick_" label="Chrome Homepage">
+                </cros-button>
+              </span>
+            </div>
+            <div class="list-container">
+              $i18n{sanitizeDoneAccordionChromeLanguages}
+              <span class="secondary-button-container">
+                <cros-button button-style="secondary" id="chromeLanguagesButton"
+                    on-click="onChromeLanguagesClick_" label="Chrome Languages">
+                </cros-button>
+              </span>
+            </div>
+          </div>
+        </template>
+      </cr-expand-button>
+    </div>
+  </div>
+  <div class="button-container done-button-container">
+    <cros-button button-style="primary" id="doneButton"
+        label="$i18n{sanitizeDoneButton}" on-click="onDoneClick_">
+    </cros-button>
+  </div>
+</div>
diff --git a/ash/webui/sanitize_ui/resources/sanitize_done.ts b/ash/webui/sanitize_ui/resources/sanitize_done.ts
index 6e99321..90b65c0 100644
--- a/ash/webui/sanitize_ui/resources/sanitize_done.ts
+++ b/ash/webui/sanitize_ui/resources/sanitize_done.ts
@@ -2,22 +2,30 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {getTemplate} from './sanitize_done.html.js';
-
-export interface SanitizeDoneElement {
-  $: {
-    header: HTMLDivElement,
-  };
-}
-
 /**
  * @fileoverview
  * 'sanitize-done' is a dialog shown after reverting to safe settings
  * (aka sanitize).
  */
-export class SanitizeDoneElement extends PolymerElement {
+import 'chrome://resources/ash/common/cr_elements/cr_shared_vars.css.js';
+import 'chrome://resources/ash/common/cr_elements/localized_link/localized_link.js';
+import 'chrome://resources/ash/common/cr_elements/cr_button/cr_button.js';
+import 'chrome://resources/ash/common/cr_elements/cr_expand_button/cr_expand_button.js';
+import 'chrome://resources/cros_components/button/button.js';
+import './sanitize_shared.css.js';
+import './strings.m.js';
+
+import {I18nMixin} from 'chrome://resources/ash/common/cr_elements/i18n_mixin.js';
+import {ColorChangeUpdater} from 'chrome://resources/cr_components/color_change_listener/colors_css_updater.js';
+import {OpenWindowProxyImpl} from 'chrome://resources/js/open_window_proxy.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {getTemplate} from './sanitize_done.html.js';
+
+
+const SanitizeDoneElementBase = I18nMixin(PolymerElement);
+
+export class SanitizeDoneElement extends SanitizeDoneElementBase {
   static get is() {
     return 'sanitize-done' as const;
   }
@@ -26,10 +34,61 @@
     return getTemplate();
   }
 
-  override ready() {
-    super.ready();
-    this.$.header.textContent = 'Sanitize Done';
+  private onExtensionsButtonClick_(): void {
+    OpenWindowProxyImpl.getInstance().openUrl('chrome://extensions');
   }
+
+  private onChromeOsInputClick_(): void {
+    OpenWindowProxyImpl.getInstance().openUrl(
+        'chrome://os-settings/osLanguages/input');
+  }
+
+  private onChromeOsNetworkClick_(): void {
+    OpenWindowProxyImpl.getInstance().openUrl('chrome://os-settings/internet');
+  }
+
+  private onChromeSiteContentClick_(): void {
+    OpenWindowProxyImpl.getInstance().openUrl('chrome://settings/content');
+  }
+
+  private onChromeStartupClick_(): void {
+    OpenWindowProxyImpl.getInstance().openUrl('chrome://settings/onStartup');
+  }
+
+  private onChromeHomepageClick_(): void {
+    OpenWindowProxyImpl.getInstance().openUrl('chrome://settings/appearance');
+  }
+
+  private onChromeLanguagesClick_(): void {
+    OpenWindowProxyImpl.getInstance().openUrl('chrome://settings/languages');
+  }
+
+  private onDoneClick_(): void {
+    window.close();
+  }
+
+  static get properties() {
+    return {
+      extensionsExpanded_: {
+        type: Boolean,
+        value: false,
+      },
+
+      chromeOSSettingsInfoExpanded_: {
+        type: Boolean,
+        value: false,
+      },
+
+      chromeSettingsInfoExpanded_: {
+        type: Boolean,
+        value: false,
+      },
+    };
+  }
+
+  private extensionsExpanded_: boolean;
+  private chromeOSSettingsInfoExpanded_: boolean;
+  private chromeSettingsInfoExpanded_: boolean;
 }
 
 declare global {
@@ -37,4 +96,6 @@
     [SanitizeDoneElement.is]: SanitizeDoneElement;
   }
 }
+
 customElements.define(SanitizeDoneElement.is, SanitizeDoneElement);
+ColorChangeUpdater.forDocument().start();
diff --git a/ash/webui/sanitize_ui/resources/sanitize_shared.css b/ash/webui/sanitize_ui/resources/sanitize_shared.css
new file mode 100644
index 0000000..dc7ce03
--- /dev/null
+++ b/ash/webui/sanitize_ui/resources/sanitize_shared.css
@@ -0,0 +1,155 @@
+/* Copyright 2024 The Chromium Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+/* #css_wrapper_metadata_start
+ * #type=style
+ * #import=chrome://resources/ash/common/navigation_shared_vars.css.js
+ * #import=chrome://resources/ash/common/cr_elements/cros_color_overrides.css.js
+ * #import=chrome://resources/ash/common/cr_elements/cr_shared_style.css.js
+ * #import=chrome://resources/ash/common/cr_elements/cr_shared_vars.css.js
+ * #include=cr-shared-style cros-color-overrides
+ * #css_wrapper_metadata_end */
+
+:host-context(body.jelly-enabled) {
+  --chart-system-line-color: var(--cros-sys-tertiary);
+  --chart-system-gradient-color: var(--cros-sys-tertiary_container);
+  --chart-user-line-color: var(--cros-sys-primary);
+  --chart-user-gradient-color: var(--cros-sys-primary_container);
+}
+
+a[href] {
+  color: var(--cr-link-color);
+}
+
+a[href]:focus {
+  outline-color: var(--cros-sys-focus_ring);
+}
+
+.link-wrapper {
+  align-items: center;
+  display: flex;
+  flex-grow: 1;
+}
+
+h2.first {
+  padding-top: 0;
+}
+
+::-webkit-scrollbar {
+  width: 6px;
+  border-radius: 3px;
+  border: 1px solid var(--cros-sys-scrollbar_border);
+  background-color: var(--cros-sys-scrollbar);
+}
+
+::-webkit-scrollbar-thumb {
+  width: 8px;
+  border-radius: 8px;
+  border: 1px solid var(--cros-sys-scrollbar_border);
+  background-color: var(--cros-sys-scrollbar_hover);
+}
+
+@media (min-width:600px) {
+  :host {
+    --container-padding: 24px;
+    --content-container-width: 552px;
+    --chart-width: 452px;
+    --chart-width-nav: 452px;
+    --data-point-container-padding: 44px;
+    --card-container-max-width: 650px;
+  }
+}
+
+@media (min-width: 650px) {
+  :host {
+    --chart-width-nav: 502px;
+  }
+}
+
+@media (min-width:769px) {
+  :host {
+    --chart-width-nav: 420px;
+  }
+}
+
+@media (min-width: 789px) {
+  :host {
+    --chart-width-nav: 440px;
+  }
+}
+
+@media (min-width: 809px) {
+  :host {
+    --chart-width-nav: 460px;
+  }
+}
+
+@media (min-width: 829px) {
+  :host {
+    --chart-width-nav: 480px;
+  }
+}
+
+@media (min-width: 849px) {
+  :host {
+    --chart-width-nav: 500px;
+  }
+}
+
+@media (min-width: 869px) {
+  :host {
+    --chart-width-nav: 520px;
+  }
+}
+
+@media (min-width: 900px) {
+  :host {
+    --chart-width-nav: 540px;
+  }
+}
+
+@media (min-width: 925px) {
+  :host {
+    --chart-width-nav: 560px;
+  }
+}
+
+@media (min-width:768px) {
+  :host {
+    --container-padding: 64px;
+    --content-container-width: 640px;
+    --chart-width: 540px;
+    --data-point-container-padding: 64px;
+  }
+}
+
+@media (min-width:960px) {
+  :host {
+    --container-padding: 160px;
+    --content-container-width: 640px;
+    --chart-width: 540px;
+    --chart-width-nav: 540px;
+    --data-point-container-padding: 64px;
+  }
+}
+
+@media (min-width:1280px) {
+  :host {
+    --container-padding: 160px;
+    --content-container-width: 680px;
+    --chart-width: 580px;
+    --chart-width-nav: 620px;
+    --data-point-container-padding: 64px;
+    --card-container-max-width: 720px;
+  }
+}
+
+@media (min-width:1440px) {
+  :host {
+    --container-padding: 360px;
+    --content-container-width: 720px;
+    --chart-width: 620px;
+    --data-point-container-padding: 64px;
+  }
+}
diff --git a/ash/webui/sanitize_ui/resources/svg/card_chrome_product.svg b/ash/webui/sanitize_ui/resources/svg/card_chrome_product.svg
new file mode 100644
index 0000000..060a9283
--- /dev/null
+++ b/ash/webui/sanitize_ui/resources/svg/card_chrome_product.svg
@@ -0,0 +1,10 @@
+<svg id="card_chrome_product" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+  <g clip-path="url(#a)">
+    <path fill="var(--cros-sys-primary)" d="M8.37917 12.0458c0 1.0084.35139 1.8639 1.05416 2.5667.70277.7028 1.55837 1.0542 2.56667 1.0542 1.0083 0 1.8639-.3514 2.5667-1.0542.7027-.7028 1.0541-1.5583 1.0541-2.5667 0-1.0083-.3514-1.8639-1.0541-2.56663C13.8639 8.77639 13.0083 8.425 12 8.425s-1.8639.35139-2.56667 1.05417c-.70277.70273-1.05416 1.55833-1.05416 2.56663ZM12 17.4771c.1833 0 .3667-.0077.55-.0229.1986-.0153.3896-.0459.5729-.0917l-2.2916 3.9187c-2.33755-.2597-4.28547-1.268-5.8438-3.025-1.54306-1.7569-2.31458-3.827-2.31458-6.2104 0-.6722.06875-1.3291.20625-1.9708.15277-.64167.36666-1.26042.64166-1.85625L7.325 14.75c.45833.8403 1.1 1.5049 1.925 1.9937.8403.4889 1.7569.7334 2.75.7334Zm0-10.86252c-1.2069 0-2.27639.35139-3.20833 1.05417-.93195.70278-1.57361 1.60417-1.925 2.70415L4.575 6.43125C5.43056 5.28542 6.5 4.38403 7.78333 3.72708 9.08194 3.05486 10.4875 2.71875 12 2.71875c1.5431 0 2.9715.35139 4.2854 1.05417 1.3292.70277 2.4215 1.65 3.2771 2.84166H12ZM20.5708 8.425c.2598.58055.4507 1.17639.573 1.7875.1222.5958.1833 1.2069.1833 1.8333 0 2.4598-.8021 4.5528-2.4063 6.2792-1.5889 1.7111-3.5902 2.7042-6.0041 2.9792L16.675 14.75c.2292-.3972.4125-.825.55-1.2833.1375-.4584.2063-.932.2063-1.4209 0-.6875-.1299-1.3368-.3896-1.9479-.2445-.62637-.5806-1.18401-1.0084-1.6729h4.5375Z"/>
+  </g>
+  <defs>
+    <clipPath id="a">
+      <path fill="var(--cros-sys-app_base)" d="M0 0h24v24H0z"/>
+    </clipPath>
+  </defs>
+</svg>
diff --git a/ash/webui/sanitize_ui/resources/svg/card_settings.svg b/ash/webui/sanitize_ui/resources/svg/card_settings.svg
new file mode 100644
index 0000000..4768123b
--- /dev/null
+++ b/ash/webui/sanitize_ui/resources/svg/card_settings.svg
@@ -0,0 +1,10 @@
+<svg id="card_settings" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
+  <g clip-path="url(#a)">
+    <path fill="var(--cros-sys-primary)" d="M9.70833 21.1667 9.25 18.3479c-.24444-.1069-.48125-.2215-.71042-.3437-.22916-.1375-.44305-.2903-.64166-.4584l-2.68125 1.0313-2.31459-3.9875L5.125 12.7792c-.01528-.1223-.03056-.2445-.04583-.3667v-.8021c.01527-.1375.03055-.2673.04583-.3896L2.90208 9.41042l2.31459-3.9875 2.68125 1.03125c.21389-.16806.42777-.3132.64166-.43542.22917-.1375.46598-.25208.71042-.34375l.45833-2.84167h4.58337L14.75 5.675c.2444.09167.4813.20625.7104.34375.2292.12222.4431.26736.6417.43542l2.6812-1.03125 2.3146 3.9875-2.2229 1.81038c.0153.1223.0229.2521.0229.3896.0153.1222.0229.2521.0229.3896s-.0076.275-.0229.4125c0 .1222-.0153.2444-.0458.3667l2.2458 1.8104-2.3146 3.9875-2.6812-1.0313c-.2139.1681-.4354.3209-.6646.4584-.2139.1222-.4431.2368-.6875.3437l-.4583 2.8188H9.70833Zm1.69587-1.9938h1.1916l.3667-2.3375c.5347-.1069 1.0313-.2903 1.4896-.55.4736-.275.8861-.6187 1.2375-1.0312l2.2229.8479.5958-1.0313-1.8562-1.4896c.0917-.2444.1604-.4965.2062-.7562.0459-.275.0688-.55.0688-.825 0-.275-.0229-.5424-.0688-.8021-.0458-.275-.1145-.5347-.2062-.7792l1.8562-1.48953-.5958-1.03125-2.2229.84791c-.3514-.4125-.7639-.74861-1.2375-1.00833-.4583-.275-.9549-.46597-1.4896-.57292l-.3667-2.3375h-1.1916l-.3667 2.3375c-.5347.10695-1.03889.29792-1.5125.57292-.45833.25972-.87083.59583-1.2375 1.00833l-2.2-.84791-.59583 1.03125L7.325 10.4187c-.09167.2445-.16042.4966-.20625.7563-.04583.2597-.06875.5347-.06875.825 0 .275.02292.55.06875.825.04583.2597.11458.5118.20625.7562l-1.83333 1.4896.59583 1.0313 2.2-.8479c.36667.4125.77917.7562 1.2375 1.0312.47361.2597.9778.4431 1.5125.55l.3667 2.3375ZM12 15.2542c.9014 0 1.6653-.3132 2.2917-.9396.6416-.6417.9625-1.4132.9625-2.3146s-.3209-1.6653-.9625-2.29167c-.6264-.64166-1.3903-.9625-2.2917-.9625s-1.6729.32084-2.31458.9625C9.05903 10.3347 8.74583 11.0986 8.74583 12s.3132 1.6729.93959 2.3146c.64168.6264 1.41318.9396 2.31458.9396Z"/>
+  </g>
+  <defs>
+    <clipPath id="a">
+      <path fill="var(--cros-sys-app_base)" d="M0 0h24v24H0z"/>
+    </clipPath>
+  </defs>
+</svg>
diff --git a/ash/webui/sanitize_ui/resources/svg/extension_off.svg b/ash/webui/sanitize_ui/resources/svg/extension_off.svg
new file mode 100644
index 0000000..794ecca
--- /dev/null
+++ b/ash/webui/sanitize_ui/resources/svg/extension_off.svg
@@ -0,0 +1,10 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" viewBox="0 0 20 20">
+  <g clip-path="url(#a)">
+    <path fill="#000" d="M4.5 17.1667c-.45833 0-.85417-.1598-1.1875-.4792-.31944-.3333-.47917-.7292-.47917-1.1875v-3.5833c.51389-.0278.95139-.2223 1.3125-.5834.36111-.375.54167-.8194.54167-1.3333 0-.51389-.18056-.95139-.54167-1.3125-.36111-.375-.79861-.57639-1.3125-.60417V4.5c0-.23611.04167-.45139.125-.64583.08334-.20834.20139-.38889.35417-.54167l1.25 1.25v2.27083c.58333.30556 1.03472.74306 1.35417 1.3125.33333.56945.5 1.1875.5 1.85417 0 .6806-.16667 1.3056-.5 1.875-.31945.5694-.77084 1.0069-1.35417 1.3125v2.25h2.25c.31944-.5833.76389-1.0347 1.33333-1.3542.56945-.3333 1.1875-.5 1.85417-.5.6667 0 1.2847.1667 1.8542.5.5694.3195 1.0139.7709 1.3333 1.3542h2.25l1.25 1.25c-.1528.1528-.3333.2708-.5417.3542-.1944.0833-.4097.125-.6458.125h-3.5833c-.0278-.5139-.2292-.9514-.6042-1.3125-.3611-.3611-.7986-.5417-1.3125-.5417-.51389 0-.95833.1806-1.33333.5417-.36111.3611-.55556.7986-.58334 1.3125H4.5Zm12.6667-2.2917-1.7292-1.7292V10.5h1.5417c.125 0 .2361-.0486.3333-.1458.1111-.0973.1667-.2153.1667-.3542 0-.13889-.0556-.25694-.1667-.35417-.0972-.09722-.2083-.14583-.3333-.14583h-1.5417V4.5625H10.5V3.02083c0-.125-.0486-.23611-.1458-.33333-.0973-.11111-.2153-.16667-.3542-.16667-.13889 0-.25694.05556-.35417.16667-.09722.09722-.14583.20833-.14583.33333V4.5625H6.85417L5.125 2.83333h2.72917c.04166-.58333.26389-1.06944.66666-1.45833C8.9375.98611 9.43056.791665 10 .791665c.5694 0 1.0556.194445 1.4583.583335.4167.38889.6459.875.6875 1.45833H15.5c.4583 0 .8472.16667 1.1667.5.3333.31945.5.70834.5 1.16667v3.35417c.5833.04166 1.0694.27083 1.4583.6875.3889.40277.5833.88889.5833 1.45833 0 .5694-.1944 1.0625-.5833 1.4792-.3889.4027-.875.625-1.4583.6666v2.7292Zm-.9792 3.4583L1.66667 3.8125l1.10416-1.10417L17.2917 17.2292l-1.1042 1.1041Z"/>
+  </g>
+  <defs>
+    <clipPath id="a">
+      <path fill="#fff" d="M0 0h20v20H0z"/>
+    </clipPath>
+  </defs>
+</svg>
diff --git a/ash/webui/sanitize_ui/resources/svg/extension_off_32.svg b/ash/webui/sanitize_ui/resources/svg/extension_off_32.svg
new file mode 100644
index 0000000..1fc050b
--- /dev/null
+++ b/ash/webui/sanitize_ui/resources/svg/extension_off_32.svg
@@ -0,0 +1,10 @@
+<svg id="extension_off_32" xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="none" viewBox="0 0 32 32">
+  <g clip-path="url(#a)">
+    <path fill="var(--cros-sys-primary)" d="M6.43333 28.2333c-.73333 0-1.36666-.2555-1.9-.7666-.51111-.5334-.76666-1.1667-.76666-1.9V20.1c.97777-.0444 1.82222-.3889 2.53333-1.0333.73333-.6445 1.1-1.4556 1.1-2.4334 0-.9777-.36667-1.7889-1.1-2.4333-.71111-.6444-1.55556-.9889-2.53333-1.0333V7.7c0-.37778.06666-.72222.2-1.03333.13333-.33334.32222-.62223.56666-.86667L26.2 27.4667c-.2444.2444-.5333.4333-.8667.5666-.3111.1334-.6555.2-1.0333.2h-5.4667c-.0444-.9777-.3889-1.8222-1.0333-2.5333-.6444-.7333-1.4556-1.1-2.4333-1.1-.9778 0-1.7889.3667-2.4334 1.1-.6444.7111-.9889 1.5556-1.0333 2.5333H6.43333Zm20.53337-5L8.76667 5.03333h3.00003c.1333-.95555.5333-1.74444 1.2-2.36666C13.6333 2.02222 14.4444 1.7 15.4 1.7c.9333 0 1.7333.32222 2.4.96667.6889.62222 1.1 1.41111 1.2333 2.36666H24.3c.7333 0 1.3556.26667 1.8667.8.5333.51111.8 1.13334.8 1.86667v5.2667c.9555.1333 1.7444.5444 2.3666 1.2333.6223.6889.9334 1.5111.9334 2.4667 0 .9333-.3111 1.7333-.9334 2.4-.6222.6666-1.4111 1.0666-2.3666 1.2v2.9666ZM26.9 30.4 1.6 5.1l1.8-1.8 25.3 25.3-1.8 1.8Z"/>
+  </g>
+  <defs>
+    <clipPath id="a">
+      <path fill="var(--cros-sys-app_base)" d="M0 0h32v32H0z"/>
+    </clipPath>
+  </defs>
+</svg>
diff --git a/ash/webui/sanitize_ui/resources/svg/finished_32.svg b/ash/webui/sanitize_ui/resources/svg/finished_32.svg
new file mode 100644
index 0000000..c8d15dc
--- /dev/null
+++ b/ash/webui/sanitize_ui/resources/svg/finished_32.svg
@@ -0,0 +1,3 @@
+<svg id="finished_32" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
+  <path fill="var(--cros-sys-positive)" fill-rule="evenodd" d="M30.3996 16.0001c0 7.9529-6.4471 14.4-14.4 14.4-7.95289 0-14.39999-6.4471-14.39999-14.4 0-7.9529 6.4471-14.4 14.39999-14.4 7.9529 0 14.4 6.4471 14.4 14.4Zm-7.7272-4.8728c-.7029-.7029-1.8426-.7029-2.5456 0l-5.9272 5.9272-2.3272-2.3272c-.7029-.7029-1.8426-.7029-2.54558 0-.70295.7029-.70295 1.8426 0 2.5456l3.59998 3.6c.703.7029 1.8427.7029 2.5456 0l7.2-7.2c.7029-.703.7029-1.8427 0-2.5456Z" clip-rule="evenodd"/>
+</svg>
diff --git a/ash/webui/sanitize_ui/sanitize_ui.cc b/ash/webui/sanitize_ui/sanitize_ui.cc
index ce36754..e9373432 100644
--- a/ash/webui/sanitize_ui/sanitize_ui.cc
+++ b/ash/webui/sanitize_ui/sanitize_ui.cc
@@ -24,6 +24,7 @@
       network::mojom::CSPDirectiveName::ScriptSrc,
       "script-src chrome://resources chrome://webui-test 'self';");
   ash::EnableTrustedTypesCSP(html_source);
+  html_source->UseStringsJs();
   html_source->EnableReplaceI18nInJS();
 
   const auto resources =
@@ -34,10 +35,44 @@
   html_source->AddResourcePath("test_loader.js", IDR_WEBUI_JS_TEST_LOADER_JS);
   html_source->AddResourcePath("test_loader_util.js",
                                IDR_WEBUI_JS_TEST_LOADER_UTIL_JS);
+
+  webui::LocalizedString kLocalizedStrings[] = {
+      {"sanitizeDoneTitle", IDS_SANITIZE_DONE_HEADING},
+      {"sanitizeDoneExplanation", IDS_SANITIZE_DONE_DESCRIPTION},
+      {"sanitizeDoneRollback", IDS_SANITIZE_DONE_ROLLBACK},
+      {"sanitizeDoneButton", IDS_SANITIZE_DONE},
+      {"sanitizeDoneAccordionExtensionsTitle",
+       IDS_SANITIZE_DONE_ACCORDION_EXTENSIONS_TITLE},
+      {"sanitizeDoneAccordionExtensionsReenable",
+       IDS_SANITIZE_DONE_ACCORDION_EXTENSIONS_REENABLE},
+      {"sanitizeDoneAccordionChromeOsTitle",
+       IDS_SANITIZE_DONE_ACCORDION_CHROMEOS_TITLE},
+      {"sanitizeDoneAccordionChromeOsInput",
+       IDS_SANITIZE_DONE_ACCORDION_CHROMEOS_INPUT},
+      {"sanitizeDoneAccordionChromeOsNetwork",
+       IDS_SANITIZE_DONE_ACCORDION_CHROMEOS_NETWORK},
+      {"sanitizeDoneAccordionChromeTitle",
+       IDS_SANITIZE_DONE_ACCORDION_CHROME_TITLE},
+      {"sanitizeDoneAccordionChromeSiteContent",
+       IDS_SANITIZE_DONE_ACCORDION_CHROME_SITE_CONTENT},
+      {"sanitizeDoneAccordionChromeStartup",
+       IDS_SANITZIE_DONE_ACCORDION_CHROME_STARTUP},
+      {"sanitizeDoneAccordionChromeHomepage",
+       IDS_SANITIZE_DONE_ACCORDION_CHROME_HOMEPAGE},
+      {"sanitizeDoneAccordionChromeLanguages",
+       IDS_SANITIZE_DONE_ACCORDION_CHROME_LANGUAGES},
+  };
+  html_source->AddLocalizedStrings(kLocalizedStrings);
 }
 
 SanitizeDialogUI::~SanitizeDialogUI() {}
 
+void SanitizeDialogUI::BindInterface(
+    mojo::PendingReceiver<color_change_listener::mojom::PageHandler> receiver) {
+  color_provider_handler_ = std::make_unique<ui::ColorChangeHandler>(
+      web_ui()->GetWebContents(), std::move(receiver));
+}
+
 WEB_UI_CONTROLLER_TYPE_IMPL(SanitizeDialogUI)
 
 }  // namespace ash
diff --git a/ash/webui/sanitize_ui/sanitize_ui.h b/ash/webui/sanitize_ui/sanitize_ui.h
index dec1f0e..218ccba 100644
--- a/ash/webui/sanitize_ui/sanitize_ui.h
+++ b/ash/webui/sanitize_ui/sanitize_ui.h
@@ -8,6 +8,8 @@
 #include "ash/webui/common/chrome_os_webui_config.h"
 #include "ash/webui/sanitize_ui/url_constants.h"
 #include "ui/web_dialogs/web_dialog_ui.h"
+#include "ui/webui/color_change_listener/color_change_handler.h"
+#include "ui/webui/resources/cr_components/color_change_listener/color_change_listener.mojom.h"
 
 namespace ash {
 class SanitizeDialogUI;
@@ -30,9 +32,15 @@
 
   SanitizeDialogUI(const SanitizeDialogUI&) = delete;
   SanitizeDialogUI& operator=(const SanitizeDialogUI&) = delete;
+  void BindInterface(
+      mojo::PendingReceiver<color_change_listener::mojom::PageHandler>
+          receiver);
 
  private:
   WEB_UI_CONTROLLER_TYPE_DECL();
+  // The color change handler notifies the WebUI when the color provider
+  // changes.
+  std::unique_ptr<ui::ColorChangeHandler> color_provider_handler_;
 };
 
 }  // namespace ash
diff --git a/base/BUILD.gn b/base/BUILD.gn
index b3e994e..b51b58a0 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -5088,7 +5088,7 @@
       ":base_cached_flags_java",
       ":base_java",
       "//build/android:build_java",
-      "//testing/android/instrumentation:instrumentation_test_runner_java",
+      "//testing/android/instrumentation:test_runner_java",
       "//third_party/accessibility_test_framework:accessibility_core_java",
       "//third_party/android_deps:com_google_code_findbugs_jsr305_java",
       "//third_party/android_deps:espresso_java",
@@ -5343,7 +5343,7 @@
       ":base_junit_test_support",
       ":base_shared_preferences_java",
       "//base/test:test_support_java",
-      "//testing/android/instrumentation:instrumentation_test_runner_java",
+      "//testing/android/instrumentation:test_runner_java",
       "//third_party/android_deps:guava_android_java",
       "//third_party/androidx:androidx_annotation_annotation_java",
       "//third_party/androidx:androidx_test_core_java",
diff --git a/base/containers/buffer_iterator.h b/base/containers/buffer_iterator.h
index 0fa382d..9f4dada 100644
--- a/base/containers/buffer_iterator.h
+++ b/base/containers/buffer_iterator.h
@@ -12,6 +12,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "base/numerics/checked_math.h"
 
 namespace base {
@@ -231,9 +232,9 @@
 
  private:
   // The original buffer that the iterator was constructed with.
-  const span<B> buffer_;
+  const raw_span<B> buffer_;
   // A subspan of `buffer_` containing the remaining bytes to iterate over.
-  span<B> remaining_;
+  raw_span<B> remaining_;
   // Copy and assign allowed.
 };
 
diff --git a/base/containers/checked_iterators.h b/base/containers/checked_iterators.h
index ee9859b..312a8dd 100644
--- a/base/containers/checked_iterators.h
+++ b/base/containers/checked_iterators.h
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
-#pragma allow_unsafe_buffers
-#endif
-
 #ifndef BASE_CONTAINERS_CHECKED_ITERATORS_H_
 #define BASE_CONTAINERS_CHECKED_ITERATORS_H_
 
@@ -44,10 +39,27 @@
 
   constexpr CheckedContiguousIterator() = default;
 
+  // Constructs an iterator from `start` to `end`, starting at `start`.
+  //
+  // # Safety
+  // `start` and `end` must point to a single allocation.
+  //
+  // # Checks
+  // This function CHECKs that `start <= end` and will terminate otherwise.
   UNSAFE_BUFFER_USAGE constexpr CheckedContiguousIterator(T* start,
                                                           const T* end)
-      : CheckedContiguousIterator(start, start, end) {}
+      : start_(start), current_(start), end_(end) {
+    CHECK_LE(start, end);
+  }
 
+  // Constructs an iterator from `start` to `end`, starting at `current`.
+  //
+  // # Safety
+  // `start`, `current` and `end` must point to a single allocation.
+  //
+  // # Checks
+  // This function CHECKs that `start <= current <= end` and will terminate
+  // otherwise.
   UNSAFE_BUFFER_USAGE constexpr CheckedContiguousIterator(const T* start,
                                                           T* current,
                                                           const T* end)
@@ -94,7 +106,10 @@
 
   constexpr CheckedContiguousIterator& operator++() {
     CHECK_NE(current_, end_);
-    ++current_;
+    // SAFETY: `current_ <= end_` is an invariant maintained internally, and the
+    // CHECK above ensures that we are not at the end yet, so incrementing stays
+    // in bounds of the allocation.
+    UNSAFE_BUFFERS(++current_);
     return *this;
   }
 
@@ -106,7 +121,10 @@
 
   constexpr CheckedContiguousIterator& operator--() {
     CHECK_NE(current_, start_);
-    --current_;
+    // SAFETY: `current_ >= start_` is an invariant maintained internally, and
+    // the CHECK above ensures that we are not at the start yet, so decrementing
+    // stays in bounds of the allocation.
+    UNSAFE_BUFFERS(--current_);
     return *this;
   }
 
@@ -117,12 +135,17 @@
   }
 
   constexpr CheckedContiguousIterator& operator+=(difference_type rhs) {
-    if (rhs > 0) {
-      CHECK_LE(rhs, end_ - current_);
-    } else {
-      CHECK_LE(-rhs, current_ - start_);
-    }
-    current_ += rhs;
+    // NOTE: Since the max allocation size is PTRDIFF_MAX (in our compilers),
+    // subtracting two pointers from the same allocation can not underflow.
+    CHECK_LE(rhs, end_ - current_);
+    CHECK_GE(rhs, start_ - current_);
+    // SAFETY: `current_ <= end_` is an invariant maintained internally. The
+    // checks above ensure:
+    // `start_ - current_ <= rhs <= end_ - current_`.
+    // Which means:
+    // `start_ <= rhs + current <= end_`, so `current_` will remain in bounds of
+    // the allocation after adding `rhs`.
+    UNSAFE_BUFFERS(current_ += rhs);
     return *this;
   }
 
@@ -139,12 +162,17 @@
   }
 
   constexpr CheckedContiguousIterator& operator-=(difference_type rhs) {
-    if (rhs < 0) {
-      CHECK_LE(-rhs, end_ - current_);
-    } else {
-      CHECK_LE(rhs, current_ - start_);
-    }
-    current_ -= rhs;
+    // NOTE: Since the max allocation size is PTRDIFF_MAX (in our compilers),
+    // subtracting two pointers from the same allocation can not underflow.
+    CHECK_GE(rhs, current_ - end_);
+    CHECK_LE(rhs, current_ - start_);
+    // SAFETY: `start_ <= current_` is an invariant maintained internally. The
+    // checks above ensure:
+    // `current_ - end_ <= rhs <= current_ - start_`.
+    // Which means:
+    // `end_ >= current - rhs >= start_`, so `current_` will remain in bounds
+    // of the allocation after subtracting `rhs`.
+    UNSAFE_BUFFERS(current_ -= rhs);
     return *this;
   }
 
@@ -172,17 +200,27 @@
   }
 
   constexpr reference operator[](difference_type rhs) const {
-    CHECK_GE(rhs, 0);
+    // NOTE: Since the max allocation size is PTRDIFF_MAX (in our compilers),
+    // subtracting two pointers from the same allocation can not underflow.
+    CHECK_GE(rhs, start_ - current_);
     CHECK_LT(rhs, end_ - current_);
-    return current_[rhs];
+    // SAFETY: `start_ <= current_ <= end_` is an invariant maintained
+    // internally. The checks above ensure:
+    // `start_ - current_ <= rhs < end_ - current_`.
+    // Which means:
+    // `start_ <= current_ + rhs < end_`.
+    // So `current_[rhs]` will be a valid dereference of a pointer in the
+    // allocation (it is not the pointer toone-past-the-end).
+    return UNSAFE_BUFFERS(current_[rhs]);
   }
 
   [[nodiscard]] static bool IsRangeMoveSafe(
       const CheckedContiguousIterator& from_begin,
       const CheckedContiguousIterator& from_end,
       const CheckedContiguousIterator& to) {
-    if (from_end < from_begin)
+    if (from_end < from_begin) {
       return false;
+    }
     const auto from_begin_uintptr = get_uintptr(from_begin.current_);
     const auto from_end_uintptr = get_uintptr(from_end.current_);
     const auto to_begin_uintptr = get_uintptr(to.current_);
diff --git a/base/containers/checked_iterators_unittest.cc b/base/containers/checked_iterators_unittest.cc
index 3387231..08401828 100644
--- a/base/containers/checked_iterators_unittest.cc
+++ b/base/containers/checked_iterators_unittest.cc
@@ -2,18 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "base/containers/checked_iterators.h"
 
 #include <algorithm>
 #include <iterator>
 
 #include "base/check_op.h"
+#include "base/debug/alias.h"
 #include "base/ranges/algorithm.h"
+#include "base/test/gtest_util.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -23,31 +20,55 @@
   static_assert(std::contiguous_iterator<CheckedContiguousIterator<int>>);
 }
 
+template <class T, size_t N>
+constexpr CheckedContiguousConstIterator<T> MakeConstIter(T (&arr)[N],
+                                                          size_t cur) {
+  // We allow cur == N as that makes a pointer at one-past-the-end which is
+  // considered part of the same allocation.
+  CHECK_LE(cur, N);
+  return
+      // SAFETY: `arr` has 1 element, `arr + 1` is considered a pointer into the
+      // same allocation, as it's one past the end.
+      UNSAFE_BUFFERS(
+          CheckedContiguousConstIterator<T>(arr, arr + cur, arr + N));
+}
+
+template <class T, size_t N>
+constexpr CheckedContiguousIterator<T> MakeIter(T (&arr)[N], size_t cur) {
+  // We allow cur == N as that makes a pointer at one-past-the-end which is
+  // considered part of the same allocation.
+  CHECK_LE(cur, N);
+  return
+      // SAFETY: `arr` has 1 element, `arr + 1` is considered a pointer into the
+      // same allocation, as it's one past the end.
+      UNSAFE_BUFFERS(CheckedContiguousIterator<T>(arr, arr + cur, arr + N));
+}
+
 // Checks that constexpr CheckedContiguousConstIterators can be compared at
 // compile time.
 TEST(CheckedContiguousIterator, StaticComparisonOperators) {
   static constexpr int arr[] = {0};
 
-  constexpr CheckedContiguousConstIterator<int> begin(arr, arr, arr + 1);
-  constexpr CheckedContiguousConstIterator<int> end(arr, arr + 1, arr + 1);
+  constexpr CheckedContiguousConstIterator<int> begin = MakeConstIter(arr, 0u);
+  constexpr CheckedContiguousConstIterator<int> end = MakeConstIter(arr, 1u);
 
-  static_assert(begin == begin, "");
-  static_assert(end == end, "");
+  static_assert(begin == begin);
+  static_assert(end == end);
 
-  static_assert(begin != end, "");
-  static_assert(end != begin, "");
+  static_assert(begin != end);
+  static_assert(end != begin);
 
-  static_assert(begin < end, "");
+  static_assert(begin < end);
 
-  static_assert(begin <= begin, "");
-  static_assert(begin <= end, "");
-  static_assert(end <= end, "");
+  static_assert(begin <= begin);
+  static_assert(begin <= end);
+  static_assert(end <= end);
 
-  static_assert(end > begin, "");
+  static_assert(end > begin);
 
-  static_assert(end >= end, "");
-  static_assert(end >= begin, "");
-  static_assert(begin >= begin, "");
+  static_assert(end >= end);
+  static_assert(end >= begin);
+  static_assert(begin >= begin);
 }
 
 // Checks that comparison between iterators and const iterators works in both
@@ -55,11 +76,11 @@
 TEST(CheckedContiguousIterator, ConvertingComparisonOperators) {
   static int arr[] = {0};
 
-  CheckedContiguousIterator<int> begin(arr, arr, arr + 1);
-  CheckedContiguousConstIterator<int> cbegin(arr, arr, arr + 1);
+  CheckedContiguousIterator<int> begin = MakeIter(arr, 0u);
+  CheckedContiguousConstIterator<int> cbegin = MakeConstIter(arr, 0u);
 
-  CheckedContiguousIterator<int> end(arr, arr + 1, arr + 1);
-  CheckedContiguousConstIterator<int> cend(arr, arr + 1, arr + 1);
+  CheckedContiguousIterator<int> end = MakeIter(arr, 1u);
+  CheckedContiguousConstIterator<int> cend = MakeConstIter(arr, 1u);
 
   EXPECT_EQ(begin, cbegin);
   EXPECT_EQ(cbegin, begin);
@@ -92,6 +113,60 @@
   EXPECT_GE(cbegin, begin);
 }
 
+TEST(CheckedContiguousIteratorDeathTest, OutOfBounds) {
+  static int arr[] = {0, 1, 2};
+
+  CheckedContiguousIterator<int> it = MakeIter(arr, 1u);
+
+  EXPECT_CHECK_DEATH(base::debug::Alias(&it[-2]));
+  EXPECT_EQ(it[-1], 0);
+  EXPECT_EQ(it[0], 1);
+  EXPECT_EQ(it[1], 2);
+  EXPECT_CHECK_DEATH(base::debug::Alias(&it[3]));
+
+  it += 2;  // At [3], in bounds (at end).
+  it -= 3;  // At [0], in bounds.
+  it += 1;  // Back to [1], in bounds.
+
+  EXPECT_CHECK_DEATH({
+    it -= 2;
+    base::debug::Alias(&it);
+  });
+  EXPECT_CHECK_DEATH({
+    it += 3;
+    base::debug::Alias(&it);
+  });
+  EXPECT_CHECK_DEATH({
+    auto o = it - 2;
+    base::debug::Alias(&o);
+  });
+  EXPECT_CHECK_DEATH({
+    auto o = it + 3;
+    base::debug::Alias(&o);
+  });
+
+  it++;  // At [2], in bounds.
+  ++it;  // At [3], in bounds (at end).
+  EXPECT_CHECK_DEATH({
+    ++it;
+    base::debug::Alias(&it);
+  });
+  EXPECT_CHECK_DEATH({
+    it++;
+    base::debug::Alias(&it);
+  });
+
+  it -= 3;  // At [0], in bounds.
+  EXPECT_CHECK_DEATH({
+    --it;
+    base::debug::Alias(&it);
+  });
+  EXPECT_CHECK_DEATH({
+    it--;
+    base::debug::Alias(&it);
+  });
+}
+
 }  // namespace base
 
 namespace {
@@ -134,9 +209,9 @@
   int arr_in[5] = {1, 2, 3, 4, 5};
   int arr_out[5];
 
-  Iter in_begin(std::begin(arr_in), std::end(arr_in));
-  Iter in_end(std::begin(arr_in), std::end(arr_in), std::end(arr_in));
-  Iter out_begin(std::begin(arr_out), std::end(arr_out));
+  Iter in_begin = MakeIter(arr_in, 0u);
+  Iter in_end = MakeIter(arr_in, 5u);
+  Iter out_begin = MakeIter(arr_out, 0u);
   Iter out_end = std::copy(in_begin, in_end, out_begin);
   EXPECT_EQ(out_end, out_begin + (in_end - in_begin));
 
diff --git a/base/containers/span_reader.h b/base/containers/span_reader.h
index 58ed336..aacb2de 100644
--- a/base/containers/span_reader.h
+++ b/base/containers/span_reader.h
@@ -9,6 +9,7 @@
 #include <optional>
 
 #include "base/containers/span.h"
+#include "base/memory/stack_allocated.h"
 #include "base/numerics/byte_conversions.h"
 #include "base/numerics/safe_conversions.h"
 
@@ -21,6 +22,8 @@
 // with span directly).
 template <class T>
 class SpanReader {
+  STACK_ALLOCATED();
+
  public:
   // Construct SpanReader from a span.
   explicit SpanReader(span<T> buf) : buf_(buf), original_size_(buf_.size()) {}
diff --git a/base/metrics/histogram_threadsafe_unittest.cc b/base/metrics/histogram_threadsafe_unittest.cc
index e0b190d..9c1006f 100644
--- a/base/metrics/histogram_threadsafe_unittest.cc
+++ b/base/metrics/histogram_threadsafe_unittest.cc
@@ -1,14 +1,11 @@
 // Copyright 2023 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-
 #ifdef UNSAFE_BUFFERS_BUILD
 // TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
 #pragma allow_unsafe_buffers
 #endif
 
-#include "base/metrics/histogram.h"
-
 #include <memory>
 #include <set>
 #include <string>
@@ -16,7 +13,9 @@
 
 #include "base/atomicops.h"
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "base/metrics/bucket_ranges.h"
+#include "base/metrics/histogram.h"
 #include "base/metrics/persistent_histogram_allocator.h"
 #include "base/metrics/sparse_histogram.h"
 #include "base/no_destructor.h"
@@ -147,12 +146,12 @@
   }
 
   const size_t num_emissions_;
-  span<HistogramBase*> histograms_;
+  raw_span<HistogramBase*> histograms_;
   const HistogramBase::Sample histogram_max_;
   raw_ptr<subtle::Atomic32> real_total_samples_count_;
-  span<subtle::Atomic32> real_bucket_counts_;
+  raw_span<subtle::Atomic32> real_bucket_counts_;
   raw_ptr<subtle::Atomic32> snapshots_total_samples_count_;
-  span<subtle::Atomic32> snapshots_bucket_counts_;
+  raw_span<subtle::Atomic32> snapshots_bucket_counts_;
 };
 
 }  // namespace
diff --git a/base/metrics/persistent_memory_allocator_unittest.cc b/base/metrics/persistent_memory_allocator_unittest.cc
index d5f72b41..82a851d 100644
--- a/base/metrics/persistent_memory_allocator_unittest.cc
+++ b/base/metrics/persistent_memory_allocator_unittest.cc
@@ -17,6 +17,7 @@
 #include "base/files/memory_mapped_file.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_span.h"
 #include "base/memory/read_only_shared_memory_region.h"
 #include "base/memory/shared_memory_mapping.h"
 #include "base/memory/writable_shared_memory_region.h"
@@ -399,7 +400,7 @@
 
  private:
   raw_ptr<PersistentMemoryAllocator> allocator_;
-  span<Reference> refs_;
+  raw_span<Reference> refs_;
 };
 
 // Verifies that multiple threads making the same objects iterable doesn't cause
diff --git a/base/profiler/chrome_unwind_info_android.h b/base/profiler/chrome_unwind_info_android.h
index db08ef8..8483b31 100644
--- a/base/profiler/chrome_unwind_info_android.h
+++ b/base/profiler/chrome_unwind_info_android.h
@@ -9,6 +9,7 @@
 
 #include "base/base_export.h"
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 
 namespace base {
 
@@ -127,7 +128,7 @@
   // - 10101nnn
   // - 10110000
   // - 10110010 uleb128
-  span<const uint8_t> unwind_instruction_table;
+  raw_span<const uint8_t> unwind_instruction_table;
 
   // Function offset table is expected to have following memory layout:
   // +---------------------+---------------------+
@@ -158,7 +159,7 @@
   // - Within each function section, offset strictly decreases. By doing so,
   //   each function's own terminal instruction will serve as termination
   //   condition when searching in the table.
-  span<const uint8_t> function_offset_table;
+  raw_span<const uint8_t> function_offset_table;
 
   // The function table represents the individual functions within a 128kb page.
   // The relevant entry for an instruction offset from the start of the text
@@ -188,7 +189,7 @@
   // - Within each page, `Page Offset` strictly increases.
   // - Each `FunctionTableEntry` represents a function where the start
   // address falls into the page memory address range.
-  span<const FunctionTableEntry> function_table;
+  raw_span<const FunctionTableEntry> function_table;
 
   // The page table represents discrete 128kb 'pages' of memory in the text
   // section, each of which contains functions. The page table is indexed by
@@ -212,7 +213,7 @@
   // Note:
   // - The page start instructions in page table non-strictly increases, i.e
   // empty page is allowed.
-  span<const uint32_t> page_table;
+  raw_span<const uint32_t> page_table;
 };
 
 // Creates `ChromeUnwindInfoAndroid` struct based on binary `data` assuming
diff --git a/base/profiler/chrome_unwind_info_android_unittest.cc b/base/profiler/chrome_unwind_info_android_unittest.cc
index 4d7aec7..2785925 100644
--- a/base/profiler/chrome_unwind_info_android_unittest.cc
+++ b/base/profiler/chrome_unwind_info_android_unittest.cc
@@ -24,8 +24,13 @@
                   e2.function_offset_table_byte_index);
 }
 
-template <class T, size_t E1, size_t E2>
-void ExpectSpanSizeAndContentsEqual(span<T, E1> actual, span<T, E2> expected) {
+template <class T,
+          size_t E1,
+          size_t E2,
+          typename InternalPtrType1,
+          typename InternalPtrType2>
+void ExpectSpanSizeAndContentsEqual(span<T, E1, InternalPtrType1> actual,
+                                    span<T, E2, InternalPtrType2> expected) {
   EXPECT_EQ(actual.size(), expected.size());
   if (actual.size() != expected.size()) {
     return;
diff --git a/base/task/sequence_manager/lazily_deallocated_deque.h b/base/task/sequence_manager/lazily_deallocated_deque.h
index 7781074..73edc79 100644
--- a/base/task/sequence_manager/lazily_deallocated_deque.h
+++ b/base/task/sequence_manager/lazily_deallocated_deque.h
@@ -19,6 +19,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/raw_ptr_exclusion.h"
+#include "base/memory/raw_span.h"
 #include "base/time/time.h"
 
 namespace base {
@@ -315,7 +316,7 @@
     size_t front_index_ = 0;
     size_t back_index_ = 0;
     std::unique_ptr<char[]> backing_store_;
-    base::span<T> data_;
+    base::raw_span<T> data_;
     std::unique_ptr<Ring> next_ = nullptr;
   };
 
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 2ed5851..d1d3e3d5 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -3658,7 +3658,7 @@
       }
 
       deps = [
-        "//testing/android/instrumentation:instrumentation_test_runner_java",
+        "//testing/android/instrumentation:test_runner_java",
       ]
       if (defined(invoker.deps)) {
         deps += invoker.deps
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index f598fd1..d6af230 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -424,7 +424,11 @@
       # links.
       ldflags += [ "-Wl,--build-id=sha1" ]
     } else if (current_os != "aix" && current_os != "zos") {
-      ldflags += [ "-Wl,--build-id" ]
+      if (use_lld && !is_nacl) {
+        ldflags += [ "-Wl,--build-id=fast" ]
+      } else {
+        ldflags += [ "-Wl,--build-id" ]
+      }
     }
 
     if (!is_android) {
diff --git a/build/util/lib/proto/measures.py b/build/util/lib/proto/measures.py
index 4486c2b3..29c8c72 100755
--- a/build/util/lib/proto/measures.py
+++ b/build/util/lib/proto/measures.py
@@ -5,7 +5,11 @@
 # found in the LICENSE file.
 """ The module to create and manage measures using in the process. """
 
-from typing import Iterable
+import json
+import os
+
+from google.protobuf import any_pb2
+from google.protobuf.json_format import MessageToJson
 
 from average import Average
 from count import Count
@@ -13,6 +17,10 @@
 from measure import Measure
 from metric import Metric
 
+# The file name is used as the key when being loaded into the ResultDB and
+# shouldn't be changed.
+TEST_SCRIPT_METRICS_JSONPB_FILENAME = 'test_script_metrics.jsonpb'
+
 _metric = Metric()
 
 
@@ -37,3 +45,19 @@
 
 def data_points(*name_pieces: str) -> DataPoints:
   return _register(DataPoints(_create_name(*name_pieces)))
+
+
+# TODO(crbug.com/343242386): May need to implement a lock and reset logic to
+# clear in-memory data and lock the instance to block further operations and
+# avoid accidentally accumulating data which won't be published at all.
+def dump(dir_path: str) -> None:
+  """Dumps the metric data into test_script_metrics.jsonpb in the |path|."""
+  os.makedirs(dir_path, exist_ok=True)
+  any_msg = any_pb2.Any()
+  any_msg.Pack(_metric.dump())
+  with open(os.path.join(dir_path, TEST_SCRIPT_METRICS_JSONPB_FILENAME),
+            'w',
+            encoding='utf-8') as wf:
+    wf.write(
+        MessageToJson(any_msg, preserving_proto_field_name=True,
+                      sort_keys=True))
diff --git a/build/util/lib/proto/measures_unittests.py b/build/util/lib/proto/measures_unittests.py
index 0115e63..5e865cb 100755
--- a/build/util/lib/proto/measures_unittests.py
+++ b/build/util/lib/proto/measures_unittests.py
@@ -5,10 +5,19 @@
 # found in the LICENSE file.
 """File for testing measures.py."""
 
-import measures
+import os
+import sys
+import tempfile
 import unittest
+
+import google.protobuf.json_format as json_format
+
+from google.protobuf import any_pb2
+
+import measures
+
 from measure import Measure
-from test_script_metrics_pb2 import TestScriptMetric
+from test_script_metrics_pb2 import TestScriptMetric, TestScriptMetrics
 
 
 class MeasuresTest(unittest.TestCase):
@@ -44,6 +53,44 @@
       measures.average('a')
     self.assertEqual(len(measures._metric._metrics), before + 3)
 
+  def test_dump(self) -> None:
+    before = len(measures._metric._metrics)
+    count = measures.count('test', 'dump')
+    for _ in range(101):
+      count.record()
+    with tempfile.TemporaryDirectory() as tmpdir:
+      measures.dump(tmpdir)
+      with open(os.path.join(tmpdir,
+                             measures.TEST_SCRIPT_METRICS_JSONPB_FILENAME),
+                'r',
+                encoding='utf-8') as rf:
+        any_msg = json_format.Parse(rf.read(), any_pb2.Any())
+        message = TestScriptMetrics()
+        self.assertTrue(any_msg.Unpack(message))
+    self.assertEqual(len(message.metrics), before + 1)
+    exp = TestScriptMetric()
+    exp.name = 'test/dump'
+    exp.value = 101
+    self.assertEqual(message.metrics[-1], exp)
+
+  def test_dump_with_type(self) -> None:
+    with tempfile.TemporaryDirectory() as tmpdir:
+      measures.dump(tmpdir)
+      with open(os.path.join(tmpdir,
+                             measures.TEST_SCRIPT_METRICS_JSONPB_FILENAME),
+                'r',
+                encoding='utf-8') as rf:
+        txt = rf.read()
+        self.assertTrue('"@type":' in txt)
+        self.assertTrue(TestScriptMetrics().DESCRIPTOR.full_name in txt)
+
+  def test_dump_create_dir(self) -> None:
+    with tempfile.TemporaryDirectory() as tmpdir:
+      dir_path = os.path.join(tmpdir, 'hello', 'this', 'dir', 'should', 'not',
+                              'exist')
+      measures.dump(dir_path)
+      self.assertTrue(os.path.isdir(dir_path))
+
 
 if __name__ == '__main__':
   unittest.main()
diff --git a/build/util/lib/proto/metric.py b/build/util/lib/proto/metric.py
index 544e7847..9751cf19 100755
--- a/build/util/lib/proto/metric.py
+++ b/build/util/lib/proto/metric.py
@@ -17,9 +17,6 @@
   def register(self, metric: Measure) -> None:
     self._metrics.append(metric)
 
-  # Dumping to the protobuf is mostly for testing purpose only. The real use
-  # case would dump everything into a json file for the further upload.
-  # TODO(crbug.com/343242386): May dump to a file once the file name is defined.
   def dump(self) -> TestScriptMetrics:
     result = TestScriptMetrics()
     result.metrics.extend([m.dump() for m in self._metrics])
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index 936f467..f5591b6 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -1632,11 +1632,6 @@
     ]
   }
 
-  java_cpp_enum("context_menu_image_format_enum_javagen") {
-    sources =
-        [ "browser/android/context_menu/context_menu_native_delegate_impl.h" ]
-  }
-
   source_set("chrome_android_core") {
     sources = [
       "app/android/chrome_jni_onload.cc",
diff --git a/chrome/VERSION b/chrome/VERSION
index 31461bf..f86379c 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=128
 MINOR=0
-BUILD=6542
+BUILD=6543
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 7ce431d7..57141f9 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -229,6 +229,7 @@
       "//chrome/browser/ui/android/device_lock:java_resources",
       "//chrome/browser/ui/android/favicon:java_resources",
       "//chrome/browser/ui/android/google_bottom_bar:java_resources",
+      "//chrome/browser/ui/android/logo:java_resources",
       "//chrome/browser/ui/android/management:java_resources",
       "//chrome/browser/ui/android/omnibox:java_resources",
       "//chrome/browser/ui/android/quickactionsearchwidget:java_resources",
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java
index dab4f84..8952b336 100644
--- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java
+++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java
@@ -598,13 +598,7 @@
                     resources, StartSurfaceConfiguration.getLogoSizeForLogoPolish());
         }
 
-        if (mIsSurfacePolishEnabled) {
-            return LogoUtils.getLogoTotalHeightPolished(resources);
-        }
-
-        return getPixelSize(R.dimen.ntp_logo_height)
-                + getPixelSize(R.dimen.ntp_logo_margin_top)
-                + getPixelSize(R.dimen.ntp_logo_margin_bottom);
+        return LogoUtils.getLogoTotalHeight(resources);
     }
 
     private void initializeOffsetChangedListener() {
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java
index 71dc1f5..2d6d55f 100644
--- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java
+++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java
@@ -54,13 +54,11 @@
 import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
 import org.chromium.chrome.browser.feed.FeedActionDelegate;
 import org.chromium.chrome.browser.feed.FeedReliabilityLogger;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.lens.LensEntryPoint;
 import org.chromium.chrome.browser.lens.LensMetrics;
 import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
 import org.chromium.chrome.browser.lifecycle.PauseResumeWithNativeObserver;
 import org.chromium.chrome.browser.logo.LogoCoordinator;
-import org.chromium.chrome.browser.logo.LogoUtils;
 import org.chromium.chrome.browser.logo.LogoView;
 import org.chromium.chrome.browser.magic_stack.HomeModulesConfigManager;
 import org.chromium.chrome.browser.magic_stack.HomeModulesCoordinator;
@@ -146,7 +144,6 @@
     private final ActivityLifecycleDispatcher mActivityLifecycleDispatcher;
     private final TabCreatorManager mTabCreatorManager;
     private final boolean mUseMagicStack;
-    private final boolean mIsSurfacePolishEnabled;
     @Nullable private final ModuleDelegateCreator mModuleDelegateCreator;
     private boolean mShouldIgnoreTabSelecting;
 
@@ -216,8 +213,6 @@
             ObservableSupplier<Profile> profileSupplier) {
         mTabSwitcherModule = tabSwitcherModule;
         mController = mTabSwitcherModule != null ? mTabSwitcherModule.getController() : null;
-        mIsSurfacePolishEnabled =
-                isStartSurfaceEnabled && ChromeFeatureList.sSurfacePolish.isEnabled();
         mUseMagicStack = isStartSurfaceEnabled && StartSurfaceConfiguration.useMagicStack();
         // When a magic stack is enabled on Start surface, it doesn't need a controller to handle
         // its showing and hiding.
@@ -1034,8 +1029,6 @@
     }
 
     private void setLogoVisibility(boolean isVisible) {
-        if (!mIsSurfacePolishEnabled) return;
-
         if (isVisible && mLogoCoordinator == null) {
             mLogoCoordinator = initializeLogo();
             if (mIsNativeInitialized) mLogoCoordinator.initWithNative();
@@ -1180,15 +1173,6 @@
                         });
         mLogoContainerView.setVisibility(View.VISIBLE);
         LogoView logoView = mLogoContainerView.findViewById(R.id.search_provider_logo);
-        if (mIsSurfacePolishEnabled) {
-            LogoUtils.setLogoViewLayoutParams(
-                    logoView,
-                    mContext.getResources(),
-                    /* isTablet= */ false,
-                    StartSurfaceConfiguration.isLogoPolishEnabled(),
-                    StartSurfaceConfiguration.getLogoSizeForLogoPolish());
-        }
-
         mLogoCoordinator =
                 new LogoCoordinator(mContext, logoClickedCallback, logoView, true, null, this);
         return mLogoCoordinator;
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/ShowNtpAtStartupTest.java b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/ShowNtpAtStartupTest.java
index f3fce62..d656b117 100644
--- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/ShowNtpAtStartupTest.java
+++ b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/ShowNtpAtStartupTest.java
@@ -294,10 +294,9 @@
     public void testLogoSize() {
         mActivityTestRule.startMainActivityWithURL(UrlConstants.NTP_URL);
         Resources res = mActivityTestRule.getActivity().getResources();
-        int expectedLogoHeight = res.getDimensionPixelSize(R.dimen.ntp_logo_height_shrink);
-        int expectedTopMargin = LogoUtils.getTopMarginPolished(res);
-        int expectedBottomMargin =
-                res.getDimensionPixelSize(R.dimen.ntp_logo_vertical_bottom_margin_tablet);
+        int expectedLogoHeight = res.getDimensionPixelSize(R.dimen.ntp_logo_height);
+        int expectedTopMargin = res.getDimensionPixelSize(R.dimen.ntp_logo_margin_top);
+        int expectedBottomMargin = res.getDimensionPixelSize(R.dimen.ntp_logo_margin_bottom);
 
         // Verifies the logo size is decreased, and top bottom margins are updated.
         testLogoSizeImpl(expectedLogoHeight, expectedTopMargin, expectedBottomMargin);
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java
index b6cc08be..d833a9cd 100644
--- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java
+++ b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java
@@ -519,7 +519,7 @@
                     LogoUtils.getLogoTotalHeightForLogoPolish(
                             resources, StartSurfaceConfiguration.getLogoSizeForLogoPolish());
         } else {
-            logoInSurfaceHeight = LogoUtils.getLogoTotalHeightPolished(resources);
+            logoInSurfaceHeight = LogoUtils.getLogoTotalHeight(resources);
         }
         float toY =
                 -cta.getResources().getDimensionPixelSize(R.dimen.toolbar_height_no_shadow)
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_af.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_af.xtb
index dfe022c..7bcbb1b9 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_af.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_af.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Pers</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Vou <ph name="TITLE_OF_GROUP" />-oortjiegroep met <ph name="TABS_COUNT_ONE" /> oortjie uit.}other{Vou <ph name="TITLE_OF_GROUP" />-oortjiegroep met <ph name="TABS_COUNT_MANY" /> oortjies uit.}}</translation>
 <translation id="427987768447457592">Nuwe oortjiegroep</translation>
+<translation id="4371591986692297148">Onaktief</translation>
 <translation id="4460014764210899310">Ongroepeer</translation>
 <translation id="4648718555153979859">Jou oortjies word hier saamgegroepeer</translation>
 <translation id="4686942373615810936">Pas geskep</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_am.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_am.xtb
index 6f18a119..dee5618 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_am.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_am.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">ሐምራዊ</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> ትር ያለው የ<ph name="TITLE_OF_GROUP" /> ትር ቡድንን ይዘርጉ።}one{<ph name="TABS_COUNT_MANY" /> ትር ያለው የ<ph name="TITLE_OF_GROUP" /> ትር ቡድንን ይዘርጉ።}other{<ph name="TABS_COUNT_MANY" /> ትሮች ያሉት የ<ph name="TITLE_OF_GROUP" /> ትር ቡድንን ይዘርጉ።}}</translation>
 <translation id="427987768447457592">አዲስ የትር ቡድን</translation>
+<translation id="4371591986692297148">ያልነቃ</translation>
 <translation id="4460014764210899310">ነጥል</translation>
 <translation id="4648718555153979859">የእርስዎ ትሮች እዚህ አብረው ይቦደናሉ</translation>
 <translation id="4686942373615810936">አሁን የተፈጠረ</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ar.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ar.xtb
index fd6c652..4f3624a 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ar.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ar.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">أرجواني</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{توسيع المجموعة "<ph name="TITLE_OF_GROUP" />" التي تحتوي على علامة تبويب واحدة (<ph name="TABS_COUNT_ONE" />)}zero{توسيع المجموعة "<ph name="TITLE_OF_GROUP" />" التي تحتوي على <ph name="TABS_COUNT_MANY" /> علامة تبويب}two{توسيع المجموعة "<ph name="TITLE_OF_GROUP" />" التي تحتوي على علامتَي تبويب (<ph name="TABS_COUNT_MANY" />)}few{توسيع المجموعة "<ph name="TITLE_OF_GROUP" />" التي تحتوي على <ph name="TABS_COUNT_MANY" /> علامات تبويب}many{توسيع المجموعة "<ph name="TITLE_OF_GROUP" />" التي تحتوي على <ph name="TABS_COUNT_MANY" /> علامة تبويب}other{توسيع المجموعة "<ph name="TITLE_OF_GROUP" />" التي تحتوي على <ph name="TABS_COUNT_MANY" /> علامة تبويب}}</translation>
 <translation id="427987768447457592">مجموعة علامات تبويب جديدة</translation>
+<translation id="4371591986692297148">غير مفعّلة</translation>
 <translation id="4460014764210899310">إلغاء التجميع</translation>
 <translation id="4648718555153979859">يتم جمع علامات التبويب معًا هنا</translation>
 <translation id="4686942373615810936">تم إنشاء المجموعة للتو</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_as.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_as.xtb
index dd7a14d..ced503f 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_as.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_as.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">বেঙুনীয়া</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> টা টেবযুক্ত <ph name="TITLE_OF_GROUP" /> টেবৰ গোটটো বিস্তাৰ কৰক।}one{<ph name="TABS_COUNT_MANY" /> টা টেবযুক্ত <ph name="TITLE_OF_GROUP" /> টেবৰ গোটটো বিস্তাৰ কৰক।}other{<ph name="TABS_COUNT_MANY" /> টা টেবযুক্ত <ph name="TITLE_OF_GROUP" /> টেবৰ গোটটো বিস্তাৰ কৰক।}}</translation>
 <translation id="427987768447457592">নতুন টেবৰ গোট</translation>
+<translation id="4371591986692297148">নিষ্ক্ৰিয় হৈ আছে</translation>
 <translation id="4460014764210899310">গোট ভংগ কৰক</translation>
 <translation id="4648718555153979859">আপোনাৰ টেবসমূহ ইয়াত একগোট কৰা হৈছে</translation>
 <translation id="4686942373615810936">এইমাত্ৰ সৃষ্টি কৰা হৈছে</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_az.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_az.xtb
index 12c3aa86..3ae1a499 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_az.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_az.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Bənövşəyi</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> tab olan <ph name="TITLE_OF_GROUP" /> tab qrupunu genişləndirin.}other{<ph name="TABS_COUNT_MANY" /> tab olan <ph name="TITLE_OF_GROUP" /> tab qrupunu genişləndirin.}}</translation>
 <translation id="427987768447457592">Yeni tab qrupu</translation>
+<translation id="4371591986692297148">Fəaliyyətsiz</translation>
 <translation id="4460014764210899310">Qruplaşdırma olmasın</translation>
 <translation id="4648718555153979859">Tablar burada qruplaşdırılır</translation>
 <translation id="4686942373615810936">İndicə yaradıldı</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_be.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_be.xtb
index a4200eb..3938d32a 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_be.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_be.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Фіялетавы</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Разгарнуць групу ўкладак "<ph name="TITLE_OF_GROUP" />". У ёй <ph name="TABS_COUNT_ONE" /> укладка.}one{Разгарнуць групу ўкладак "<ph name="TITLE_OF_GROUP" />". У ёй <ph name="TABS_COUNT_MANY" /> укладка.}few{Разгарнуць групу ўкладак "<ph name="TITLE_OF_GROUP" />". У ёй <ph name="TABS_COUNT_MANY" /> укладкі.}many{Разгарнуць групу ўкладак "<ph name="TITLE_OF_GROUP" />". У ёй <ph name="TABS_COUNT_MANY" /> укладак.}other{Разгарнуць групу ўкладак "<ph name="TITLE_OF_GROUP" />". У ёй <ph name="TABS_COUNT_MANY" /> укладкі.}}</translation>
 <translation id="427987768447457592">Новая група ўкладак</translation>
+<translation id="4371591986692297148">неактыўная</translation>
 <translation id="4460014764210899310">Разгрупаваць</translation>
 <translation id="4648718555153979859">Укладкі згрупаваны тут</translation>
 <translation id="4686942373615810936">Створана толькі што</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bg.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bg.xtb
index 4fb4a60..adaa4230 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bg.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bg.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">лилаво</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Разгъване на групата раздели „<ph name="TITLE_OF_GROUP" />“ с <ph name="TABS_COUNT_ONE" /> раздел.}other{Разгъване на групата раздели „<ph name="TITLE_OF_GROUP" />“ с(ъс) <ph name="TABS_COUNT_MANY" /> раздела.}}</translation>
 <translation id="427987768447457592">Нова група раздели</translation>
+<translation id="4371591986692297148">Неактивно</translation>
 <translation id="4460014764210899310">Разгрупиране</translation>
 <translation id="4648718555153979859">Разделите ви са групирани заедно тук</translation>
 <translation id="4686942373615810936">Създадено току-що</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bn.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bn.xtb
index d3d91d2..e5ab427 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bn.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bn.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">বেগুনি</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TITLE_OF_GROUP" /> ট্যাব গ্রুপ বন্ধ করুন যেটিতে <ph name="TABS_COUNT_ONE" />টি ট্যাব আছে।}one{<ph name="TITLE_OF_GROUP" /> ট্যাব গ্রুপ বন্ধ করুন যেটিতে <ph name="TABS_COUNT_MANY" />টি ট্যাব আছে।}other{<ph name="TITLE_OF_GROUP" /> ট্যাব গ্রুপ বন্ধ করুন যেটিতে <ph name="TABS_COUNT_MANY" />টি ট্যাব আছে।}}</translation>
 <translation id="427987768447457592">নতুন ট্যাব গ্রুপ</translation>
+<translation id="4371591986692297148">চালু নেই</translation>
 <translation id="4460014764210899310">আলাদা করুন</translation>
 <translation id="4648718555153979859">আপনার ট্যাবগুলি এখানে একসাথে গ্রুপ করা আছে</translation>
 <translation id="4686942373615810936">এইমাত্র তৈরি করা হয়েছে</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bs.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bs.xtb
index 67d58ce..c4940ca 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bs.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_bs.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Ljubičasta</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Proširivanje grupe kartica <ph name="TITLE_OF_GROUP" /> s <ph name="TABS_COUNT_ONE" /> karticom.}one{Proširivanje grupe kartica <ph name="TITLE_OF_GROUP" /> sa <ph name="TABS_COUNT_MANY" /> karticom.}few{Proširivanje grupe kartica <ph name="TITLE_OF_GROUP" /> sa <ph name="TABS_COUNT_MANY" /> kartice.}other{Proširivanje grupe kartica <ph name="TITLE_OF_GROUP" /> sa <ph name="TABS_COUNT_MANY" /> kartica.}}</translation>
 <translation id="427987768447457592">Nova grupa kartica</translation>
+<translation id="4371591986692297148">Neaktivno</translation>
 <translation id="4460014764210899310">Razgrupiši</translation>
 <translation id="4648718555153979859">Vaše kartice su grupisane ovdje</translation>
 <translation id="4686942373615810936">Kreirano je upravo sada</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ca.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ca.xtb
index 5f3810a7..cc459f2 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ca.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ca.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Porpra</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Desplega el grup <ph name="TITLE_OF_GROUP" /> format per <ph name="TABS_COUNT_ONE" /> pestanya.}other{Desplega el grup <ph name="TITLE_OF_GROUP" /> format per <ph name="TABS_COUNT_MANY" /> pestanyes.}}</translation>
 <translation id="427987768447457592">Grup de pestanyes nou</translation>
+<translation id="4371591986692297148">inactiu</translation>
 <translation id="4460014764210899310">Desagrupa</translation>
 <translation id="4648718555153979859">Les teves pestanyes s'agrupen aquí</translation>
 <translation id="4686942373615810936">Creat ara mateix</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_cs.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_cs.xtb
index ac9ec5daf..f3b97bd 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_cs.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_cs.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Nachová</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Rozbalit skupinu karet <ph name="TITLE_OF_GROUP" /> s <ph name="TABS_COUNT_ONE" /> kartou.}few{Rozbalit skupinu karet <ph name="TITLE_OF_GROUP" /> se <ph name="TABS_COUNT_MANY" /> kartami.}many{Rozbalit skupinu karet <ph name="TITLE_OF_GROUP" /> s <ph name="TABS_COUNT_MANY" /> karty.}other{Rozbalit skupinu karet <ph name="TITLE_OF_GROUP" /> s <ph name="TABS_COUNT_MANY" /> kartami.}}</translation>
 <translation id="427987768447457592">Nová skupina karet</translation>
+<translation id="4371591986692297148">Neaktivní</translation>
 <translation id="4460014764210899310">Zrušit seskupení</translation>
 <translation id="4648718555153979859">Zde jsou seskupeny vaše karty</translation>
 <translation id="4686942373615810936">Vytvořeno právě teď</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_cy.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_cy.xtb
index 7958630..01c703b 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_cy.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_cy.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Porffor</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Ehangu'r grŵp tabiau <ph name="TITLE_OF_GROUP" /> sydd ag <ph name="TABS_COUNT_ONE" /> tab.}zero{Ehangu'r grŵp tabiau <ph name="TITLE_OF_GROUP" /> sydd â <ph name="TABS_COUNT_MANY" /> tab.}two{Ehangu'r grŵp tabiau <ph name="TITLE_OF_GROUP" /> sydd â <ph name="TABS_COUNT_MANY" /> dab.}few{Ehangu'r grŵp tabiau <ph name="TITLE_OF_GROUP" /> sydd â <ph name="TABS_COUNT_MANY" /> tab.}many{Ehangu'r grŵp tabiau <ph name="TITLE_OF_GROUP" /> sydd â <ph name="TABS_COUNT_MANY" /> tab.}other{Ehangu'r grŵp tabiau <ph name="TITLE_OF_GROUP" /> sydd â <ph name="TABS_COUNT_MANY" /> tab.}}</translation>
 <translation id="427987768447457592">Grŵp tabiau newydd</translation>
+<translation id="4371591986692297148">Anweithredol</translation>
 <translation id="4460014764210899310">Dadgrwpio</translation>
 <translation id="4648718555153979859">Mae'ch tabiau wedi'u grwpio gyda'i gilydd yma</translation>
 <translation id="4686942373615810936">Newydd ei greu</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_da.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_da.xtb
index 7f33e3a..2ab294b 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_da.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_da.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Lilla</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Udvid fanegruppen <ph name="TITLE_OF_GROUP" /> med <ph name="TABS_COUNT_ONE" /> fane.}one{Udvid fanegruppen <ph name="TITLE_OF_GROUP" /> med <ph name="TABS_COUNT_MANY" /> fane.}other{Udvid fanegruppen <ph name="TITLE_OF_GROUP" /> med <ph name="TABS_COUNT_MANY" /> faner.}}</translation>
 <translation id="427987768447457592">Ny fanegruppe</translation>
+<translation id="4371591986692297148">Inaktiv</translation>
 <translation id="4460014764210899310">Ophæv gruppering</translation>
 <translation id="4648718555153979859">Dine faner er grupperet sammen her</translation>
 <translation id="4686942373615810936">Oprettet lige nu</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_de.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_de.xtb
index 1ebde71..47e8115 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_de.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_de.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Violett</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Tabgruppe „<ph name="TITLE_OF_GROUP" />“ mit <ph name="TABS_COUNT_ONE" /> Tab maximieren.}other{Tabgruppe „<ph name="TITLE_OF_GROUP" />“ mit <ph name="TABS_COUNT_MANY" /> Tabs maximieren.}}</translation>
 <translation id="427987768447457592">Neue Tabgruppe</translation>
+<translation id="4371591986692297148">Inaktiv</translation>
 <translation id="4460014764210899310">Gruppierung aufheben</translation>
 <translation id="4648718555153979859">Deine Tabs werden hier in Gruppen zusammengefasst</translation>
 <translation id="4686942373615810936">Gerade eben erstellt</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_el.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_el.xtb
index 51c703bc..0cecd7e 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_el.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_el.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Μοβ</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Ανάπτυξη της ομάδας καρτελών <ph name="TITLE_OF_GROUP" /> με <ph name="TABS_COUNT_ONE" /> καρτέλα.}other{Ανάπτυξη της ομάδας καρτελών <ph name="TITLE_OF_GROUP" /> με <ph name="TABS_COUNT_MANY" /> καρτέλες.}}</translation>
 <translation id="427987768447457592">Νέα ομάδα καρτελών</translation>
+<translation id="4371591986692297148">Ανενεργή</translation>
 <translation id="4460014764210899310">Κατάργηση ομαδοποίησης</translation>
 <translation id="4648718555153979859">Οι καρτέλες σας ομαδοποιούνται εδώ</translation>
 <translation id="4686942373615810936">Δημιουργήθηκε μόλις τώρα</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_en-GB.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_en-GB.xtb
index e3007d56..1669769 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_en-GB.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_en-GB.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Purple</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Expand <ph name="TITLE_OF_GROUP" /> tab group with <ph name="TABS_COUNT_ONE" /> tab.}other{Expand <ph name="TITLE_OF_GROUP" /> tab group with <ph name="TABS_COUNT_MANY" /> tabs.}}</translation>
 <translation id="427987768447457592">New tab group</translation>
+<translation id="4371591986692297148">Inactive</translation>
 <translation id="4460014764210899310">Ungroup</translation>
 <translation id="4648718555153979859">Your tabs are grouped together here</translation>
 <translation id="4686942373615810936">Created just now</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_es-419.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_es-419.xtb
index 4df5d91..629afd4d 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_es-419.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_es-419.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Púrpura</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Expandir el grupo de pestañas <ph name="TITLE_OF_GROUP" /> con <ph name="TABS_COUNT_ONE" /> pestaña.}other{Expandir el grupo de pestañas <ph name="TITLE_OF_GROUP" /> con <ph name="TABS_COUNT_MANY" /> pestañas.}}</translation>
 <translation id="427987768447457592">Nuevo grupo de pestañas</translation>
+<translation id="4371591986692297148">Inactivo</translation>
 <translation id="4460014764210899310">Desagrupar</translation>
 <translation id="4648718555153979859">Tus pestañas se agrupan aquí</translation>
 <translation id="4686942373615810936">Se creó recién</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_es.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_es.xtb
index ca3a2c7..8e9a1922 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_es.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_es.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Morado</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Desplegar el grupo de pestañas <ph name="TITLE_OF_GROUP" /> con <ph name="TABS_COUNT_ONE" /> pestaña.}other{Desplegar el grupo de pestañas <ph name="TITLE_OF_GROUP" /> con <ph name="TABS_COUNT_MANY" /> pestañas.}}</translation>
 <translation id="427987768447457592">Nuevo grupo de pestañas</translation>
+<translation id="4371591986692297148">Inactivo</translation>
 <translation id="4460014764210899310">Sin agrupar</translation>
 <translation id="4648718555153979859">Tus pestañas se agrupan aquí</translation>
 <translation id="4686942373615810936">Creado ahora mismo</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_et.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_et.xtb
index 5b4b55a6..7749a59 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_et.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_et.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Lilla</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Laienda <ph name="TABS_COUNT_ONE" /> vahelehega vahelehegrupp <ph name="TITLE_OF_GROUP" />.}other{Laienda <ph name="TABS_COUNT_MANY" /> vahelehega vahelehegrupp <ph name="TITLE_OF_GROUP" />.}}</translation>
 <translation id="427987768447457592">Uus vahelehegrupp</translation>
+<translation id="4371591986692297148">Mitteaktiivne</translation>
 <translation id="4460014764210899310">Tühista grupeerimine</translation>
 <translation id="4648718555153979859">Teie vahelehed on siin grupeeritud</translation>
 <translation id="4686942373615810936">Loodud just praegu</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_eu.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_eu.xtb
index 1fc4c03..0302197 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_eu.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_eu.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Morea</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Zabaldu fitxa <ph name="TABS_COUNT_ONE" /> duen <ph name="TITLE_OF_GROUP" /> fitxa taldea.}other{Zabaldu <ph name="TABS_COUNT_MANY" /> fitxa dituen <ph name="TITLE_OF_GROUP" /> fitxa taldea.}}</translation>
 <translation id="427987768447457592">Fitxa talde berria</translation>
+<translation id="4371591986692297148">Inaktibo</translation>
 <translation id="4460014764210899310">Desegin taldea</translation>
 <translation id="4648718555153979859">Fitxak taldekatuta daude hemen</translation>
 <translation id="4686942373615810936">Oraintxe bertan sortua</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fa.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fa.xtb
index 360390e..5af69ff 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fa.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fa.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">بنفش</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{ازهم بازکردن گروه برگه <ph name="TITLE_OF_GROUP" /> با <ph name="TABS_COUNT_ONE" /> برگه.}one{ازهم بازکردن گروه برگه <ph name="TITLE_OF_GROUP" /> با <ph name="TABS_COUNT_MANY" /> برگه.}other{ازهم بازکردن گروه برگه <ph name="TITLE_OF_GROUP" /> با <ph name="TABS_COUNT_MANY" /> برگه.}}</translation>
 <translation id="427987768447457592">گروه برگه جدید</translation>
+<translation id="4371591986692297148">غیرفعال</translation>
 <translation id="4460014764210899310">لغو گروه‌بندی</translation>
 <translation id="4648718555153979859">برگه‌هایتان اینجا باهم گروه‌بندی می‌شوند</translation>
 <translation id="4686942373615810936">همین الآن ایجاد شد</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fi.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fi.xtb
index 1e774cd4..f46b222 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fi.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fi.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Violetti</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Laajenna välilehtiryhmä <ph name="TITLE_OF_GROUP" />, jossa on <ph name="TABS_COUNT_ONE" /> välilehti.}other{Laajenna välilehtiryhmä <ph name="TITLE_OF_GROUP" />, jossa on <ph name="TABS_COUNT_MANY" /> välilehteä.}}</translation>
 <translation id="427987768447457592">Uusi välilehtiryhmä</translation>
+<translation id="4371591986692297148">Ei aktiivinen</translation>
 <translation id="4460014764210899310">Poista ryhmittely</translation>
 <translation id="4648718555153979859">Välilehtesi on koottu tänne</translation>
 <translation id="4686942373615810936">Luotiin juuri nyt</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fil.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fil.xtb
index 03a640ed..ce646c4 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fil.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fil.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Lila</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{I-expand ang grupo ng tab na <ph name="TITLE_OF_GROUP" /> na may <ph name="TABS_COUNT_ONE" /> tab.}one{I-expand ang grupo ng tab na <ph name="TITLE_OF_GROUP" /> na may <ph name="TABS_COUNT_MANY" /> tab.}other{I-expand ang grupo ng tab na <ph name="TITLE_OF_GROUP" /> na may <ph name="TABS_COUNT_MANY" /> na tab.}}</translation>
 <translation id="427987768447457592">Bagong grupo ng tab</translation>
+<translation id="4371591986692297148">Hindi Aktibo</translation>
 <translation id="4460014764210899310">I-ungroup</translation>
 <translation id="4648718555153979859">Magkakasama sa pangkat ang iyong mga tab dito</translation>
 <translation id="4686942373615810936">Kakagawa lang</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fr-CA.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fr-CA.xtb
index fd4bf14..459d79c 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fr-CA.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fr-CA.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Mauve</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Développer le groupe d'onglets <ph name="TITLE_OF_GROUP" /> qui contient <ph name="TABS_COUNT_ONE" /> onglet.}one{Développer le groupe d'onglets <ph name="TITLE_OF_GROUP" /> qui contient <ph name="TABS_COUNT_MANY" /> onglet.}other{Développer le groupe d'onglets <ph name="TITLE_OF_GROUP" /> qui contient <ph name="TABS_COUNT_MANY" /> onglets.}}</translation>
 <translation id="427987768447457592">Nouveau groupe d'onglets</translation>
+<translation id="4371591986692297148">Inactif</translation>
 <translation id="4460014764210899310">Dégrouper</translation>
 <translation id="4648718555153979859">Vos onglets sont regroupés ici</translation>
 <translation id="4686942373615810936">Créé à l'instant</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fr.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fr.xtb
index 682cdb75..1bd178e 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fr.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_fr.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Violet</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Développer le groupe d'onglets <ph name="TITLE_OF_GROUP" /> qui contient <ph name="TABS_COUNT_ONE" /> onglet.}one{Développer le groupe d'onglets <ph name="TITLE_OF_GROUP" /> qui contient <ph name="TABS_COUNT_MANY" /> onglet.}other{Développer le groupe d'onglets <ph name="TITLE_OF_GROUP" /> qui contient <ph name="TABS_COUNT_MANY" /> onglets.}}</translation>
 <translation id="427987768447457592">Nouveau groupe d'onglets</translation>
+<translation id="4371591986692297148">Inactive</translation>
 <translation id="4460014764210899310">Dégrouper</translation>
 <translation id="4648718555153979859">Vos onglets sont regroupés ici</translation>
 <translation id="4686942373615810936">Créé à l'instant</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_gl.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_gl.xtb
index 2cd8b82..58ea6ea 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_gl.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_gl.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Púrpura</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Despregar o grupo de pestanas <ph name="TITLE_OF_GROUP" /> con <ph name="TABS_COUNT_ONE" /> pestana.}other{Despregar o grupo de pestanas <ph name="TITLE_OF_GROUP" /> con <ph name="TABS_COUNT_MANY" /> pestanas.}}</translation>
 <translation id="427987768447457592">Novo grupo de pestanas</translation>
+<translation id="4371591986692297148">Inactivo</translation>
 <translation id="4460014764210899310">Desagrupar</translation>
 <translation id="4648718555153979859">As túas pestanas agrúpanse aquí</translation>
 <translation id="4686942373615810936">Creouse agora mesmo</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_gu.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_gu.xtb
index 6940a03..62fe5b3 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_gu.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_gu.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">જાંબલી</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> ટૅબ ધરાવતા <ph name="TITLE_OF_GROUP" /> ટૅબ ગ્રૂપને મોટું કરો.}one{<ph name="TABS_COUNT_MANY" /> ટૅબ ધરાવતા <ph name="TITLE_OF_GROUP" /> ટૅબ ગ્રૂપને મોટું કરો.}other{<ph name="TABS_COUNT_MANY" /> ટૅબ ધરાવતા <ph name="TITLE_OF_GROUP" /> ટૅબ ગ્રૂપને મોટું કરો.}}</translation>
 <translation id="427987768447457592">ટૅબનું નવું ગ્રૂપ</translation>
+<translation id="4371591986692297148">નિષ્ક્રિય</translation>
 <translation id="4460014764210899310">અલગ થયેલું ગ્રૂપ</translation>
 <translation id="4648718555153979859">તમારા ટૅબ અહીં એકસાથે ગ્રૂપ કરવામાં આવ્યા છે</translation>
 <translation id="4686942373615810936">હમણાં જ બનાવ્યું</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hi.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hi.xtb
index b4ece86..6405d3ff 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hi.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hi.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">बैंगनी</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> टैब वाले टैब ग्रुप को बड़ा करें. इसका नाम <ph name="TITLE_OF_GROUP" /> है.}one{<ph name="TABS_COUNT_MANY" /> टैब वाले टैब ग्रुप को बड़ा करें. इसका नाम <ph name="TITLE_OF_GROUP" /> है.}other{<ph name="TABS_COUNT_MANY" /> टैब वाले टैब ग्रुप को बड़ा करें. इसका नाम <ph name="TITLE_OF_GROUP" /> है.}}</translation>
 <translation id="427987768447457592">नया टैब ग्रुप</translation>
+<translation id="4371591986692297148">चालू नहीं है</translation>
 <translation id="4460014764210899310">ग्रुप से अलग करें</translation>
 <translation id="4648718555153979859">यहां पर आपके टैब एक ग्रुप में रखे जाते हैं</translation>
 <translation id="4686942373615810936">अभी-अभी बनाया गया</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hr.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hr.xtb
index e3ce049..ccef50e7 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hr.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hr.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Ljubičasto</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Proširite grupu kartica <ph name="TITLE_OF_GROUP" /> koja sadrži <ph name="TABS_COUNT_ONE" /> karticu.}one{Proširite grupu kartica <ph name="TITLE_OF_GROUP" /> koja sadrži <ph name="TABS_COUNT_MANY" /> karticu.}few{Proširite grupu kartica <ph name="TITLE_OF_GROUP" /> koja sadrži <ph name="TABS_COUNT_MANY" /> kartice.}other{Proširite grupu kartica <ph name="TITLE_OF_GROUP" /> koja sadrži <ph name="TABS_COUNT_MANY" /> kartica.}}</translation>
 <translation id="427987768447457592">Nova grupa kartica</translation>
+<translation id="4371591986692297148">neaktivan</translation>
 <translation id="4460014764210899310">Pojedinačno</translation>
 <translation id="4648718555153979859">Ovdje su grupirane vaše kartice</translation>
 <translation id="4686942373615810936">Upravo izrađeno</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hu.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hu.xtb
index 14e84ab4..b25cdca8 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hu.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hu.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Lila</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{A következő, <ph name="TABS_COUNT_ONE" /> lapot tartalmazó lapcsoport kibontása: <ph name="TITLE_OF_GROUP" />.}other{A következő, <ph name="TABS_COUNT_MANY" /> lapot tartalmazó lapcsoport kibontása: <ph name="TITLE_OF_GROUP" />.}}</translation>
 <translation id="427987768447457592">Új lapcsoport</translation>
+<translation id="4371591986692297148">Inaktív</translation>
 <translation id="4460014764210899310">Csoportosítás megszüntetése</translation>
 <translation id="4648718555153979859">A lapok itt vannak csoportosítva</translation>
 <translation id="4686942373615810936">Épp most létrehozva</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hy.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hy.xtb
index 57554421..fa75a67 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hy.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_hy.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Մանուշակագույն</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Ծավալել <ph name="TABS_COUNT_ONE" /> ներդիրից բաղկացած «<ph name="TITLE_OF_GROUP" />» խումբը։}one{Ծավալել <ph name="TABS_COUNT_MANY" /> ներդիրից բաղկացած «<ph name="TITLE_OF_GROUP" />» խումբը։}other{Ծավալել <ph name="TABS_COUNT_MANY" /> ներդիրից բաղկացած «<ph name="TITLE_OF_GROUP" />» խումբը։}}</translation>
 <translation id="427987768447457592">Ներդիրների նոր խումբ</translation>
+<translation id="4371591986692297148">Ակտիվ չէ</translation>
 <translation id="4460014764210899310">Ապախմբավորել</translation>
 <translation id="4648718555153979859">Ձեր ներդիրները խմբավորվում են այստեղ</translation>
 <translation id="4686942373615810936">Ստեղծվել է քիչ առաջ</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_id.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_id.xtb
index fa2ff370..45e92d8 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_id.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_id.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Ungu</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Luaskan grup tab <ph name="TITLE_OF_GROUP" /> yang berisi <ph name="TABS_COUNT_ONE" /> tab.}other{Luaskan grup tab <ph name="TITLE_OF_GROUP" /> yang berisi <ph name="TABS_COUNT_MANY" /> tab.}}</translation>
 <translation id="427987768447457592">Grup tab baru</translation>
+<translation id="4371591986692297148">Tidak aktif</translation>
 <translation id="4460014764210899310">Pisahkan</translation>
 <translation id="4648718555153979859">Tab Anda dikelompokkan menjadi satu di sini</translation>
 <translation id="4686942373615810936">Baru saja dibuat</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_is.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_is.xtb
index 2c0e08f5..3877a4e 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_is.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_is.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Purpurarauður</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Stækka <ph name="TITLE_OF_GROUP" />-flipahóp með <ph name="TABS_COUNT_ONE" /> flipa.}one{Stækka <ph name="TITLE_OF_GROUP" /> -flipahóp með <ph name="TABS_COUNT_MANY" /> flipa.}other{Stækka <ph name="TITLE_OF_GROUP" /> -flipahóp með <ph name="TABS_COUNT_MANY" /> flipum.}}</translation>
 <translation id="427987768447457592">Nýr flipahópur</translation>
+<translation id="4371591986692297148">Óvirkt</translation>
 <translation id="4460014764210899310">Sundra hópi</translation>
 <translation id="4648718555153979859">Fliparnir þínir eru flokkaðir saman hér</translation>
 <translation id="4686942373615810936">Búinn til rétt í þessu</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_it.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_it.xtb
index 7a96a4d..c28028f 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_it.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_it.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Viola</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Espandi il gruppo di schede <ph name="TITLE_OF_GROUP" /> con <ph name="TABS_COUNT_ONE" /> scheda.}other{Espandi il gruppo di schede <ph name="TITLE_OF_GROUP" /> con <ph name="TABS_COUNT_MANY" /> schede.}}</translation>
 <translation id="427987768447457592">Nuovo gruppo di schede</translation>
+<translation id="4371591986692297148">non attivo</translation>
 <translation id="4460014764210899310">Separa</translation>
 <translation id="4648718555153979859">Le schede sono raggruppate qui</translation>
 <translation id="4686942373615810936">Creato un attimo fa</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_iw.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_iw.xtb
index 0da4c23..5106f88b 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_iw.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_iw.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">סגול</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{הרחבה של קבוצת הכרטיסיות ’<ph name="TITLE_OF_GROUP" />‘ שמכילה כרטיסייה אחת (<ph name="TABS_COUNT_ONE" />).}one{הרחבה של קבוצת הכרטיסיות ’<ph name="TITLE_OF_GROUP" />‘ שמכילה <ph name="TABS_COUNT_MANY" /> כרטיסיות.}two{הרחבה של קבוצת הכרטיסיות ’<ph name="TITLE_OF_GROUP" />‘ שמכילה <ph name="TABS_COUNT_MANY" /> כרטיסיות.}other{הרחבה של קבוצת הכרטיסיות ’<ph name="TITLE_OF_GROUP" />‘ שמכילה <ph name="TABS_COUNT_MANY" /> כרטיסיות.}}</translation>
 <translation id="427987768447457592">קבוצת כרטיסיות חדשה</translation>
+<translation id="4371591986692297148">לא פעיל</translation>
 <translation id="4460014764210899310">פיזור הקבוצה</translation>
 <translation id="4648718555153979859">הכרטיסיות שלך מסודרות כאן בקבוצה</translation>
 <translation id="4686942373615810936">נוצרה עכשיו</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ja.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ja.xtb
index 7c51584..e7585a80 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ja.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ja.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">パープル</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TITLE_OF_GROUP" /> タブグループの <ph name="TABS_COUNT_ONE" /> 個のタブを展開します。}other{<ph name="TITLE_OF_GROUP" /> タブグループの <ph name="TABS_COUNT_MANY" /> 個のタブを展開します。}}</translation>
 <translation id="427987768447457592">新しいタブグループ</translation>
+<translation id="4371591986692297148">無効</translation>
 <translation id="4460014764210899310">グループを解除</translation>
 <translation id="4648718555153979859">タブはここにグループ化されます</translation>
 <translation id="4686942373615810936">作成: たった今</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ka.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ka.xtb
index 02c5f37..5fbf0696 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ka.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ka.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">მეწამული</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{ჩანართების <ph name="TABS_COUNT_ONE" />-ჩანართიანი ჯგუფის „<ph name="TITLE_OF_GROUP" />“ გაფართოება.}other{ჩანართების <ph name="TABS_COUNT_MANY" />-ჩანართიანი ჯგუფის „<ph name="TITLE_OF_GROUP" />“ გაფართოება.}}</translation>
 <translation id="427987768447457592">ჩანართების ახალი ჯგუფი</translation>
+<translation id="4371591986692297148">არააქტიური</translation>
 <translation id="4460014764210899310">დაჯგუფების გაუქმება</translation>
 <translation id="4648718555153979859">თქვენი ჩანართები აქ დაჯგუფებულია</translation>
 <translation id="4686942373615810936">შეიქმნა ახლახან</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_kk.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_kk.xtb
index 4282e02..3ca02ae 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_kk.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_kk.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Күлгін</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> қойындысы бар "<ph name="TITLE_OF_GROUP" />" қойындылар тобын жаю.}other{<ph name="TABS_COUNT_MANY" /> қойындысы бар "<ph name="TITLE_OF_GROUP" />" қойындылар тобын жаю.}}</translation>
 <translation id="427987768447457592">Жаңа қойындылар тобы</translation>
+<translation id="4371591986692297148">Өшірілген</translation>
 <translation id="4460014764210899310">Топты тарату</translation>
 <translation id="4648718555153979859">Қойындылар осы жерге топтастырылады.</translation>
 <translation id="4686942373615810936">Жаңа ғана жасалды.</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_km.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_km.xtb
index 3cf1fd5..b0b5b4d 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_km.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_km.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">ស្វាយ</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{ពង្រីក​ក្រុមផ្ទាំង <ph name="TITLE_OF_GROUP" /> ដែលមាន <ph name="TABS_COUNT_ONE" /> ផ្ទាំង។}other{ពង្រីក​ក្រុមផ្ទាំង <ph name="TITLE_OF_GROUP" /> ដែលមាន <ph name="TABS_COUNT_MANY" /> ផ្ទាំង។}}</translation>
 <translation id="427987768447457592">ក្រុមផ្ទាំងថ្មី</translation>
+<translation id="4371591986692297148">អសកម្ម​</translation>
 <translation id="4460014764210899310">បំបែក​ក្រុម</translation>
 <translation id="4648718555153979859">ផ្ទាំងរបស់អ្នកត្រូវ​បានដាក់ជាក្រុម​រួមគ្នានៅទីនេះ</translation>
 <translation id="4686942373615810936">ទើប​បាន​បង្កើត​អម្បាញ់​មិញ</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_kn.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_kn.xtb
index 9b9d77a4..7ae6c95 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_kn.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_kn.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">ನೇರಳೆ</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> ಟ್ಯಾಬ್ ಜೊತೆಗೆ <ph name="TITLE_OF_GROUP" /> ಟ್ಯಾಬ್ ಗುಂಪನ್ನು ವಿಸ್ತೃತಗೊಳಿಸಿ.}one{<ph name="TABS_COUNT_MANY" /> ಟ್ಯಾಬ್‌ಗಳ ಜೊತೆಗೆ <ph name="TITLE_OF_GROUP" /> ಟ್ಯಾಬ್ ಗುಂಪನ್ನು ವಿಸ್ತೃತಗೊಳಿಸಿ.}other{<ph name="TABS_COUNT_MANY" /> ಟ್ಯಾಬ್‌ಗಳ ಜೊತೆಗೆ <ph name="TITLE_OF_GROUP" /> ಟ್ಯಾಬ್ ಗುಂಪನ್ನು ವಿಸ್ತೃತಗೊಳಿಸಿ.}}</translation>
 <translation id="427987768447457592">ಹೊಸ ಟ್ಯಾಬ್ ಗುಂಪು</translation>
+<translation id="4371591986692297148">ನಿಷ್ಕ್ರಿಯವಾಗಿದೆ</translation>
 <translation id="4460014764210899310">ಗುಂಪು ವಿಂಗಡಿಸಿ</translation>
 <translation id="4648718555153979859">ಟ್ಯಾಬ್‌ಗಳನ್ನು ಇಲ್ಲಿ ಒಟ್ಟಿಗೆ ಗುಂಪುಗೂಡಿಸಲಾಗಿದೆ</translation>
 <translation id="4686942373615810936">ಇದೀಗ ತಾನೇ ರಚಿಸಲಾಗಿದೆ</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ko.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ko.xtb
index 8e1f804..a12b5808 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ko.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ko.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">보라색</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{탭 <ph name="TABS_COUNT_ONE" />개가 포함된 <ph name="TITLE_OF_GROUP" /> 탭 그룹을 펼칩니다.}other{탭 <ph name="TABS_COUNT_MANY" />개가 포함된 <ph name="TITLE_OF_GROUP" /> 탭 그룹을 펼칩니다.}}</translation>
 <translation id="427987768447457592">새 탭 그룹</translation>
+<translation id="4371591986692297148">비활성</translation>
 <translation id="4460014764210899310">그룹 해제</translation>
 <translation id="4648718555153979859">탭이 여기에서 그룹화됩니다.</translation>
 <translation id="4686942373615810936">방금 생성됨</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ky.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ky.xtb
index aef1e97..15d6cf40 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ky.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ky.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Кызгылт көгүш</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> өтмөктөн турган <ph name="TITLE_OF_GROUP" /> өтмөктөр тобун жайып көрсөтүү.}other{<ph name="TABS_COUNT_MANY" /> өтмөктөн турган <ph name="TITLE_OF_GROUP" /> өтмөктөр тобун жайып көрсөтүү.}}</translation>
 <translation id="427987768447457592">Жаңы өтмөктөр тобу</translation>
+<translation id="4371591986692297148">Жигерсиз</translation>
 <translation id="4460014764210899310">Топтолбосун</translation>
 <translation id="4648718555153979859">Өтмөктөрүңүз бул жерге топтолот</translation>
 <translation id="4686942373615810936">Азыр түзүлдү</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lo.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lo.xtb
index 4a41812a..0b1a8750b 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lo.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lo.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">ສີມ່ວງ</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{ຂະຫຍາຍກຸ່ມແຖບ <ph name="TITLE_OF_GROUP" /> ທີ່ມີ <ph name="TABS_COUNT_ONE" /> ແຖບ.}other{ຂະຫຍາຍກຸ່ມແຖບ <ph name="TITLE_OF_GROUP" /> ທີ່ມີ <ph name="TABS_COUNT_MANY" /> ແຖບ.}}</translation>
 <translation id="427987768447457592">ກຸ່ມແຖບໃໝ່</translation>
+<translation id="4371591986692297148">ບໍ່ໄດ້ນຳໃຊ້</translation>
 <translation id="4460014764210899310">ຍົກເລີກການຈັດກຸ່ມ</translation>
 <translation id="4648718555153979859">ແຖບຂອງທ່ານຖືກຈັດເປັນກຸ່ມຮວມກັນຢູ່ບ່ອນນີ້</translation>
 <translation id="4686942373615810936">ຫາກໍສ້າງຕອນນີ້</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lt.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lt.xtb
index 54cb6c4f..d34e6c3e 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lt.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lt.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Violetinė</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Išskleisti skirtukų grupę „<ph name="TITLE_OF_GROUP" />“, kurioje yra <ph name="TABS_COUNT_ONE" /> skirtukas.}one{Išskleisti skirtukų grupę „<ph name="TITLE_OF_GROUP" />“, kurioje yra <ph name="TABS_COUNT_MANY" /> skirtukas.}few{Išskleisti skirtukų grupę „<ph name="TITLE_OF_GROUP" />“, kurioje yra <ph name="TABS_COUNT_MANY" /> skirtukai.}many{Išskleisti skirtukų grupę „<ph name="TITLE_OF_GROUP" />“, kurioje yra <ph name="TABS_COUNT_MANY" /> skirtuko.}other{Išskleisti skirtukų grupę „<ph name="TITLE_OF_GROUP" />“, kurioje yra <ph name="TABS_COUNT_MANY" /> skirtukų.}}</translation>
 <translation id="427987768447457592">Nauja skirtukų grupė</translation>
+<translation id="4371591986692297148">Neaktyvus</translation>
 <translation id="4460014764210899310">Išgrupuoti</translation>
 <translation id="4648718555153979859">Čia skirtukai suskirstyti į grupes</translation>
 <translation id="4686942373615810936">Ką tik sukurta</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lv.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lv.xtb
index a10ebb6..983da07 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lv.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_lv.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Violets</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Izvērst ciļņu grupu “<ph name="TITLE_OF_GROUP" />”, kurā ir <ph name="TABS_COUNT_ONE" /> cilne.}zero{Izvērst ciļņu grupu “<ph name="TITLE_OF_GROUP" />”, kurā ir <ph name="TABS_COUNT_MANY" /> cilnes.}one{Izvērst ciļņu grupu “<ph name="TITLE_OF_GROUP" />”, kurā ir <ph name="TABS_COUNT_MANY" /> cilne.}other{Izvērst ciļņu grupu “<ph name="TITLE_OF_GROUP" />”, kurā ir <ph name="TABS_COUNT_MANY" /> cilnes.}}</translation>
 <translation id="427987768447457592">Jauna ciļņu grupa</translation>
+<translation id="4371591986692297148">neaktīva</translation>
 <translation id="4460014764210899310">Atcelt grupēšanu</translation>
 <translation id="4648718555153979859">Jūsu cilnes šeit ir grupētas kopā</translation>
 <translation id="4686942373615810936">Izveidota tikko</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mk.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mk.xtb
index 4a91a89..312cbb7 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mk.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mk.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Пурпурна</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Прошири ја групата картички „<ph name="TITLE_OF_GROUP" />“ со <ph name="TABS_COUNT_ONE" /> картичка.}one{Прошири ја групата картички „<ph name="TITLE_OF_GROUP" />“ со <ph name="TABS_COUNT_MANY" /> картичка.}other{Прошири ја групата картички „<ph name="TITLE_OF_GROUP" />“ со <ph name="TABS_COUNT_MANY" /> картички.}}</translation>
 <translation id="427987768447457592">Нова група картички</translation>
+<translation id="4371591986692297148">Неактивно</translation>
 <translation id="4460014764210899310">Одгрупирајте</translation>
 <translation id="4648718555153979859">Картичките тука се групирани заедно</translation>
 <translation id="4686942373615810936">Создадено пред малку</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ml.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ml.xtb
index bfd934a..101c169 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ml.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ml.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">പര്‍പ്പിള്‍</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> ടാബുള്ള <ph name="TITLE_OF_GROUP" /> ടാബ് ഗ്രൂപ്പ് വികസിപ്പിക്കുക.}other{<ph name="TABS_COUNT_MANY" /> ടാബുകളുള്ള <ph name="TITLE_OF_GROUP" /> ടാബ് ഗ്രൂപ്പ് വികസിപ്പിക്കുക.}}</translation>
 <translation id="427987768447457592">പുതിയ ടാബ് ഗ്രൂപ്പ്</translation>
+<translation id="4371591986692297148">നിഷ്‌ക്രിയം</translation>
 <translation id="4460014764210899310">ഗ്രൂപ്പ് അല്ലാതാക്കി മാറ്റുക</translation>
 <translation id="4648718555153979859">നിങ്ങളുടെ ടാബുകൾ ഇവിടെ ഒന്നിച്ച് ഗ്രൂപ്പ് ചെയ്യപ്പെടും</translation>
 <translation id="4686942373615810936">ഇപ്പോൾ സൃഷ്‌ടിച്ചത്</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mn.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mn.xtb
index 54322e8..4ca1b9f2 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mn.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mn.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Нил ягаан</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> таб бүхий <ph name="TITLE_OF_GROUP" />-н бүлгийг дэлгэх.}other{<ph name="TABS_COUNT_MANY" /> таб бүхий <ph name="TITLE_OF_GROUP" />-н бүлгийг дэлгэх.}}</translation>
 <translation id="427987768447457592">Шинэ табын бүлэг</translation>
+<translation id="4371591986692297148">Идэвхгүй</translation>
 <translation id="4460014764210899310">Бүлгийг болих</translation>
 <translation id="4648718555153979859">Таны табуудыг энд бүлэглэсэн болно</translation>
 <translation id="4686942373615810936">Дөнгөж сая үүсгэсэн</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mr.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mr.xtb
index 8ac0720..793b858 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mr.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_mr.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">जांभळा</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> टॅब असलेल्या <ph name="TITLE_OF_GROUP" /> या टॅब गटाचा विस्तार करा.}other{<ph name="TABS_COUNT_MANY" /> टॅब असलेल्या <ph name="TITLE_OF_GROUP" /> या टॅब गटाचा विस्तार करा.}}</translation>
 <translation id="427987768447457592">नवीन टॅब गट</translation>
+<translation id="4371591986692297148">इनॅक्टिव्ह आहे</translation>
 <translation id="4460014764210899310">गटामधून काढून टाका</translation>
 <translation id="4648718555153979859">तुमचे टॅब येथे एकत्रित केले आहेत</translation>
 <translation id="4686942373615810936">आता तयार केला आहे</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ms.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ms.xtb
index 790f488..69ce868 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ms.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ms.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Ungu</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Kembangkan kumpulan tab <ph name="TITLE_OF_GROUP" /> dengan <ph name="TABS_COUNT_ONE" /> tab.}other{Kembangkan kumpulan tab <ph name="TITLE_OF_GROUP" /> dengan <ph name="TABS_COUNT_MANY" /> tab.}}</translation>
 <translation id="427987768447457592">Kumpulan tab baharu</translation>
+<translation id="4371591986692297148">Tidak aktif</translation>
 <translation id="4460014764210899310">Nyahkumpulan</translation>
 <translation id="4648718555153979859">Tab anda dikumpulkan bersama di sini</translation>
 <translation id="4686942373615810936">Dibuat sebentar tadi</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_my.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_my.xtb
index 3b6eed51d6..429cbb8c 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_my.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_my.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">ခရမ်း</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{တဘ် <ph name="TABS_COUNT_ONE" /> ခုပါသော <ph name="TITLE_OF_GROUP" /> တဘ်အုပ်စုကို ပိုပြပါ။}other{တဘ် <ph name="TABS_COUNT_MANY" /> ခုပါသော <ph name="TITLE_OF_GROUP" /> တဘ်အုပ်စုကို ပိုပြပါ။}}</translation>
 <translation id="427987768447457592">တဘ်အုပ်စုအသစ်</translation>
+<translation id="4371591986692297148">သုံးမနေပါ</translation>
 <translation id="4460014764210899310">အုပ်စု ဖွဲ့မထားပါ</translation>
 <translation id="4648718555153979859">သင့်တဘ်များကို ဤနေရာတွင် အုပ်စုဖွဲ့ထားသည်</translation>
 <translation id="4686942373615810936">ယခုလေးတင် ပြုလုပ်ထားသည်</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ne.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ne.xtb
index ff49ade7..112d51cc 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ne.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ne.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">बैजनी</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> ट्याब भएको <ph name="TITLE_OF_GROUP" /> को ट्याब समूह एक्स्पान्ड गर्नुहोस्।}other{<ph name="TABS_COUNT_MANY" /> वटा ट्याब भएको <ph name="TITLE_OF_GROUP" /> को ट्याब समूह एक्स्पान्ड गर्नुहोस्।}}</translation>
 <translation id="427987768447457592">नयाँ ट्याब समूह</translation>
+<translation id="4371591986692297148">निष्क्रिय</translation>
 <translation id="4460014764210899310">समूह विघटन गर्नुहोस्</translation>
 <translation id="4648718555153979859">तपाईंका ट्याबहरू यहाँ एकै ठाउँमा समूहबद्ध गरिएको छन्</translation>
 <translation id="4686942373615810936">भर्खरै बनाइएको</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_nl.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_nl.xtb
index 6023f31..78171fdc 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_nl.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_nl.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Paars</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Tabbladgroep <ph name="TITLE_OF_GROUP" /> met <ph name="TABS_COUNT_ONE" /> tabblad uitvouwen.}other{Tabbladgroep <ph name="TITLE_OF_GROUP" /> met <ph name="TABS_COUNT_MANY" /> tabbladen uitvouwen.}}</translation>
 <translation id="427987768447457592">Nieuwe tabbladgroep</translation>
+<translation id="4371591986692297148">Inactief</translation>
 <translation id="4460014764210899310">Groeperen ongedaan maken</translation>
 <translation id="4648718555153979859">Je tabbladen zijn hier gegroepeerd</translation>
 <translation id="4686942373615810936">Zojuist gemaakt</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_no.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_no.xtb
index 059a4990..e73f9ed 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_no.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_no.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Fiolett</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Vis fanegruppen <ph name="TITLE_OF_GROUP" /> med <ph name="TABS_COUNT_ONE" /> fane.}other{Vis fanegruppen <ph name="TITLE_OF_GROUP" /> med <ph name="TABS_COUNT_MANY" /> faner.}}</translation>
 <translation id="427987768447457592">Ny fanegruppe</translation>
+<translation id="4371591986692297148">Inaktiv</translation>
 <translation id="4460014764210899310">Fjern gruppering</translation>
 <translation id="4648718555153979859">Fanene dine er gruppert sammen her</translation>
 <translation id="4686942373615810936">Opprettet nå nettopp</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_or.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_or.xtb
index 5e01acf7..67bacaa 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_or.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_or.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">ବାଇଗଣୀ</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> ଟାବ ଥିବା <ph name="TITLE_OF_GROUP" /> ଟାବ ଗ୍ରୁପ ବିସ୍ତାର କରନ୍ତୁ।}other{<ph name="TABS_COUNT_MANY" /> ଟାବ ଥିବା <ph name="TITLE_OF_GROUP" /> ଟାବ ଗ୍ରୁପ ବିସ୍ତାର କରନ୍ତୁ।}}</translation>
 <translation id="427987768447457592">ନୂଆ ଟାବ ଗ୍ରୁପ</translation>
+<translation id="4371591986692297148">ନିଷ୍କ୍ରିୟ</translation>
 <translation id="4460014764210899310">ଅଣଗୋଷ୍ଠୀ କରନ୍ତୁ</translation>
 <translation id="4648718555153979859">ଆପଣଙ୍କର ଟାବ୍‌ଗୁଡ଼ିକ, ଏଠାରେ ଏକାଠି କରାଯାଇଛି</translation>
 <translation id="4686942373615810936">ଏବେ ତିଆରି ହୋଇଛି</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pa.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pa.xtb
index c07f2234..eccc7a1 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pa.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pa.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">ਜਾਮਨੀ</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> ਟੈਬ ਵਾਲੇ <ph name="TITLE_OF_GROUP" /> ਟੈਬ ਗਰੁੱਪ ਦਾ ਵਿਸਤਾਰ ਕਰੋ।}one{<ph name="TABS_COUNT_MANY" /> ਟੈਬ ਵਾਲੇ <ph name="TITLE_OF_GROUP" /> ਟੈਬ ਗਰੁੱਪ ਦਾ ਵਿਸਤਾਰ ਕਰੋ।}other{<ph name="TABS_COUNT_MANY" /> ਟੈਬਾਂ ਵਾਲੇ <ph name="TITLE_OF_GROUP" /> ਟੈਬ ਗਰੁੱਪ ਦਾ ਵਿਸਤਾਰ ਕਰੋ।}}</translation>
 <translation id="427987768447457592">ਨਵਾਂ ਟੈਬ ਗਰੁੱਪ</translation>
+<translation id="4371591986692297148">ਅਕਿਰਿਆਸ਼ੀਲ</translation>
 <translation id="4460014764210899310">ਗਰੁੱਪ ਹਟਾਓ</translation>
 <translation id="4648718555153979859">ਤੁਹਾਡੀਆਂ ਟੈਬਾਂ ਇੱਥੇ ਇਕੱਠੇ ਗਰੁੱਪਬੱਧ ਕੀਤੀਆਂ ਜਾਂਦੀਆਂ ਹਨ</translation>
 <translation id="4686942373615810936">ਹੁਣੇ ਬਣਾਇਆ ਗਿਆ</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pl.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pl.xtb
index 8d93e70a..70a60803 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pl.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pl.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Purpurowy</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Rozwiń grupę kart <ph name="TITLE_OF_GROUP" /> z <ph name="TABS_COUNT_ONE" /> kartą.}few{Rozwiń grupę kart <ph name="TITLE_OF_GROUP" /> z <ph name="TABS_COUNT_MANY" /> kartami.}many{Rozwiń grupę kart <ph name="TITLE_OF_GROUP" /> z <ph name="TABS_COUNT_MANY" /> kartami.}other{Rozwiń grupę kart <ph name="TITLE_OF_GROUP" /> z <ph name="TABS_COUNT_MANY" /> karty.}}</translation>
 <translation id="427987768447457592">Nowa grupa kart</translation>
+<translation id="4371591986692297148">Nieaktywna</translation>
 <translation id="4460014764210899310">Rozgrupuj</translation>
 <translation id="4648718555153979859">Tutaj są zgrupowane Twoje karty</translation>
 <translation id="4686942373615810936">Utworzono przed chwilą</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pt-BR.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pt-BR.xtb
index 850e314..2bda3311 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pt-BR.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pt-BR.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Roxo</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Abrir o grupo "<ph name="TITLE_OF_GROUP" />" com <ph name="TABS_COUNT_ONE" /> guia.}one{Abrir o grupo "<ph name="TITLE_OF_GROUP" />" com <ph name="TABS_COUNT_MANY" /> guia.}other{Abrir o grupo "<ph name="TITLE_OF_GROUP" />" com <ph name="TABS_COUNT_MANY" /> guias.}}</translation>
 <translation id="427987768447457592">Novo grupo de guias</translation>
+<translation id="4371591986692297148">Inativos</translation>
 <translation id="4460014764210899310">Desagrupar</translation>
 <translation id="4648718555153979859">Suas guias são agrupadas aqui</translation>
 <translation id="4686942373615810936">Criado agora</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pt-PT.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pt-PT.xtb
index b3a71f6..ba46898 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pt-PT.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_pt-PT.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Roxo</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Expandir o grupo de separadores <ph name="TITLE_OF_GROUP" /> com <ph name="TABS_COUNT_ONE" /> separador.}other{Expandir o grupo de separadores <ph name="TITLE_OF_GROUP" /> com <ph name="TABS_COUNT_MANY" /> separadores.}}</translation>
 <translation id="427987768447457592">Novo grupo separadores</translation>
+<translation id="4371591986692297148">Inativo</translation>
 <translation id="4460014764210899310">Desagrupar</translation>
 <translation id="4648718555153979859">Os separadores estão agrupados aqui.</translation>
 <translation id="4686942373615810936">Criado agora mesmo</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ro.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ro.xtb
index 574153c..3764201 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ro.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ro.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Mov</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Extinde grupul de file <ph name="TITLE_OF_GROUP" /> cu <ph name="TABS_COUNT_ONE" /> filă.}few{Extinde grupul de file <ph name="TITLE_OF_GROUP" /> cu <ph name="TABS_COUNT_MANY" /> file.}other{Extinde grupul de file <ph name="TITLE_OF_GROUP" /> cu <ph name="TABS_COUNT_MANY" /> de file.}}</translation>
 <translation id="427987768447457592">Grup de file nou</translation>
+<translation id="4371591986692297148">Inactiv</translation>
 <translation id="4460014764210899310">Anulați gruparea</translation>
 <translation id="4648718555153979859">Filele tale sunt grupate aici</translation>
 <translation id="4686942373615810936">Creat chiar acum</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ru.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ru.xtb
index ff0f8dd..208715fa 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ru.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ru.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Фиолетовый</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Развернуть группу вкладок "<ph name="TITLE_OF_GROUP" />". В ней <ph name="TABS_COUNT_ONE" /> вкладка.}one{Развернуть группу вкладок "<ph name="TITLE_OF_GROUP" />". В ней <ph name="TABS_COUNT_MANY" /> вкладка.}few{Развернуть группу вкладок "<ph name="TITLE_OF_GROUP" />". В ней <ph name="TABS_COUNT_MANY" /> вкладки.}many{Развернуть группу вкладок "<ph name="TITLE_OF_GROUP" />". В ней <ph name="TABS_COUNT_MANY" /> вкладок.}other{Развернуть группу вкладок "<ph name="TITLE_OF_GROUP" />". В ней <ph name="TABS_COUNT_MANY" /> вкладки.}}</translation>
 <translation id="427987768447457592">Новая группа вкладок</translation>
+<translation id="4371591986692297148">неактивно</translation>
 <translation id="4460014764210899310">Отменить создание группы</translation>
 <translation id="4648718555153979859">Вкладки сгруппированы здесь</translation>
 <translation id="4686942373615810936">Создано только что</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_si.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_si.xtb
index c0f7fe5..437f804 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_si.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_si.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">දම්</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> පටිත්තක් සමග <ph name="TITLE_OF_GROUP" /> පටිති සමූහය දිග හරින්න.}one{පටිති <ph name="TABS_COUNT_MANY" />ක් සමග <ph name="TITLE_OF_GROUP" /> පටිති සමූහය දිග හරින්න.}other{පටිති <ph name="TABS_COUNT_MANY" />ක් සමග <ph name="TITLE_OF_GROUP" /> පටිති සමූහය දිග හරින්න.}}</translation>
 <translation id="427987768447457592">නව පටිති සමූහය</translation>
+<translation id="4371591986692297148">අක්‍රිය</translation>
 <translation id="4460014764210899310">කණ්ඩායම් නොකරන්න</translation>
 <translation id="4648718555153979859">ඔබේ පටිති මෙහි එකට කණ්ඩායම් කෙරේ</translation>
 <translation id="4686942373615810936">මේ දැන් තනන ලදි</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sk.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sk.xtb
index 785ce0af..efc6be9 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sk.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sk.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Purpurová</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Rozbaľte skupinu kariet <ph name="TITLE_OF_GROUP" /> s <ph name="TABS_COUNT_ONE" /> kartou.}few{Rozbaľte skupinu kariet <ph name="TITLE_OF_GROUP" /> s <ph name="TABS_COUNT_MANY" /> kartami.}many{Expand <ph name="TITLE_OF_GROUP" /> tab group with <ph name="TABS_COUNT_MANY" /> tabs.}other{Rozbaľte skupinu kariet <ph name="TITLE_OF_GROUP" /> s <ph name="TABS_COUNT_MANY" /> kartami.}}</translation>
 <translation id="427987768447457592">Nová skupina kariet</translation>
+<translation id="4371591986692297148">Neaktívne</translation>
 <translation id="4460014764210899310">Zrušiť zoskupenie</translation>
 <translation id="4648718555153979859">Tu sú zoskupené vaše karty</translation>
 <translation id="4686942373615810936">Vytvorená práve teraz</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sl.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sl.xtb
index dc80f7f..2210749d 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sl.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sl.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Vijolična</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Razširitev <ph name="TITLE_OF_GROUP" /> skupine zavihkov z <ph name="TABS_COUNT_ONE" /> zavihkom.}one{Zapiranje <ph name="TITLE_OF_GROUP" /> skupine zavihkov z/s <ph name="TABS_COUNT_MANY" /> zavihkom.}two{Zapiranje <ph name="TITLE_OF_GROUP" /> skupine zavihkov z/s <ph name="TABS_COUNT_MANY" /> zavihkoma.}few{Zapiranje <ph name="TITLE_OF_GROUP" /> skupine zavihkov z/s <ph name="TABS_COUNT_MANY" /> zavihki.}other{Zapiranje <ph name="TITLE_OF_GROUP" /> skupine zavihkov z/s <ph name="TABS_COUNT_MANY" /> zavihki.}}</translation>
 <translation id="427987768447457592">Nova skupina zavihkov</translation>
+<translation id="4371591986692297148">Neaktivno</translation>
 <translation id="4460014764210899310">Razdruži</translation>
 <translation id="4648718555153979859">Zavihki so združeni tukaj</translation>
 <translation id="4686942373615810936">Ustvarjeno pravkar</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sq.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sq.xtb
index 6415766..36ad6b8 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sq.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sq.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Vjollcë</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Zgjero grupin e skedave "<ph name="TITLE_OF_GROUP" />" me <ph name="TABS_COUNT_ONE" /> skedë.}other{Zgjero grupin e skedave "<ph name="TITLE_OF_GROUP" />" me <ph name="TABS_COUNT_MANY" /> skeda.}}</translation>
 <translation id="427987768447457592">Grupi i ri i skedave</translation>
+<translation id="4371591986692297148">Joaktiv</translation>
 <translation id="4460014764210899310">Mos grupo</translation>
 <translation id="4648718555153979859">Skedat e tua grupohen së bashku këtu</translation>
 <translation id="4686942373615810936">Krijuar pikërisht tani</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sr-Latn.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sr-Latn.xtb
index 644129a..db6437f 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sr-Latn.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sr-Latn.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Ljubičasta</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Proširite grupu kartica <ph name="TITLE_OF_GROUP" /> sa <ph name="TABS_COUNT_ONE" /> karticom.}one{Proširite grupu kartica <ph name="TITLE_OF_GROUP" /> sa <ph name="TABS_COUNT_MANY" /> karticom.}few{Proširite grupu kartica <ph name="TITLE_OF_GROUP" /> sa <ph name="TABS_COUNT_MANY" /> kartice.}other{Proširite grupu kartica <ph name="TITLE_OF_GROUP" /> sa <ph name="TABS_COUNT_MANY" /> kartica.}}</translation>
 <translation id="427987768447457592">Nova grupa kartica</translation>
+<translation id="4371591986692297148">Neaktivno</translation>
 <translation id="4460014764210899310">Razdvoji</translation>
 <translation id="4648718555153979859">Kartice su grupisane zajedno ovde</translation>
 <translation id="4686942373615810936">Napravljeno je malopre</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sr.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sr.xtb
index 7f2dfc8..66da1a8 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sr.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sr.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Љубичаста</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Проширите групу картица <ph name="TITLE_OF_GROUP" /> са <ph name="TABS_COUNT_ONE" /> картицом.}one{Проширите групу картица <ph name="TITLE_OF_GROUP" /> са <ph name="TABS_COUNT_MANY" /> картицом.}few{Проширите групу картица <ph name="TITLE_OF_GROUP" /> са <ph name="TABS_COUNT_MANY" /> картице.}other{Проширите групу картица <ph name="TITLE_OF_GROUP" /> са <ph name="TABS_COUNT_MANY" /> картица.}}</translation>
 <translation id="427987768447457592">Нова група картица</translation>
+<translation id="4371591986692297148">Неактивно</translation>
 <translation id="4460014764210899310">Раздвоји</translation>
 <translation id="4648718555153979859">Картице су груписане заједно овде</translation>
 <translation id="4686942373615810936">Направљено је малопре</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sv.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sv.xtb
index 67e27d63..f4e74f5d 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sv.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sv.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Lila</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Utöka flikgruppen <ph name="TITLE_OF_GROUP" /> med <ph name="TABS_COUNT_ONE" /> flik.}other{Utöka flikgruppen <ph name="TITLE_OF_GROUP" /> med <ph name="TABS_COUNT_MANY" /> flikar.}}</translation>
 <translation id="427987768447457592">Ny flikgrupp</translation>
+<translation id="4371591986692297148">Inaktiv</translation>
 <translation id="4460014764210899310">Ta bort gruppering</translation>
 <translation id="4648718555153979859">Dina flikar samlas här</translation>
 <translation id="4686942373615810936">Skapades just nu</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sw.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sw.xtb
index 38e6e72..1ecb93f0 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sw.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_sw.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Zambarau</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Panua kikundi cha kichupo cha <ph name="TITLE_OF_GROUP" /> chenye kichupo <ph name="TABS_COUNT_ONE" />.}other{Panua kikundi cha vichupo cha <ph name="TITLE_OF_GROUP" /> chenye vichupo <ph name="TABS_COUNT_MANY" />.}}</translation>
 <translation id="427987768447457592">Kikundi kipya cha vichupo</translation>
+<translation id="4371591986692297148">Haitumiki</translation>
 <translation id="4460014764210899310">Ondoa kwenye kundi</translation>
 <translation id="4648718555153979859">Vichupo vyako vimewekwa katika kikundi kimoja hapa</translation>
 <translation id="4686942373615810936">Kimeundwa sasa hivi</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ta.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ta.xtb
index abad8ce..cd4058b 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ta.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ta.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">பர்பிள்</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> பக்கம் உள்ள <ph name="TITLE_OF_GROUP" /> பக்கக் குழுவை விரிவாக்கும்.}other{<ph name="TABS_COUNT_MANY" /> பக்கங்கள் உள்ள <ph name="TITLE_OF_GROUP" /> பக்கக் குழுவை விரிவாக்கும்.}}</translation>
 <translation id="427987768447457592">புதிய பக்கக் குழு</translation>
+<translation id="4371591986692297148">செயலில் இல்லை</translation>
 <translation id="4460014764210899310">குழுவைப் பிரி</translation>
 <translation id="4648718555153979859">உங்கள் தாவல்கள் இங்கு குழுவாக்கப்பட்டுள்ளன</translation>
 <translation id="4686942373615810936">சற்றுமுன் உருவாக்கப்பட்டது</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_te.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_te.xtb
index 1fe2aa6..791ed23 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_te.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_te.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">వంగపండు రంగు</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> ట్యాబ్‌తో <ph name="TITLE_OF_GROUP" /> ట్యాబ్ గ్రూప్‌ను విస్తరించండి.}other{<ph name="TABS_COUNT_MANY" /> ట్యాబ్‌లతో <ph name="TITLE_OF_GROUP" /> ట్యాబ్ గ్రూప్‌ను విస్తరించండి.}}</translation>
 <translation id="427987768447457592">కొత్త ట్యాబ్ గ్రూప్</translation>
+<translation id="4371591986692297148">ఇన్‌యాక్టివ్</translation>
 <translation id="4460014764210899310">విడివిడిగా ఉంచు</translation>
 <translation id="4648718555153979859">మీ ట్యాబ్‌లు గ్రూప్ చేయబడి, ఇక్కడ ఉన్నాయి</translation>
 <translation id="4686942373615810936">ఇప్పుడే క్రియేట్ చేయడం జరిగింది</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_th.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_th.xtb
index 02ed6f9..41ba349 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_th.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_th.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">ม่วง</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{ขยายกลุ่มแท็บ <ph name="TITLE_OF_GROUP" /> ที่มีอยู่ <ph name="TABS_COUNT_ONE" /> แท็บ}other{ขยายกลุ่มแท็บ <ph name="TITLE_OF_GROUP" /> ที่มีอยู่ <ph name="TABS_COUNT_MANY" /> แท็บ}}</translation>
 <translation id="427987768447457592">กลุ่มแท็บใหม่</translation>
+<translation id="4371591986692297148">ไม่ได้ใช้งาน</translation>
 <translation id="4460014764210899310">ยกเลิกการจัดกลุ่ม</translation>
 <translation id="4648718555153979859">แท็บของคุณมีการจัดกลุ่มเข้าด้วยกันที่นี่</translation>
 <translation id="4686942373615810936">สร้างเมื่อสักครู่</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_tr.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_tr.xtb
index 3e9ea2e..bfad25f 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_tr.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_tr.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Mor</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> sekmeli <ph name="TITLE_OF_GROUP" /> sekme grubunu genişlet.}other{<ph name="TABS_COUNT_MANY" /> sekmeli <ph name="TITLE_OF_GROUP" /> sekme grubunu genişlet.}}</translation>
 <translation id="427987768447457592">Yeni sekme grubu</translation>
+<translation id="4371591986692297148">Etkin değil</translation>
 <translation id="4460014764210899310">Grubu Çöz</translation>
 <translation id="4648718555153979859">Sekmeleriniz burada gruplandırılır</translation>
 <translation id="4686942373615810936">Az önce oluşturuldu</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_uk.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_uk.xtb
index 74ee54d..d4273e8 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_uk.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_uk.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Пурпуровий</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Розгорнути групу "<ph name="TITLE_OF_GROUP" />" з <ph name="TABS_COUNT_ONE" /> вкладкою.}one{Розгорнути групу "<ph name="TITLE_OF_GROUP" />" з <ph name="TABS_COUNT_MANY" /> вкладкою.}few{Розгорнути групу "<ph name="TITLE_OF_GROUP" />" з <ph name="TABS_COUNT_MANY" /> вкладками.}many{Розгорнути групу "<ph name="TITLE_OF_GROUP" />" з <ph name="TABS_COUNT_MANY" /> вкладками.}other{Розгорнути групу "<ph name="TITLE_OF_GROUP" />" з <ph name="TABS_COUNT_MANY" /> вкладки.}}</translation>
 <translation id="427987768447457592">Нова група вкладок</translation>
+<translation id="4371591986692297148">неактивна</translation>
 <translation id="4460014764210899310">Розгрупувати</translation>
 <translation id="4648718555153979859">Тут згруповано ваші вкладки</translation>
 <translation id="4686942373615810936">Щойно створено</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ur.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ur.xtb
index 8301dfda..80076ff 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ur.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ur.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">جامنی</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TITLE_OF_GROUP" /> ٹیب گروپ کو <ph name="TABS_COUNT_ONE" /> ٹیب کے ساتھ پھیلائیں۔}other{<ph name="TITLE_OF_GROUP" /> ٹیب گروپ کو <ph name="TABS_COUNT_MANY" /> ٹیبز کے ساتھ پھیلائیں۔}}</translation>
 <translation id="427987768447457592">نیا ٹیب گروپ</translation>
+<translation id="4371591986692297148">غیر فعال ہے</translation>
 <translation id="4460014764210899310">گروپ ختم کریں</translation>
 <translation id="4648718555153979859">آپ کے ٹیبز کو ایک ساتھ یہاں گروپ بند کیا گیا ہے</translation>
 <translation id="4686942373615810936">ابھی ابھی تخلیق کیا گیا</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_uz.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_uz.xtb
index e43f4d4..a8b5692 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_uz.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_uz.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Siyohrang</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{<ph name="TABS_COUNT_ONE" /> ta varaqli <ph name="TITLE_OF_GROUP" /> guruhini yoyish.}other{<ph name="TABS_COUNT_MANY" /> ta varaqli <ph name="TITLE_OF_GROUP" /> guruhini yoyish.}}</translation>
 <translation id="427987768447457592">Yangi varaqlar guruhi</translation>
+<translation id="4371591986692297148">Nofaol</translation>
 <translation id="4460014764210899310">Guruhni bekor qilish</translation>
 <translation id="4648718555153979859">Varaqlaringiz shu guruhda jamlanadi</translation>
 <translation id="4686942373615810936">Hozirgina yaratildi</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_vi.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_vi.xtb
index 6f499b8..9f9ea90 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_vi.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_vi.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Tím</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Mở rộng nhóm thẻ <ph name="TITLE_OF_GROUP" /> có <ph name="TABS_COUNT_ONE" /> thẻ.}other{Mở rộng nhóm thẻ <ph name="TITLE_OF_GROUP" /> có <ph name="TABS_COUNT_MANY" /> thẻ.}}</translation>
 <translation id="427987768447457592">Nhóm thẻ mới</translation>
+<translation id="4371591986692297148">Không hoạt động</translation>
 <translation id="4460014764210899310">Tách nhóm</translation>
 <translation id="4648718555153979859">Các thẻ của bạn được nhóm với nhau tại đây</translation>
 <translation id="4686942373615810936">Vừa tạo</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-CN.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-CN.xtb
index 0028814..b37aa85dc 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-CN.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-CN.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">紫色</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{展开包含 <ph name="TABS_COUNT_ONE" /> 个标签页的“<ph name="TITLE_OF_GROUP" />”标签页分组。}other{展开包含 <ph name="TABS_COUNT_MANY" /> 个标签页的“<ph name="TITLE_OF_GROUP" />”标签页分组。}}</translation>
 <translation id="427987768447457592">新标签页分组</translation>
+<translation id="4371591986692297148">已停用</translation>
 <translation id="4460014764210899310">取消分组</translation>
 <translation id="4648718555153979859">您的标签页会按组列在此处</translation>
 <translation id="4686942373615810936">创建时间:刚刚</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-HK.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-HK.xtb
index cbbe65fe..1f7fcb0 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-HK.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-HK.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">紫色</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{打開有 <ph name="TABS_COUNT_ONE" /> 個分頁嘅<ph name="TITLE_OF_GROUP" />分頁群組。}other{打開有 <ph name="TABS_COUNT_MANY" /> 個分頁嘅<ph name="TITLE_OF_GROUP" />分頁群組。}}</translation>
 <translation id="427987768447457592">新分頁群組</translation>
+<translation id="4371591986692297148">未啟用</translation>
 <translation id="4460014764210899310">未分組</translation>
 <translation id="4648718555153979859">您的分頁在這裡分組顯示</translation>
 <translation id="4686942373615810936">剛才建立</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-TW.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-TW.xtb
index 0228296..b4646cf 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-TW.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zh-TW.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">紫色</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{展開含有 <ph name="TABS_COUNT_ONE" /> 個分頁的「<ph name="TITLE_OF_GROUP" />」分頁群組。}other{展開含有 <ph name="TABS_COUNT_MANY" /> 個分頁的「<ph name="TITLE_OF_GROUP" />」分頁群組。}}</translation>
 <translation id="427987768447457592">新分頁群組</translation>
+<translation id="4371591986692297148">未啟用</translation>
 <translation id="4460014764210899310">取消分組</translation>
 <translation id="4648718555153979859">你的分頁都集中顯示在這裡</translation>
 <translation id="4686942373615810936">剛剛建立</translation>
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zu.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zu.xtb
index c4bcd8f..2c339e07 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zu.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_zu.xtb
@@ -66,6 +66,7 @@
 <translation id="4159784952369912983">Okuphephuli</translation>
 <translation id="4220650239473304853">{NUMBER_OF_TABS,plural, =1{Nweba iqembu lethebhu elithi <ph name="TITLE_OF_GROUP" /> ngethebhu eli-<ph name="TABS_COUNT_ONE" />.}one{Nweba iqembu lethebhu elithi <ph name="TITLE_OF_GROUP" /> ngamathebhu angu-<ph name="TABS_COUNT_MANY" />.}other{Nweba iqembu lethebhu elithi <ph name="TITLE_OF_GROUP" /> ngamathebhu angu-<ph name="TABS_COUNT_MANY" />.}}</translation>
 <translation id="427987768447457592">Iqembu lethebhu elisha</translation>
+<translation id="4371591986692297148">Akusebenzi</translation>
 <translation id="4460014764210899310">Khipha ukubuthana</translation>
 <translation id="4648718555153979859">Amathebhu akho afakwa kuqembu ndawonye lapha</translation>
 <translation id="4686942373615810936">Kusanda kusungulwa</translation>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml
index 4db5c2b..3f8a56ef 100644
--- a/chrome/android/java/res/values/dimens.xml
+++ b/chrome/android/java/res/values/dimens.xml
@@ -134,12 +134,6 @@
     <dimen name="mvt_container_top_padding">17dp</dimen>
     <dimen name="mvt_container_bottom_padding">22dp</dimen>
     <dimen name="mvt_container_top_margin">23dp</dimen>
-    <dimen name="ntp_logo_height">100dp</dimen>
-    <dimen name="ntp_logo_margin_top">26dp</dimen>
-    <dimen name="ntp_logo_margin_bottom">23dp</dimen>
-    <dimen name="ntp_logo_height_shrink">72dp</dimen>
-    <dimen name="ntp_logo_vertical_top_margin_tablet">36dp</dimen>
-    <dimen name="ntp_logo_vertical_bottom_margin_tablet">24dp</dimen>
     <dimen name="ntp_search_box_height_for_start_animation">48dp</dimen>
     <dimen name="ntp_search_box_bottom_margin">1dp</dimen>
     <dimen name="ntp_search_box_transition_length">16dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/TabbedModeTabDelegateFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/TabbedModeTabDelegateFactory.java
index 06f6369c..59ba2bb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/TabbedModeTabDelegateFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/TabbedModeTabDelegateFactory.java
@@ -19,7 +19,6 @@
 import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator;
 import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulator;
 import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulatorFactory;
-import org.chromium.chrome.browser.contextmenu.ContextMenuPopulatorFactory;
 import org.chromium.chrome.browser.externalnav.ExternalNavigationDelegateImpl;
 import org.chromium.chrome.browser.fullscreen.BrowserControlsManager;
 import org.chromium.chrome.browser.fullscreen.FullscreenManager;
@@ -44,6 +43,7 @@
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.browser_ui.util.BrowserControlsVisibilityDelegate;
 import org.chromium.components.browser_ui.util.ComposedBrowserControlsVisibilityDelegate;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuPopulatorFactory;
 import org.chromium.components.external_intents.ExternalNavigationHandler;
 import org.chromium.components.externalauth.ExternalAuthUtils;
 import org.chromium.ui.base.WindowAndroid;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
index d543f35..08817d5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -40,7 +40,7 @@
 import org.chromium.chrome.browser.tabpersistence.TabStateFileManager;
 import org.chromium.chrome.browser.tasks.tab_management.TabManagementFieldTrial;
 import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities;
-import org.chromium.chrome.browser.ui.google_bottom_bar.GoogleBottomBarCoordinator;
+import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator;
 import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration;
 import org.chromium.components.omnibox.OmniboxFeatures;
 
@@ -94,7 +94,7 @@
                         CustomTabIntentDataProvider.ALLOWLIST_ENTRIES,
                         CustomTabIntentDataProvider.OMNIBOX_ALLOWED_PACKAGE_NAMES,
                         DseNewTabUrlManager.SWAP_OUT_NTP,
-                        GoogleBottomBarCoordinator.GOOGLE_BOTTOM_BAR_PARAM_BUTTON_LIST,
+                        BottomBarConfigCreator.GOOGLE_BOTTOM_BAR_PARAM_BUTTON_LIST,
                         HubFieldTrial.PANE_SWITCHER_USES_TEXT,
                         HubFieldTrial.SUPPORTS_OTHER_TABS,
                         HubFieldTrial.SUPPORTS_SEARCH,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
index 229cd44..7cca762 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -54,7 +54,13 @@
 import org.chromium.chrome.browser.share.ShareUtils;
 import org.chromium.chrome.browser.share.link_to_text.LinkToTextHelper;
 import org.chromium.components.browser_ui.share.ShareParams;
+import org.chromium.components.embedder_support.contextmenu.ChipDelegate;
+import org.chromium.components.embedder_support.contextmenu.ChipRenderParams;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuImageFormat;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuItemDelegate;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuNativeDelegate;
 import org.chromium.components.embedder_support.contextmenu.ContextMenuParams;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuPopulator;
 import org.chromium.components.embedder_support.util.UrlUtilities;
 import org.chromium.components.externalauth.ExternalAuthUtils;
 import org.chromium.components.feature_engagement.FeatureConstants;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorFactory.java
index 3459fbee..603c681 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorFactory.java
@@ -11,7 +11,11 @@
 import org.chromium.base.supplier.Supplier;
 import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulator.ContextMenuMode;
 import org.chromium.chrome.browser.share.ShareDelegate;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuItemDelegate;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuNativeDelegate;
 import org.chromium.components.embedder_support.contextmenu.ContextMenuParams;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuPopulator;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuPopulatorFactory;
 import org.chromium.components.externalauth.ExternalAuthUtils;
 
 /** Factory for creating {@link ContextMenuPopulator}s. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuChipController.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuChipController.java
index 10409b4..6ed798ef 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuChipController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuChipController.java
@@ -15,6 +15,7 @@
 
 import org.chromium.chrome.R;
 import org.chromium.components.browser_ui.widget.chips.ChipView;
+import org.chromium.components.embedder_support.contextmenu.ChipRenderParams;
 import org.chromium.ui.text.SpanApplier;
 import org.chromium.ui.text.SpanApplier.SpanInfo;
 import org.chromium.ui.widget.AnchoredPopupWindow;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuCoordinator.java
index e16d4fcf..9712e83 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuCoordinator.java
@@ -26,6 +26,9 @@
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.components.browser_ui.widget.ContextMenuDialog;
+import org.chromium.components.embedder_support.contextmenu.ChipDelegate;
+import org.chromium.components.embedder_support.contextmenu.ChipRenderParams;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuNativeDelegate;
 import org.chromium.components.embedder_support.contextmenu.ContextMenuParams;
 import org.chromium.content_public.browser.ContentFeatureMap;
 import org.chromium.content_public.browser.LoadCommittedDetails;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHeaderCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHeaderCoordinator.java
index 45ac638..f6c17d4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHeaderCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHeaderCoordinator.java
@@ -17,6 +17,7 @@
 import org.chromium.chrome.browser.omnibox.styles.OmniboxResourceProvider;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.ui.theme.BrandedColorScheme;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuNativeDelegate;
 import org.chromium.components.embedder_support.contextmenu.ContextMenuParams;
 import org.chromium.components.omnibox.OmniboxUrlEmphasizer;
 import org.chromium.components.security_state.ConnectionSecurityLevel;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHeaderMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHeaderMediator.java
index 2d1067f1..93f8b6c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHeaderMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHeaderMediator.java
@@ -25,6 +25,7 @@
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.components.browser_ui.styles.SemanticColorUtils;
 import org.chromium.components.browser_ui.widget.RoundedIconGenerator;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuNativeDelegate;
 import org.chromium.components.embedder_support.contextmenu.ContextMenuParams;
 import org.chromium.components.favicon.IconType;
 import org.chromium.components.favicon.LargeIconBridge;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java
index a27abe7..c240aae 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuHelper.java
@@ -15,7 +15,11 @@
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.task.PostTask;
 import org.chromium.base.task.TaskTraits;
+import org.chromium.components.embedder_support.contextmenu.ChipDelegate;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuNativeDelegate;
 import org.chromium.components.embedder_support.contextmenu.ContextMenuParams;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuPopulator;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuPopulatorFactory;
 import org.chromium.content_public.browser.RenderFrameHost;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.ui.base.WindowAndroid;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/LensChipDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/LensChipDelegate.java
index 211b3ba..6189267 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/LensChipDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/LensChipDelegate.java
@@ -11,6 +11,10 @@
 import org.chromium.chrome.browser.lens.LensController;
 import org.chromium.chrome.browser.lens.LensEntryPoint;
 import org.chromium.chrome.browser.lens.LensQueryParams;
+import org.chromium.components.embedder_support.contextmenu.ChipDelegate;
+import org.chromium.components.embedder_support.contextmenu.ChipRenderParams;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuImageFormat;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuNativeDelegate;
 import org.chromium.content_public.browser.WebContents;
 
 /** The class to handle Lens chip data and actions. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java
index c671c0f..21ab65c4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java
@@ -32,7 +32,6 @@
 import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator;
 import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulator;
 import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulatorFactory;
-import org.chromium.chrome.browser.contextmenu.ContextMenuPopulatorFactory;
 import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabBrowserControlsVisibilityDelegate;
 import org.chromium.chrome.browser.dependency_injection.ActivityScope;
 import org.chromium.chrome.browser.externalnav.ExternalNavigationDelegateImpl;
@@ -57,6 +56,7 @@
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.browser_ui.util.BrowserControlsVisibilityDelegate;
 import org.chromium.components.browser_ui.util.ComposedBrowserControlsVisibilityDelegate;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuPopulatorFactory;
 import org.chromium.components.embedder_support.delegate.WebContentsDelegateAndroid;
 import org.chromium.components.embedder_support.util.UrlConstants;
 import org.chromium.components.embedder_support.util.UrlUtilities;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/OWNERS
index d8353d1..22bd815 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/OWNERS
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/OWNERS
@@ -1,4 +1,3 @@
 file://chrome/browser/android/signin/OWNERS
-pkotwicz@chromium.org
 skym@chromium.org
 wenyufu@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java
index abcf097..bc0b82c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java
@@ -399,19 +399,6 @@
         // room, we don't need to fetch logo image.
         boolean shouldFetchDoodle = !FeedPositionUtils.isFeedPullUpEnabled();
         mLogoView = findViewById(R.id.search_provider_logo);
-        if (mIsSurfacePolishEnabled) {
-            LogoUtils.setLogoViewLayoutParams(
-                    mLogoView,
-                    getResources(),
-                    mIsTablet,
-                    mIsLogoPolishEnabled,
-                    mIsInMultiWindowModeOnTablet
-                            ? LogoSizeForLogoPolish.SMALL
-                            : mLogoSizeForLogoPolish);
-        } else if (mIsTablet) {
-            mLogoView.getLayoutParams().height =
-                    mContext.getResources().getDimensionPixelSize(R.dimen.ntp_logo_height_shrink);
-        }
 
         mLogoCoordinator =
                 new LogoCoordinator(
@@ -653,7 +640,6 @@
         LogoUtils.setLogoViewLayoutParams(
                 mLogoView,
                 getResources(),
-                mIsTablet,
                 mIsLogoPolishEnabled,
                 mIsInMultiWindowModeOnTablet
                         ? LogoSizeForLogoPolish.SMALL
@@ -859,14 +845,6 @@
             return LogoUtils.getTopMarginForLogoPolish(resources);
         }
 
-        if (mIsSurfacePolishEnabled && mSearchProviderHasLogo) {
-            return LogoUtils.getTopMarginPolished(resources);
-        }
-
-        if (mIsTablet && mSearchProviderHasLogo) {
-            return resources.getDimensionPixelSize(R.dimen.ntp_logo_vertical_top_margin_tablet);
-        }
-
         return resources.getDimensionPixelSize(R.dimen.ntp_logo_margin_top);
     }
 
@@ -877,14 +855,6 @@
             return LogoUtils.getBottomMarginForLogoPolish(resources);
         }
 
-        if (mIsSurfacePolishEnabled && mSearchProviderHasLogo) {
-            return LogoUtils.getBottomMarginPolished(resources);
-        }
-
-        if (mIsTablet && mSearchProviderHasLogo) {
-            return resources.getDimensionPixelSize(R.dimen.ntp_logo_vertical_bottom_margin_tablet);
-        }
-
         return resources.getDimensionPixelSize(R.dimen.ntp_logo_margin_bottom);
     }
 
@@ -1048,7 +1018,6 @@
             LogoUtils.setLogoViewLayoutParams(
                     mLogoView,
                     getResources(),
-                    mIsTablet,
                     mIsLogoPolishEnabled,
                     mIsInMultiWindowModeOnTablet
                             ? LogoSizeForLogoPolish.SMALL
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityTabDelegateFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityTabDelegateFactory.java
index 325184d..87216ac 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityTabDelegateFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/searchwidget/SearchActivityTabDelegateFactory.java
@@ -9,13 +9,13 @@
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.blink.mojom.DisplayMode;
-import org.chromium.chrome.browser.contextmenu.ContextMenuPopulatorFactory;
 import org.chromium.chrome.browser.pdf.PdfInfo;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabDelegateFactory;
 import org.chromium.chrome.browser.tab.TabWebContentsDelegateAndroid;
 import org.chromium.chrome.browser.ui.native_page.NativePage;
 import org.chromium.components.browser_ui.util.BrowserControlsVisibilityDelegate;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuPopulatorFactory;
 import org.chromium.components.external_intents.ExternalNavigationHandler;
 import org.chromium.content_public.browser.WebContents;
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInActivity.java
index e5d698e..2dd883b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInActivity.java
@@ -109,7 +109,7 @@
                             PrivacyPreferencesManagerImpl.getInstance(),
                             this);
 
-            setContentView(mUpgradePromoCoordinator.getViewSwitcher());
+            setContentView(mUpgradePromoCoordinator.getView());
             onInitialLayoutInflationComplete();
             return;
         }
@@ -229,7 +229,7 @@
             mCoordinator.switchHistorySyncLayout();
         } else {
             mUpgradePromoCoordinator.recreateLayoutAfterConfigurationChange();
-            setContentView(mUpgradePromoCoordinator.getViewSwitcher());
+            setContentView(mUpgradePromoCoordinator.getView());
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java
index 048764c3..dfba9eb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java
@@ -42,6 +42,7 @@
 import org.chromium.chrome.browser.ui.signin.fullscreen_signin.FullscreenSigninView;
 import org.chromium.components.browser_ui.device_lock.DeviceLockActivityLauncher;
 import org.chromium.components.signin.AccountManagerFacadeProvider;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.ui.modaldialog.ModalDialogManager;
 import org.chromium.ui.modaldialog.ModalDialogManagerHolder;
 
@@ -73,7 +74,8 @@
                         requireContext(),
                         mModalDialogManager,
                         this,
-                        PrivacyPreferencesManagerImpl.getInstance());
+                        PrivacyPreferencesManagerImpl.getInstance(),
+                        SigninAccessPoint.START_PAGE);
 
         if (getPageDelegate().isLaunchedFromCct()) {
             mSkipTosDialogPolicyListener =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS b/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS
index e9b2ac6..f2ef4e1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/DEPS
@@ -102,6 +102,7 @@
     "-components",
     "+components/android_autofill/browser/java/src/org/chromium/components/autofill",
     "+components/dom_distiller/core/android/java/src/org/chromium/components/dom_distiller/core/DomDistillerUrlUtils.java",
+    "+components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu",
     "+components/embedder_support/android/java/src/org/chromium/components/embedder_support/delegate",
     "+components/embedder_support/android/java/src/org/chromium/components/embedder_support/util",
     "+components/embedder_support/android/java/src/org/chromium/components/embedder_support/view",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
index b762241..5840546 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
@@ -26,7 +26,6 @@
 import org.chromium.chrome.browser.bookmarks.BookmarkModel;
 import org.chromium.chrome.browser.bookmarks.BookmarkUtils;
 import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator;
-import org.chromium.chrome.browser.contextmenu.ContextMenuItemDelegate;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.browser.download.ChromeDownloadDelegate;
 import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
@@ -42,6 +41,7 @@
 import org.chromium.chrome.browser.tasks.tab_management.TabGroupCreationDialogManager;
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuItemDelegate;
 import org.chromium.components.embedder_support.util.UrlUtilities;
 import org.chromium.components.feature_engagement.EventConstants;
 import org.chromium.content_public.browser.AdditionalNavigationParams;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuPopulator.java
index 5f2dd10..5a44034 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuPopulator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuPopulator.java
@@ -9,8 +9,8 @@
 import androidx.annotation.Nullable;
 
 import org.chromium.base.ObserverList.RewindableIterator;
-import org.chromium.chrome.browser.contextmenu.ChipDelegate;
-import org.chromium.chrome.browser.contextmenu.ContextMenuPopulator;
+import org.chromium.components.embedder_support.contextmenu.ChipDelegate;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuPopulator;
 import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
 
 import java.util.List;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuPopulatorFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuPopulatorFactory.java
index be6b03ca..b7b6783f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuPopulatorFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuPopulatorFactory.java
@@ -6,14 +6,14 @@
 
 import android.content.Context;
 
-import org.chromium.chrome.browser.contextmenu.ContextMenuNativeDelegate;
-import org.chromium.chrome.browser.contextmenu.ContextMenuPopulator;
-import org.chromium.chrome.browser.contextmenu.ContextMenuPopulatorFactory;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuNativeDelegate;
 import org.chromium.components.embedder_support.contextmenu.ContextMenuParams;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuPopulator;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuPopulatorFactory;
 
 /**
- * A simple wrapper around a {@link ContextMenuPopulatorFactory} for creating
- * {@link TabContextMenuPopulator} which is able to handle observer notifications.
+ * A simple wrapper around a {@link ContextMenuPopulatorFactory} for creating {@link
+ * TabContextMenuPopulator} which is able to handle observer notifications.
  */
 class TabContextMenuPopulatorFactory implements ContextMenuPopulatorFactory {
     private final ContextMenuPopulatorFactory mPopulatorFactory;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
index 65ff6516..6e0ab989 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
@@ -46,7 +46,6 @@
 import org.chromium.chrome.browser.compositor.CompositorViewHolder;
 import org.chromium.chrome.browser.content.ContentUtils;
 import org.chromium.chrome.browser.content.WebContentsFactory;
-import org.chromium.chrome.browser.contextmenu.ContextMenuPopulatorFactory;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.native_page.NativePageAssassin;
@@ -66,6 +65,7 @@
 import org.chromium.components.autofill.AutofillSelectionActionMenuDelegate;
 import org.chromium.components.autofill.AutofillSelectionMenuItemHelper;
 import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuPopulatorFactory;
 import org.chromium.components.embedder_support.util.UrlConstants;
 import org.chromium.components.embedder_support.view.ContentView;
 import org.chromium.components.security_state.ConnectionSecurityLevel;
diff --git a/chrome/android/javatests/AndroidManifest.xml b/chrome/android/javatests/AndroidManifest.xml
index 8d073d21..e643543f 100644
--- a/chrome/android/javatests/AndroidManifest.xml
+++ b/chrome/android/javatests/AndroidManifest.xml
@@ -8,9 +8,7 @@
 
 {% block extra_uses_permissions %}
     <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
-    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
     <uses-permission android:name="android.permission.READ_LOGS"/>
-    <uses-permission android:name="android.permission.SET_ANIMATION_SCALE"/>
 {% endblock %}
 
 {% block extra_application_definitions_for_test %}
@@ -34,14 +32,6 @@
             android:exported="true"/>
 {% endblock %}
 
-{% block extra_application_attributes %}
-{{ super() }}
-## Test listing breaks because of scoped storage in Android 10 - see
-## https://developer.android.com/training/data-storage#scoped-storage and
-## https://developer.android.com/training/data-storage/compatibility.
-android:requestLegacyExternalStorage="true"
-{% endblock %}
-
 {% block extra_root_definitions %}
     <instrumentation android:name="org.chromium.base.test.BaseChromiumAndroidJUnitRunner"
         android:targetPackage="{{manifest_package}}"
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java
index c2384dc..b1e6ffb0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java
@@ -49,6 +49,8 @@
 import org.chromium.chrome.browser.profiles.ProfileJni;
 import org.chromium.chrome.browser.share.ShareDelegate;
 import org.chromium.chrome.test.AutomotiveContextWrapperTestRule;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuItemDelegate;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuNativeDelegate;
 import org.chromium.components.embedder_support.contextmenu.ContextMenuParams;
 import org.chromium.components.externalauth.ExternalAuthUtils;
 import org.chromium.components.search_engines.TemplateUrlService;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuChipControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuChipControllerTest.java
index 5050f12..8e1ce2f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuChipControllerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuChipControllerTest.java
@@ -25,6 +25,7 @@
 import org.chromium.base.test.util.Batch;
 import org.chromium.chrome.R;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.components.embedder_support.contextmenu.ChipRenderParams;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.test.util.BlankUiTestActivityTestCase;
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
index 2c14766..d2f40f3 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
@@ -70,7 +70,11 @@
 import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.chrome.test.util.browser.contextmenu.ContextMenuUtils;
 import org.chromium.components.browser_ui.share.ShareParams;
+import org.chromium.components.embedder_support.contextmenu.ChipDelegate;
+import org.chromium.components.embedder_support.contextmenu.ChipRenderParams;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuItemDelegate;
 import org.chromium.components.embedder_support.contextmenu.ContextMenuParams;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuPopulatorFactory;
 import org.chromium.components.externalauth.ExternalAuthUtils;
 import org.chromium.components.policy.test.annotations.Policies;
 import org.chromium.content_public.browser.test.util.DOMUtils;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/PasswordSavingIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/PasswordSavingIntegrationTest.java
index 9c5630d..84970a136 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/PasswordSavingIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/PasswordSavingIntegrationTest.java
@@ -23,7 +23,6 @@
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
-import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Matchers;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
@@ -68,7 +67,6 @@
     private static final String PASSWORD_NODE_ID = "password_field";
     private static final String OLD_PASSWORD_NODE_ID = "chg_password_field";
     private static final String NEW_PASSWORD_NODE_ID = "chg_new_password_1";
-    private static final String NEW_PASSWORD_REPEAT_NODE_ID = "chg_new_password_2";
     private static final String USERNAME_TEXT = "username";
     private static final String PASSWORD_TEXT = "password";
     private static final String NEW_PASSWORD_TEXT = "new password";
@@ -150,7 +148,6 @@
     @MediumTest
     @Restriction(DeviceRestriction.RESTRICTION_TYPE_NON_AUTO)
     // TODO(crbug.com/40927881): Add integration tests for automotive update password flow.
-    @DisabledTest(message = "https://crbug.com/1468903")
     public void testUpdatingPassword() throws InterruptedException, TimeoutException {
         // Store the test credential.
         PasswordStoreCredential testCredential =
@@ -189,11 +186,6 @@
         // Enter the new password.
         enterInputIntoTextField(
                 mWebContents, mInputMethodManagerWrapper, NEW_PASSWORD_NODE_ID, NEW_PASSWORD_TEXT);
-        enterInputIntoTextField(
-                mWebContents,
-                mInputMethodManagerWrapper,
-                NEW_PASSWORD_REPEAT_NODE_ID,
-                NEW_PASSWORD_TEXT);
 
         // Submit the form and wait for the success page to load.
         DOMUtils.clickNodeWithJavaScript(mWebContents, CHANGE_PASSWORD_BUTTON_ID);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java
index 4da6373..ce02f2e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java
@@ -22,7 +22,6 @@
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.R;
-import org.chromium.components.payments.Event;
 import org.chromium.components.payments.Event2;
 import org.chromium.components.prefs.PrefService;
 import org.chromium.components.user_prefs.UserPrefs;
@@ -74,18 +73,14 @@
 
         // Make sure the canMakePayment events were logged correctly.
         int expectedSample =
-                Event.SHOWN
-                        | Event.USER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.CAN_MAKE_PAYMENT_TRUE
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.HAS_ENROLLED_INSTRUMENT_TRUE
-                        | Event.AVAILABLE_METHOD_OTHER;
+                Event2.SHOWN
+                        | Event2.USER_ABORTED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_METHOD_OTHER;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 
     /**
@@ -132,19 +127,15 @@
 
         // Make sure the canMakePayment events were logged correctly.
         int expectedSample =
-                Event.SHOWN
-                        | Event.PAY_CLICKED
-                        | Event.RECEIVED_INSTRUMENT_DETAILS
-                        | Event.COMPLETED
-                        | Event.CAN_MAKE_PAYMENT_TRUE
-                        | Event.HAS_ENROLLED_INSTRUMENT_FALSE
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.SELECTED_CREDIT_CARD
-                        | Event.NEEDS_COMPLETION_PAYMENT;
+                Event2.SHOWN
+                        | Event2.PAY_CLICKED
+                        | Event2.COMPLETED
+                        | Event2.REQUEST_METHOD_OTHER
+                        | Event2.SELECTED_CREDIT_CARD;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 
     /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsAndFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsAndFreeShippingTest.java
index 533d6ad7..605fbf5 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsAndFreeShippingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsAndFreeShippingTest.java
@@ -21,7 +21,7 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.R;
 import org.chromium.components.autofill.AutofillProfile;
-import org.chromium.components.payments.Event;
+import org.chromium.components.payments.Event2;
 
 import java.util.concurrent.TimeoutException;
 
@@ -103,22 +103,17 @@
     @Feature({"Payments"})
     public void testPaymentRequestEventsMetric() throws TimeoutException {
         int expectedSample =
-                Event.SHOWN
-                        | Event.PAY_CLICKED
-                        | Event.RECEIVED_INSTRUMENT_DETAILS
-                        | Event.COMPLETED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_PAYER_PHONE
-                        | Event.REQUEST_PAYER_EMAIL
-                        | Event.REQUEST_PAYER_NAME
-                        | Event.REQUEST_SHIPPING
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER
-                        | Event.SELECTED_OTHER;
+                Event2.SHOWN
+                        | Event2.PAY_CLICKED
+                        | Event2.COMPLETED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_PAYER_DATA
+                        | Event2.REQUEST_SHIPPING
+                        | Event2.REQUEST_METHOD_OTHER
+                        | Event2.SELECTED_OTHER;
         var histogramWatcher =
                 HistogramWatcher.newBuilder()
-                        .expectIntRecord("PaymentRequest.Events", expectedSample)
+                        .expectIntRecord("PaymentRequest.Events2", expectedSample)
                         .build();
 
         // Start and complete the Payment Request.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsTest.java
index 873de550..6fc469f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestContactDetailsTest.java
@@ -23,7 +23,7 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.R;
 import org.chromium.components.autofill.AutofillProfile;
-import org.chromium.components.payments.Event;
+import org.chromium.components.payments.Event2;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 
 import java.util.concurrent.TimeoutException;
@@ -375,23 +375,18 @@
                 new String[] {"Jon Doe", "+15555555555", "jon.doe@google.com"});
 
         int expectedSample =
-                Event.SHOWN
-                        | Event.COMPLETED
-                        | Event.PAY_CLICKED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.RECEIVED_INSTRUMENT_DETAILS
-                        | Event.REQUEST_PAYER_EMAIL
-                        | Event.REQUEST_PAYER_PHONE
-                        | Event.REQUEST_PAYER_NAME
-                        | Event.REQUEST_METHOD_BASIC_CARD
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.SELECTED_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER;
+                Event2.SHOWN
+                        | Event2.COMPLETED
+                        | Event2.PAY_CLICKED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_PAYER_DATA
+                        | Event2.REQUEST_METHOD_BASIC_CARD
+                        | Event2.REQUEST_METHOD_OTHER
+                        | Event2.SELECTED_OTHER;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 
     /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndFreeShippingTest.java
index 5faeb063..fa90a01c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndFreeShippingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndFreeShippingTest.java
@@ -22,7 +22,7 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.R;
 import org.chromium.components.autofill.AutofillProfile;
-import org.chromium.components.payments.Event;
+import org.chromium.components.payments.Event2;
 
 import java.util.concurrent.TimeoutException;
 
@@ -94,17 +94,15 @@
     @Feature({"Payments"})
     public void testPaymentRequestEventsMetric() throws TimeoutException {
         int expectedSample =
-                Event.SHOWN
-                        | Event.USER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_PAYER_EMAIL
-                        | Event.REQUEST_SHIPPING
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER;
+                Event2.SHOWN
+                        | Event2.USER_ABORTED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_PAYER_DATA
+                        | Event2.REQUEST_SHIPPING
+                        | Event2.REQUEST_METHOD_OTHER;
         var histogramWatcher =
                 HistogramWatcher.newBuilder()
-                        .expectIntRecord("PaymentRequest.Events", expectedSample)
+                        .expectIntRecord("PaymentRequest.Events2", expectedSample)
                         .build();
 
         // Start and cancel the Payment Request.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndPhoneTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndPhoneTest.java
index 7c20b1c6..32db684 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndPhoneTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailAndPhoneTest.java
@@ -23,7 +23,7 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.R;
 import org.chromium.components.autofill.AutofillProfile;
-import org.chromium.components.payments.Event;
+import org.chromium.components.payments.Event2;
 
 import java.util.concurrent.TimeoutException;
 
@@ -198,17 +198,14 @@
     @Feature({"Payments"})
     public void testPaymentRequestEventsMetric() throws TimeoutException {
         int expectedSample =
-                Event.SHOWN
-                        | Event.USER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_PAYER_EMAIL
-                        | Event.REQUEST_PAYER_PHONE
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER;
+                Event2.SHOWN
+                        | Event2.USER_ABORTED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_PAYER_DATA
+                        | Event2.REQUEST_METHOD_OTHER;
         var histogramWatcher =
                 HistogramWatcher.newBuilder()
-                        .expectIntRecord("PaymentRequest.Events", expectedSample)
+                        .expectIntRecord("PaymentRequest.Events2", expectedSample)
                         .build();
 
         // Start and cancel the Payment Request.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailTest.java
index f52e762..f183649 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestEmailTest.java
@@ -23,7 +23,7 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.R;
 import org.chromium.components.autofill.AutofillProfile;
-import org.chromium.components.payments.Event;
+import org.chromium.components.payments.Event2;
 
 import java.util.concurrent.TimeoutException;
 
@@ -200,20 +200,17 @@
         mPaymentRequestTestRule.expectResultContains(new String[] {"jon.doe@google.com"});
 
         int expectedSample =
-                Event.SHOWN
-                        | Event.COMPLETED
-                        | Event.PAY_CLICKED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.RECEIVED_INSTRUMENT_DETAILS
-                        | Event.REQUEST_PAYER_EMAIL
-                        | Event.REQUEST_METHOD_BASIC_CARD
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER
-                        | Event.SELECTED_OTHER;
+                Event2.SHOWN
+                        | Event2.COMPLETED
+                        | Event2.PAY_CLICKED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_PAYER_DATA
+                        | Event2.REQUEST_METHOD_BASIC_CARD
+                        | Event2.REQUEST_METHOD_OTHER
+                        | Event2.SELECTED_OTHER;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFreeShippingTest.java
index d9bf20b..ca1f72d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFreeShippingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestFreeShippingTest.java
@@ -27,7 +27,7 @@
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
 import org.chromium.chrome.test.R;
 import org.chromium.components.autofill.AutofillProfile;
-import org.chromium.components.payments.Event;
+import org.chromium.components.payments.Event2;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.test.util.NightModeTestUtils;
 import org.chromium.ui.test.util.RenderTestRule;
@@ -364,16 +364,14 @@
                 new String[] {"User closed the Payment Request UI."});
 
         int expectedSample =
-                Event.SHOWN
-                        | Event.USER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_SHIPPING
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER;
+                Event2.SHOWN
+                        | Event2.USER_ABORTED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_SHIPPING
+                        | Event2.REQUEST_METHOD_OTHER;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java
index 39ed1f8..0e0e40c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java
@@ -25,7 +25,7 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.R;
 import org.chromium.components.autofill.AutofillProfile;
-import org.chromium.components.payments.Event;
+import org.chromium.components.payments.Event2;
 
 import java.util.concurrent.TimeoutException;
 
@@ -103,175 +103,6 @@
     }
 
     /**
-     * Expect that the metric that records whether the user had complete suggestions for the
-     * requested information is logged correctly.
-     */
-    @Test
-    @MediumTest
-    @Feature({"Payments"})
-    public void testUserHadCompleteSuggestions_Shipping() throws TimeoutException {
-        // Ensure Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS is present.
-        int expectedSample =
-                Event.SHOWN
-                        | Event.USER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_SHIPPING
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER;
-        HistogramWatcher histogramWatcher =
-                HistogramWatcher.newBuilder()
-                        .expectIntRecord("PaymentRequest.Events", expectedSample)
-                        .build();
-
-        // Cancel the payment request.
-        mPaymentRequestTestRule.runJavaScriptAndWaitForUIEvent(
-                "buyWithMethods([{supportedMethods: 'https://bobpay.test'}]);",
-                mPaymentRequestTestRule.getReadyToPay());
-        mPaymentRequestTestRule.clickAndWait(
-                R.id.close_button, mPaymentRequestTestRule.getDismissed());
-        mPaymentRequestTestRule.expectResultContains(
-                new String[] {"User closed the Payment Request UI."});
-
-        // Make sure the events were logged correctly.
-        histogramWatcher.pollInstrumentationThreadUntilSatisfied();
-    }
-
-    /**
-     * Expect that the metric that records whether the user had complete suggestions for the
-     * requested information is logged correctly.
-     */
-    @Test
-    @MediumTest
-    @Feature({"Payments"})
-    public void testUserDidNotHaveCompleteSuggestions_IncompleteShipping() throws Exception {
-        int expectedSample =
-                Event.SHOWN
-                        | Event.USER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.REQUEST_SHIPPING
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER
-                        | Event.NEEDS_COMPLETION_SHIPPING;
-        HistogramWatcher histogramWatcher =
-                HistogramWatcher.newBuilder()
-                        .expectIntRecord("PaymentRequest.Events", expectedSample)
-                        .build();
-        // Set only an incomplete address (no region).
-        var autofillTestHelper = new AutofillTestHelper();
-        autofillTestHelper.clearAllDataForTesting();
-        autofillTestHelper.setProfile(
-                AutofillProfile.builder()
-                        .setFullName("Jon Doe")
-                        .setCompanyName("Google")
-                        .setStreetAddress("340 Main St")
-                        .setLocality("Los Angeles")
-                        .setPostalCode("90291")
-                        .setCountryCode("US")
-                        .setPhoneNumber("650-253-0000")
-                        .setLanguageCode("en-US")
-                        .build());
-
-        // Cancel the payment request.
-        mPaymentRequestTestRule.runJavaScriptAndWaitForUIEvent(
-                "buyWithMethods([{supportedMethods: 'https://bobpay.test'}]);",
-                mPaymentRequestTestRule.getReadyForInput());
-        mPaymentRequestTestRule.clickAndWait(
-                R.id.close_button, mPaymentRequestTestRule.getDismissed());
-        mPaymentRequestTestRule.expectResultContains(
-                new String[] {"User closed the Payment Request UI."});
-
-        // Make sure the events were logged correctly, particularly NEEDS_COMPLETION_SHIPPING is
-        // set.
-        histogramWatcher.pollInstrumentationThreadUntilSatisfied();
-    }
-
-    /**
-     * Expect that the metric that records whether the user had complete suggestions for the
-     * requested information is logged correctly.
-     */
-    @Test
-    @MediumTest
-    @Feature({"Payments"})
-    public void testUserHadCompleteSuggestions_PaymentApp_HasValidPaymentApp()
-            throws TimeoutException {
-        int expectedSample =
-                Event.SHOWN
-                        | Event.USER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_SHIPPING
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER;
-        HistogramWatcher histogramWatcher =
-                HistogramWatcher.newBuilder()
-                        .expectIntRecord("PaymentRequest.Events", expectedSample)
-                        .build();
-        mPaymentRequestTestRule.addPaymentAppFactory(
-                "https://kylepay.test/webpay", AppPresence.HAVE_APPS, FactorySpeed.FAST_FACTORY);
-
-        // Cancel the payment request.
-        mPaymentRequestTestRule.triggerUIAndWait(
-                "buyWithUrlMethods", mPaymentRequestTestRule.getReadyForInput());
-        mPaymentRequestTestRule.clickAndWait(
-                R.id.close_button, mPaymentRequestTestRule.getDismissed());
-        mPaymentRequestTestRule.expectResultContains(
-                new String[] {"User closed the Payment Request UI."});
-
-        // Make sure the events were logged correctly.
-        histogramWatcher.pollInstrumentationThreadUntilSatisfied();
-    }
-
-    /**
-     * Expect that the metric that records whether the user had complete suggestions for the
-     * requested information is logged correctly.
-     */
-    @Test
-    @MediumTest
-    @Feature({"Payments"})
-    public void testUserHadCompleteSuggestions_ShippingAndPaymentApp_HasInvalidShipping()
-            throws TimeoutException {
-        int expectedSample =
-                Event.SHOWN
-                        | Event.USER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.REQUEST_SHIPPING
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER
-                        | Event.NEEDS_COMPLETION_SHIPPING;
-        HistogramWatcher histogramWatcher =
-                HistogramWatcher.newBuilder()
-                        .expectIntRecord("PaymentRequest.Events", expectedSample)
-                        .build();
-        // Add a card and an incomplete address (no region).
-        AutofillTestHelper autofillTestHelper = new AutofillTestHelper();
-        autofillTestHelper.clearAllDataForTesting();
-        autofillTestHelper.setProfile(
-                AutofillProfile.builder()
-                        .setFullName("Jon Doe")
-                        .setCompanyName("Google")
-                        .setStreetAddress("340 Main St")
-                        .setLocality("Los Angeles")
-                        .setPostalCode("90291")
-                        .setCountryCode("US")
-                        .setPhoneNumber("650-253-0000")
-                        .setLanguageCode("en-US")
-                        .build());
-
-        // Cancel the payment request.
-        mPaymentRequestTestRule.runJavaScriptAndWaitForUIEvent(
-                "buyWithMethods([{supportedMethods: 'https://bobpay.test'}]);",
-                mPaymentRequestTestRule.getReadyForInput());
-        mPaymentRequestTestRule.clickAndWait(
-                R.id.close_button, mPaymentRequestTestRule.getDismissed());
-        mPaymentRequestTestRule.expectResultContains(
-                new String[] {"User closed the Payment Request UI."});
-
-        // Make sure the events were logged correctly.
-        histogramWatcher.pollInstrumentationThreadUntilSatisfied();
-    }
-
-    /**
      * Expect that that the journey metrics are logged correctly on a second consecutive payment
      * request.
      */
@@ -297,19 +128,16 @@
 
         // Make sure the events were logged correctly.
         int expectedSample =
-                Event.SHOWN
-                        | Event.COMPLETED
-                        | Event.REQUEST_SHIPPING
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.RECEIVED_INSTRUMENT_DETAILS
-                        | Event.PAY_CLICKED
-                        | Event.AVAILABLE_METHOD_OTHER
-                        | Event.SELECTED_OTHER;
+                Event2.SHOWN
+                        | Event2.COMPLETED
+                        | Event2.REQUEST_SHIPPING
+                        | Event2.REQUEST_METHOD_OTHER
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.PAY_CLICKED
+                        | Event2.SELECTED_OTHER;
         Assert.assertEquals(
                 2,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMetricsTest.java
index 6ff9427..0f876f7f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMetricsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMetricsTest.java
@@ -26,7 +26,7 @@
 import org.chromium.chrome.test.R;
 import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.components.autofill.AutofillProfile;
-import org.chromium.components.payments.Event;
+import org.chromium.components.payments.Event2;
 import org.chromium.components.payments.PaymentFeatureList;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 
@@ -96,20 +96,17 @@
 
         // Make sure the events were logged correctly.
         int expectedSample =
-                Event.SHOWN
-                        | Event.PAY_CLICKED
-                        | Event.RECEIVED_INSTRUMENT_DETAILS
-                        | Event.COMPLETED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_SHIPPING
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.SELECTED_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER;
+                Event2.SHOWN
+                        | Event2.PAY_CLICKED
+                        | Event2.COMPLETED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_SHIPPING
+                        | Event2.REQUEST_METHOD_OTHER
+                        | Event2.SELECTED_OTHER;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 
     /**
@@ -157,17 +154,15 @@
 
         // Make sure the events were logged correctly.
         int expectedSample =
-                Event.SHOWN
-                        | Event.USER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_SHIPPING
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER;
+                Event2.SHOWN
+                        | Event2.USER_ABORTED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_SHIPPING
+                        | Event2.REQUEST_METHOD_OTHER;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 
     /**
@@ -195,17 +190,15 @@
 
         // Make sure the events were logged correctly.
         int expectedSample =
-                Event.SHOWN
-                        | Event.USER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_SHIPPING
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER;
+                Event2.SHOWN
+                        | Event2.USER_ABORTED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_SHIPPING
+                        | Event2.REQUEST_METHOD_OTHER;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 
     /**
@@ -239,17 +232,15 @@
 
         // Make sure the events were logged correctly.
         int expectedSample =
-                Event.SHOWN
-                        | Event.USER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_SHIPPING
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER;
+                Event2.SHOWN
+                        | Event2.USER_ABORTED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_SHIPPING
+                        | Event2.REQUEST_METHOD_OTHER;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 
     /**
@@ -275,17 +266,15 @@
 
         // Make sure the events were logged correctly.
         int expectedSample =
-                Event.SHOWN
-                        | Event.USER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_SHIPPING
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER;
+                Event2.SHOWN
+                        | Event2.USER_ABORTED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_SHIPPING
+                        | Event2.REQUEST_METHOD_OTHER;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 
     /**
@@ -311,17 +300,15 @@
 
         // Make sure the events were logged correctly.
         int expectedSample =
-                Event.SHOWN
-                        | Event.OTHER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_SHIPPING
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER;
+                Event2.SHOWN
+                        | Event2.OTHER_ABORTED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_SHIPPING
+                        | Event2.REQUEST_METHOD_OTHER;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 
     /**
@@ -345,14 +332,11 @@
 
         // Make sure the events were logged correctly.
         int expectedSample =
-                Event.REQUEST_SHIPPING
-                        | Event.REQUEST_METHOD_GOOGLE
-                        | Event.COULD_NOT_SHOW
-                        | Event.NEEDS_COMPLETION_PAYMENT;
+                Event2.REQUEST_SHIPPING | Event2.REQUEST_METHOD_GOOGLE | Event2.COULD_NOT_SHOW;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 
     /**
@@ -373,20 +357,17 @@
 
         // Make sure the events were logged correctly.
         int expectedSample =
-                Event.SHOWN
-                        | Event.PAY_CLICKED
-                        | Event.RECEIVED_INSTRUMENT_DETAILS
-                        | Event.COMPLETED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_METHOD_GOOGLE
-                        | Event.SELECTED_GOOGLE
-                        | Event.REQUEST_SHIPPING
-                        | Event.AVAILABLE_METHOD_GOOGLE;
+                Event2.SHOWN
+                        | Event2.PAY_CLICKED
+                        | Event2.COMPLETED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_METHOD_GOOGLE
+                        | Event2.SELECTED_GOOGLE
+                        | Event2.REQUEST_SHIPPING;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 
     /**
@@ -405,19 +386,16 @@
 
         // Make sure the events were logged correctly.
         int expectedSample =
-                Event.SKIPPED_SHOW
-                        | Event.PAY_CLICKED
-                        | Event.RECEIVED_INSTRUMENT_DETAILS
-                        | Event.COMPLETED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_METHOD_GOOGLE
-                        | Event.SELECTED_GOOGLE
-                        | Event.AVAILABLE_METHOD_GOOGLE;
+                Event2.SKIPPED_SHOW
+                        | Event2.PAY_CLICKED
+                        | Event2.COMPLETED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_METHOD_GOOGLE
+                        | Event2.SELECTED_GOOGLE;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 
     /**
@@ -445,16 +423,14 @@
 
         // Make sure the events were logged correctly.
         int expectedSample =
-                Event.SHOWN
-                        | Event.USER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_METHOD_GOOGLE
-                        | Event.AVAILABLE_METHOD_GOOGLE;
+                Event2.SHOWN
+                        | Event2.USER_ABORTED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_METHOD_GOOGLE;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 
     /**
@@ -495,15 +471,14 @@
 
         // Make sure the events were logged correctly.
         int expectedSample =
-                Event.SHOWN
-                        | Event.USER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_METHOD_BASIC_CARD
-                        | Event.SELECTED_CREDIT_CARD;
+                Event2.SHOWN
+                        | Event2.USER_ABORTED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_METHOD_BASIC_CARD
+                        | Event2.SELECTED_CREDIT_CARD;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameAndFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameAndFreeShippingTest.java
index aa6f4f13..1e881bac 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameAndFreeShippingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameAndFreeShippingTest.java
@@ -22,7 +22,7 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.R;
 import org.chromium.components.autofill.AutofillProfile;
-import org.chromium.components.payments.Event;
+import org.chromium.components.payments.Event2;
 import org.chromium.ui.modaldialog.ModalDialogProperties;
 
 import java.util.concurrent.TimeoutException;
@@ -122,17 +122,15 @@
                 new String[] {"User closed the Payment Request UI."});
 
         int expectedSample =
-                Event.SHOWN
-                        | Event.USER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_SHIPPING
-                        | Event.REQUEST_PAYER_NAME
-                        | Event.REQUEST_METHOD_BASIC_CARD
-                        | Event.AVAILABLE_METHOD_BASIC_CARD;
+                Event2.SHOWN
+                        | Event2.USER_ABORTED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_SHIPPING
+                        | Event2.REQUEST_PAYER_DATA
+                        | Event2.REQUEST_METHOD_BASIC_CARD;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameTest.java
index 7dcd2d7..d304200 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNameTest.java
@@ -23,7 +23,7 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.R;
 import org.chromium.components.autofill.AutofillProfile;
-import org.chromium.components.payments.Event;
+import org.chromium.components.payments.Event2;
 
 import java.util.concurrent.TimeoutException;
 
@@ -209,19 +209,16 @@
     @Feature({"Payments"})
     public void testPaymentRequestEventsMetric() throws TimeoutException {
         int expectedSample =
-                Event.SHOWN
-                        | Event.PAY_CLICKED
-                        | Event.RECEIVED_INSTRUMENT_DETAILS
-                        | Event.COMPLETED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_PAYER_NAME
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.SELECTED_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER;
+                Event2.SHOWN
+                        | Event2.PAY_CLICKED
+                        | Event2.COMPLETED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_PAYER_DATA
+                        | Event2.REQUEST_METHOD_OTHER
+                        | Event2.SELECTED_OTHER;
         var histogramWatcher =
                 HistogramWatcher.newBuilder()
-                        .expectIntRecord("PaymentRequest.Events", expectedSample)
+                        .expectIntRecord("PaymentRequest.Events2", expectedSample)
                         .build();
 
         // Start and complete the Payment Request.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java
index 02d9b77f..f9b8b40 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java
@@ -22,7 +22,7 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.R;
 import org.chromium.components.autofill.AutofillProfile;
-import org.chromium.components.payments.Event;
+import org.chromium.components.payments.Event2;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 
 import java.util.concurrent.TimeoutException;
@@ -244,15 +244,13 @@
                 mPaymentRequestTestRule.runJavaScriptAndWaitForPromise("getResult()"));
 
         int expectedSample =
-                Event.SHOWN
-                        | Event.USER_ABORTED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER;
+                Event2.SHOWN
+                        | Event2.USER_ABORTED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_METHOD_OTHER;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppUiSkipTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppUiSkipTest.java
index 895f203..4a13940 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppUiSkipTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppUiSkipTest.java
@@ -20,7 +20,7 @@
 import org.chromium.chrome.browser.payments.PaymentRequestTestRule.FactorySpeed;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.R;
-import org.chromium.components.payments.Event;
+import org.chromium.components.payments.Event2;
 import org.chromium.components.payments.PaymentFeatureList;
 
 import java.util.concurrent.TimeoutException;
@@ -121,16 +121,13 @@
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events",
-                        Event.REQUEST_METHOD_OTHER
-                                | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                                | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                                | Event.SKIPPED_SHOW
-                                | Event.AVAILABLE_METHOD_OTHER
-                                | Event.SELECTED_OTHER
-                                | Event.PAY_CLICKED
-                                | Event.RECEIVED_INSTRUMENT_DETAILS
-                                | Event.COMPLETED));
+                        "PaymentRequest.Events2",
+                        Event2.REQUEST_METHOD_OTHER
+                                | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                                | Event2.SKIPPED_SHOW
+                                | Event2.SELECTED_OTHER
+                                | Event2.PAY_CLICKED
+                                | Event2.COMPLETED));
     }
 
     /** Two payments apps with the same payment method name should not skip payments UI. */
@@ -156,15 +153,12 @@
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events",
-                        Event.REQUEST_METHOD_OTHER
-                                | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                                | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                                | Event.SHOWN
-                                | Event.AVAILABLE_METHOD_OTHER
-                                | Event.SELECTED_OTHER
-                                | Event.PAY_CLICKED
-                                | Event.RECEIVED_INSTRUMENT_DETAILS
-                                | Event.COMPLETED));
+                        "PaymentRequest.Events2",
+                        Event2.REQUEST_METHOD_OTHER
+                                | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                                | Event2.SHOWN
+                                | Event2.SELECTED_OTHER
+                                | Event2.PAY_CLICKED
+                                | Event2.COMPLETED));
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneAndFreeShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneAndFreeShippingTest.java
index 377c9c78..6c771ab 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneAndFreeShippingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPhoneAndFreeShippingTest.java
@@ -22,7 +22,7 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.R;
 import org.chromium.components.autofill.AutofillProfile;
-import org.chromium.components.payments.Event;
+import org.chromium.components.payments.Event2;
 
 import java.util.concurrent.TimeoutException;
 
@@ -114,20 +114,17 @@
                 });
 
         int expectedSample =
-                Event.SHOWN
-                        | Event.PAY_CLICKED
-                        | Event.RECEIVED_INSTRUMENT_DETAILS
-                        | Event.COMPLETED
-                        | Event.HAD_INITIAL_FORM_OF_PAYMENT
-                        | Event.HAD_NECESSARY_COMPLETE_SUGGESTIONS
-                        | Event.REQUEST_PAYER_PHONE
-                        | Event.REQUEST_SHIPPING
-                        | Event.REQUEST_METHOD_OTHER
-                        | Event.AVAILABLE_METHOD_OTHER
-                        | Event.SELECTED_OTHER;
+                Event2.SHOWN
+                        | Event2.PAY_CLICKED
+                        | Event2.COMPLETED
+                        | Event2.HAD_INITIAL_FORM_OF_PAYMENT
+                        | Event2.REQUEST_PAYER_DATA
+                        | Event2.REQUEST_SHIPPING
+                        | Event2.REQUEST_METHOD_OTHER
+                        | Event2.SELECTED_OTHER;
         Assert.assertEquals(
                 1,
                 RecordHistogram.getHistogramValueCountForTesting(
-                        "PaymentRequest.Events", expectedSample));
+                        "PaymentRequest.Events2", expectedSample));
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java
index 8d60fe7..7160c49 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java
@@ -104,6 +104,7 @@
 import org.chromium.components.signin.base.CoreAccountInfo;
 import org.chromium.components.signin.identitymanager.ConsentLevel;
 import org.chromium.components.signin.identitymanager.IdentityManager;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.content_public.browser.test.NativeLibraryTestUtils;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.test.util.BlankUiTestActivity;
@@ -332,9 +333,12 @@
     @Restriction({DeviceRestriction.RESTRICTION_TYPE_NON_AUTO})
     public void testFragmentWithDefaultAccount() {
         mSigninTestRule.addAccount(TEST_EMAIL1, FULL_NAME1, GIVEN_NAME1, null);
-
+        HistogramWatcher accountStartedHistogram =
+                HistogramWatcher.newSingleRecordWatcher(
+                        "Signin.SignIn.Started", SigninAccessPoint.START_PAGE);
         launchActivityWithFragment();
 
+        accountStartedHistogram.assertExpected();
         checkFragmentWithSelectedAccount(TEST_EMAIL1, FULL_NAME1, GIVEN_NAME1);
         onView(withId(R.id.fre_browser_managed_by)).check(matches(not(isDisplayed())));
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/UpgradePromoIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/UpgradePromoIntegrationTest.java
index e2190ae..e8029355 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/UpgradePromoIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/UpgradePromoIntegrationTest.java
@@ -57,6 +57,7 @@
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.DoNotBatch;
 import org.chromium.base.test.util.Features;
+import org.chromium.base.test.util.HistogramWatcher;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
@@ -71,6 +72,7 @@
 import org.chromium.components.browser_ui.styles.SemanticColorUtils;
 import org.chromium.components.policy.test.annotations.Policies;
 import org.chromium.components.signin.identitymanager.ConsentLevel;
+import org.chromium.components.signin.metrics.AccountConsistencyPromoAction;
 import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.content_public.browser.test.NativeLibraryTestUtils;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
@@ -121,6 +123,19 @@
     @Test
     @MediumTest
     public void testWithExistingAccount_refuseSignin() {
+        HistogramWatcher accountConsistencyHistogram =
+                HistogramWatcher.newBuilder()
+                        .expectIntRecords(
+                                "Signin.AccountConsistencyPromoAction",
+                                AccountConsistencyPromoAction.SHOWN)
+                        .expectIntRecord(
+                                "Signin.AccountConsistencyPromoAction.Shown",
+                                SigninAccessPoint.SIGNIN_PROMO)
+                        .build();
+        HistogramWatcher accountStartedHistogram =
+                HistogramWatcher.newSingleRecordWatcher(
+                        "Signin.SignIn.Started", SigninAccessPoint.SIGNIN_PROMO);
+
         launchActivity();
 
         // Verify that the fullscreen sign-in promo is shown.
@@ -130,6 +145,8 @@
         // Refuse sign-in.
         clickButton(R.id.signin_fre_dismiss_button);
 
+        accountConsistencyHistogram.assertExpected();
+        accountStartedHistogram.assertExpected();
         ApplicationTestUtils.waitForActivityState(mActivity, Stage.DESTROYED);
         assertNull(mSigninTestRule.getPrimaryAccount(ConsentLevel.SIGNIN));
         assertFalse(SyncTestUtil.isHistorySyncEnabled());
@@ -245,23 +262,23 @@
                 mActivity, Configuration.ORIENTATION_LANDSCAPE);
 
         // Verify that the view switcher is displayed with the correct layout.
+        onView(withId(R.id.fullscreen_signin)).check(matches(isDisplayed()));
         if (DeviceFormFactor.isNonMultiDisplayContextOnTablet(mActivity)) {
             onView(withId(R.id.upgrade_promo_portrait)).check(matches(isDisplayed()));
         } else {
-            onView(withId(R.id.upgrade_promo_landscape)).check(matches(isDisplayed()));
+            onViewWaiting(withId(R.id.upgrade_promo_landscape)).check(matches(isDisplayed()));
         }
-        onView(withId(R.id.fullscreen_signin)).check(matches(isDisplayed()));
 
         // Sign in.
         onView(withId(R.id.signin_fre_continue_button)).perform(click());
 
-        // Verify that the view switcher is displayed with the correct layout.
+        // Verify that the view is displayed with the correct layout.
+        onView(withId(R.id.history_sync)).check(matches(isDisplayed()));
         if (DeviceFormFactor.isNonMultiDisplayContextOnTablet(mActivity)) {
             onView(withId(R.id.upgrade_promo_portrait)).check(matches(isDisplayed()));
         } else {
             onView(withId(R.id.upgrade_promo_landscape)).check(matches(isDisplayed()));
         }
-        onView(withId(R.id.history_sync)).check(matches(isDisplayed()));
 
         // Rotate the screen back.
         ActivityTestUtils.rotateActivityToOrientation(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/test/smoke/AndroidManifest.xml b/chrome/android/javatests/src/org/chromium/chrome/test/smoke/AndroidManifest.xml
index f22970d..2052a4c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/test/smoke/AndroidManifest.xml
+++ b/chrome/android/javatests/src/org/chromium/chrome/test/smoke/AndroidManifest.xml
@@ -7,10 +7,6 @@
 <manifest
       xmlns:android="http://schemas.android.com/apk/res/android"
       package="org.chromium.chrome.test.smoke">
-
-    <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
     <instrumentation android:name="org.chromium.base.test.BaseChromiumAndroidJUnitRunner"
         android:targetPackage="org.chromium.chrome.test.smoke"
         android:label="Runner for org.chromium.chrome.test.smoke"/>
diff --git a/chrome/android/javatests/src/org/chromium/chrome/test/smoke/AndroidManifest_bundle.xml b/chrome/android/javatests/src/org/chromium/chrome/test/smoke/AndroidManifest_bundle.xml
index d0330d5..46b013a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/test/smoke/AndroidManifest_bundle.xml
+++ b/chrome/android/javatests/src/org/chromium/chrome/test/smoke/AndroidManifest_bundle.xml
@@ -8,14 +8,6 @@
       xmlns:android="http://schemas.android.com/apk/res/android"
       package="org.chromium.chrome.test.smoke.bundle">
 
-    <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
-    <!-- Explicitly set the attribute requestLegacyExternalStorage to "true"
-         since it is "false" by default on apps targeting Android Q. -->
-    <application android:requestLegacyExternalStorage="true">
-    </application>
-
     <instrumentation android:name="org.chromium.base.test.BaseChromiumAndroidJUnitRunner"
         android:targetPackage="org.chromium.chrome.test.smoke.bundle"
         android:label="Runner for org.chromium.chrome.test.smoke.bundle"/>
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ContextMenuCoordinatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ContextMenuCoordinatorTest.java
index b2cc202..cf54fa2 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ContextMenuCoordinatorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ContextMenuCoordinatorTest.java
@@ -48,6 +48,7 @@
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.components.browser_ui.widget.ContextMenuDialog;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuNativeDelegate;
 import org.chromium.components.embedder_support.contextmenu.ContextMenuParams;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.content_public.common.ContentFeatures;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ContextMenuHeaderMediatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ContextMenuHeaderMediatorTest.java
index 2789d7c..f69a545b 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ContextMenuHeaderMediatorTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/contextmenu/ContextMenuHeaderMediatorTest.java
@@ -32,6 +32,7 @@
 import org.chromium.base.test.util.JniMocker;
 import org.chromium.blink_public.common.ContextMenuDataMediaType;
 import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuNativeDelegate;
 import org.chromium.components.embedder_support.contextmenu.ContextMenuParams;
 import org.chromium.components.favicon.LargeIconBridge;
 import org.chromium.components.favicon.LargeIconBridgeJni;
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index 2805028..70a1a66 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -1728,7 +1728,8 @@
 
 #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
   // Zygote needs to call InitCrashReporter() in RunZygote().
-  if (process_type != switches::kZygoteProcess) {
+  if (process_type != switches::kZygoteProcess &&
+      !command_line.HasSwitch(switches::kDisableCrashpadForTesting)) {
     if (command_line.HasSwitch(switches::kPreCrashpadCrashTest)) {
       // Crash for the purposes of testing the handling of crashes that happen
       // before crashpad is initialized. Please leave this check immediately
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index 50bd6918..75994c19 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -729,14 +729,6 @@
          desc="Message shown to the user to validate the download when the download content is classified to lead to malware by safebrowsing.">
         <ph name="FILE_NAME">$1<ex>malware.exe</ex></ph> is dangerous, so Chromium has blocked it.
       </message>
-      <message name="IDS_BLOCK_REASON_DANGEROUS_DOWNLOAD"
-         desc="Message shown to the user on chrome://downloads page to explain that this download is blocked because it is malware.">
-        This file is dangerous, so Chromium has blocked it.
-      </message>
-      <message name="IDS_BLOCK_REASON_UNWANTED_DOWNLOAD"
-         desc="Message shown to the user on chrome://downloads page to explain that this download is blocked because it is unwanted sofware.">
-        This file may be dangerous, so Chromium has blocked it.
-      </message>
       <message name="IDS_BLOCK_REASON_PROMPT_FOR_SCANNING"
          desc="Message shown to the user on chrome://downloads page to explain that this download is recommended to be scanned.">
         Chromium recommends scanning this file because it may be dangerous.
@@ -1131,6 +1123,11 @@
           </message>
         </if>
 
+        <message name="IDS_SIGNIN_CONTINUE_AS_BUTTON_ACCESSIBILITY_LABEL"
+          desc="Label of the 'Continue as' button of Chromium Signin promos">
+          Sign in to Chromium as <ph name="USER_EMAIL">$1<ex>john@google.com</ex></ph>
+        </message>
+
         <!-- Autofill Sign In Promo Bubble -->
         <message name="IDS_AUTOFILL_SIGNIN_PROMO_SUBTITLE_PASSWORD" desc="This is the body text of a confirmation message and means that the password was only saved locally to the user's device (not in their Google Account). It appears when the user is not signed in to Chromium and is after the 'Password saved to this device' string. If the user wants to save this data to their Google Account, they can click the 'Sign in to Chromium' button at the bottom of this message. The tone should be motivating.">
           To save and use passwords and more on all your devices, sign in to Chromium. This password will be saved in your Google Account after you sign in.
diff --git a/chrome/app/chromium_strings_grd/IDS_BLOCK_REASON_DANGEROUS_DOWNLOAD_IN_ADVANCED_PROTECTION.png.sha1 b/chrome/app/chromium_strings_grd/IDS_BLOCK_REASON_DANGEROUS_DOWNLOAD_IN_ADVANCED_PROTECTION.png.sha1
deleted file mode 100644
index 7ff0038c..0000000
--- a/chrome/app/chromium_strings_grd/IDS_BLOCK_REASON_DANGEROUS_DOWNLOAD_IN_ADVANCED_PROTECTION.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-5c865831385d99ae49626bef0555a4d78e58dd49
\ No newline at end of file
diff --git a/chrome/app/chromium_strings_grd/IDS_BLOCK_REASON_UNWANTED_DOWNLOAD_IN_ADVANCED_PROTECTION.png.sha1 b/chrome/app/chromium_strings_grd/IDS_BLOCK_REASON_UNWANTED_DOWNLOAD_IN_ADVANCED_PROTECTION.png.sha1
deleted file mode 100644
index a38e3d06..0000000
--- a/chrome/app/chromium_strings_grd/IDS_BLOCK_REASON_UNWANTED_DOWNLOAD_IN_ADVANCED_PROTECTION.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-e71305276bd714642fb5775005f8af8a5c060fd9
\ No newline at end of file
diff --git a/chrome/app/chromium_strings_grd/IDS_SIGNIN_CONTINUE_AS_BUTTON_ACCESSIBILITY_LABEL.png.sha1 b/chrome/app/chromium_strings_grd/IDS_SIGNIN_CONTINUE_AS_BUTTON_ACCESSIBILITY_LABEL.png.sha1
new file mode 100644
index 0000000..138931a
--- /dev/null
+++ b/chrome/app/chromium_strings_grd/IDS_SIGNIN_CONTINUE_AS_BUTTON_ACCESSIBILITY_LABEL.png.sha1
@@ -0,0 +1 @@
+f7c9b6eaabc6ad381178775fa026a616e6f37ff7
\ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index d0c7c26..8ba0e7b 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -2317,22 +2317,10 @@
         desc="Message shown in the download shelf for all Advanced Protection and Enhanced Safe Browsing users when Chrome recommends uploading the file for additional scanning.">
         <ph name="FILE_NAME">$1<ex>bla.exe</ex></ph> may be dangerous. Send to Google for scanning?
       </message>
-      <message name="IDS_BLOCK_REASON_UNCOMMON_DOWNLOAD"
-         desc="Message shown to the user on chrome://downloads page to explain that this download is blocked because it is uncommon.">
-        This file is not commonly downloaded and may be dangerous.
-      </message>
       <message name="IDS_BLOCK_REASON_UNCOMMON_DOWNLOAD_IN_ADVANCED_PROTECTION"
          desc="Message shown to the user on chrome://downloads page to explain that this download is blocked because it is uncommon. This variant is shown when the user is enrolled in the Advanced Protection program.">
         This file was blocked by Advanced Protection.
       </message>
-      <message name="IDS_BLOCK_REASON_GENERIC_DOWNLOAD"
-         desc="Message shown to the user on chrome://downloads page to explain that this download is blocked because it may be dangerous.">
-        This type of file may harm your computer.
-      </message>
-      <message name="IDS_BLOCK_REASON_INSECURE_DOWNLOAD"
-         desc="Message shown to the user on chrome://downloads page to explain that this download is blocked because it was insecurely delivered.">
-        This file can't be downloaded securely
-      </message>
       <message name="IDS_BLOCK_REASON_DEEP_SCANNING_UPDATED"
           desc="Message shown on chrome://downloads when a download is being scanned">
         This file might be a virus or malware. You can send it to Google to check if it's unsafe.
@@ -2416,10 +2404,6 @@
           Keep
         </message>
       </if>
-      <message name="IDS_CONFIRM_DOWNLOAD_RESTORE"
-               desc="Text for the button used to validate the downloading of a dangerous download on chrome://downloads page.">
-        Keep dangerous file
-      </message>
       <message name="IDS_CONTINUE_EXTENSION_DOWNLOAD"
                desc="Text for the button used to validate the installation of an extension.">
         Continue
@@ -2463,14 +2447,6 @@
                desc="In the download view, 'Resume' link text">
         Resume
       </message>
-      <message name="IDS_DOWNLOAD_LINK_REMOVE"
-               desc="In the download view, 'Remove from list' link text">
-        Remove from list
-      </message>
-      <message name="IDS_DOWNLOAD_LINK_REMOVE_ARIA_LABEL"
-               desc="In the download view, 'Remove from list' link aria-label">
-        Remove <ph name="FILE_NAME">$1<ex>somedocument.pdf</ex></ph> from list
-      </message>
       <message name="IDS_DOWNLOAD_LINK_CANCEL"
                desc="In the download view, 'Cancel' link text">
         Cancel
@@ -2552,9 +2528,6 @@
       <message name="IDS_DOWNLOAD_UNDO" desc="Menu title for undoing an operation">
         Undo
       </message>
-      <message name="IDS_DOWNLOAD_TOAST_REMOVED_FROM_LIST" desc="Toast message for removing download entry from list">
-        Removed '<ph name="FILE_NAME">$1<ex>somedocument.pdf</ex></ph>' from list
-      </message>
       <message name="IDS_DOWNLOAD_TOAST_CLEARED_ALL" desc="Toast message for clearing all download entries">
         Cleared all
       </message>
@@ -2570,10 +2543,6 @@
                desc="In the download view, the 'Open' button when prompt for deep scan">
         Open
       </message>
-      <message name="IDS_DOWNLOAD_BYPASS_DEEP_SCAN_UPDATED"
-               desc="In the download view, the 'Open' button when prompt for deep scan">
-        Open anyway
-      </message>
       <message name="IDS_DOWNLOAD_LOCAL_PASSWORD_SCAN"
         desc="On the downloads page, the label for the button to check a download for malware">
         Check for malware
@@ -4716,7 +4685,10 @@
 
       <!-- DevTools shared process infobar -->
       <message name="IDS_DEV_TOOLS_SHARED_PROCESS_INFOBAR" desc="Label displayed in an infobar when the tab being debugged is run in a process that hosts multiple tabs. The label does not disappear until the user dismisses it or closes the debugger.">
-        Other tabs share a process with this tab, which may result in an unexpected DevTools experience.
+        This tab shares resources with other tabs, which could interfere with debugging.
+      </message>
+      <message name="IDS_DEV_TOOLS_SHARED_PROCESS_INFOBAR_LEARN_MORE" desc="Used as 'Learn More' link text.">
+        Learn More
       </message>
 
       <!-- DevTools attached infobar -->
@@ -8707,6 +8679,12 @@
       <message name="IDS_NTP_MODULES_MOST_RELEVANT_TAB_RESUMPTION_DISMISS_BUTTON" desc="A label for the dismiss button in the dropdown.">
         Hide these tabs
       </message>
+      <message name="IDS_NTP_MODULES_MOST_RELEVANT_TAB_RESUMPTION_TITLE" desc="Title for the most relevant tab resumption module.">
+        Continue with these tabs
+      </message>
+      <message name="IDS_NTP_MODULES_MOST_RELEVANT_TAB_RESUMPTION_SEE_MORE" desc="A label for the see more button in the most relevant tab resumption module.">
+        See more
+      </message>
 
       <!-- Extensions NTP Middle Slot Promo -->
       <message name="IDS_EXTENSIONS_PROMO_PERFORMANCE">
@@ -16274,7 +16252,7 @@
          Choose which device has the passkey for <ph name="APP_NAME">$1<ex>example.com</ex></ph>
       </message>
       <message name="IDS_WEBAUTHN_USE_PASSKEY_TITLE" desc="The title of a dialog prompting the user to use a passkey for signing into a website. Refer to Glossary for the meaning of 'passkey'; do not translate it as 'password'.">
-         Use your passkey for <ph name="APP_NAME">$1<ex>example.com</ex></ph>
+         Use a saved passkey for <ph name="APP_NAME">$1<ex>example.com</ex></ph>
       </message>
       <message name="IDS_WEBAUTHN_CHOOSE_PASSKEY_TITLE" desc="The title of a dialog prompting the user to choose a passkey from a list to sign into a website. Refer to Glossary for the meaning of 'passkey'; do not translate it as 'password'.">
          Choose a passkey
@@ -16428,7 +16406,7 @@
         Create a new PIN for Google Password Manager
       </message>
       <message name="IDS_WEBAUTHN_GPM_CREATE_PIN_TITLE" desc="The title of a dialog that is shown when a user is creating a Google Password Manager PIN for the first time. Refer to Glossary for the meaning of 'passkey'; do not translate it as 'password'">
-        Next, protect all your passkeys with a recovery PIN
+        Protect all your passkeys with a recovery PIN
       </message>
       <message name="IDS_WEBAUTHN_GPM_CREATE_PIN_DESC" desc="The description of a dialog that is shown when a user is creating a Google Password Manager PIN explaining that it will be used to access their passkeys on all devices. Refer to Glossary for the meaning of 'passkey'; do not translate it as 'password'">
         A recovery PIN helps you access your saved passkeys on any device
@@ -17559,19 +17537,25 @@
         </message>
       </if>
       <if expr="not use_titlecase">
-        <message name="IDS_PERFORMANCE_INTERVENTION_DEACTIVATE_TABS_BUTTON_V1" desc="In Title Case: Label on a dialog button that deactivate the specified tabs in the dialog when clicked.">
+        <message name="IDS_PERFORMANCE_INTERVENTION_DEACTIVATE_TABS_BUTTON_V1" desc="Label on a dialog button that deactivate the specified tabs in the dialog when clicked.">
         Fix now
         </message>
-        <message name="IDS_PERFORMANCE_INTERVENTION_DEACTIVATE_TABS_BUTTON_V2" desc="In Title Case: Label on a dialog button that deactivate the specified tabs in the dialog when clicked.">
+        <message name="IDS_PERFORMANCE_INTERVENTION_DEACTIVATE_TABS_BUTTON_V2" desc="Label on a dialog button that deactivate the specified tabs in the dialog when clicked.">
         Boost now
         </message>
-        <message name="IDS_PERFORMANCE_INTERVENTION_DEACTIVATE_TABS_BUTTON_V3" desc="In Title Case: Label on a dialog button that deactivate the specified tabs in the dialog when clicked.">
+        <message name="IDS_PERFORMANCE_INTERVENTION_DEACTIVATE_TABS_BUTTON_V3" desc="Label on a dialog button that deactivate the specified tabs in the dialog when clicked.">
         Make tabs inactive
         </message>
       </if>
       <message name="IDS_PERFORMANCE_INTERVENTION_DISMISS_BUTTON" desc="Label on a dialog button that dismisses the dialog when clicked.">
         Dismiss
       </message>
+      <message name="IDS_PERFORMANCE_INTERVENTION_BUTTON_TOOLTIP" desc="The tooltip for the performance intervention toolbar button">
+        Perfomance issue alert
+      </message>
+      <message name="IDS_PERFORMANCE_INTERVENTION_BUTTON_ACCNAME" desc="The accessibility text for the performance intervention toolbar button">
+        Performance issue alert
+      </message>
     </if>
     <message name="IDS_ACCNAME_SIDEBAR_WEBVIEW_LOCATION_BAR" desc="The accessible name of the sidebar webview's location bar.">
       Location
diff --git a/chrome/app/generated_resources_grd/IDS_BLOCK_REASON_INSECURE_DOWNLOAD.png.sha1 b/chrome/app/generated_resources_grd/IDS_BLOCK_REASON_INSECURE_DOWNLOAD.png.sha1
deleted file mode 100644
index 233c35e..0000000
--- a/chrome/app/generated_resources_grd/IDS_BLOCK_REASON_INSECURE_DOWNLOAD.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-683025d5bf752c22833ad5a72455ea9a201f836c
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_BLOCK_REASON_UNCOMMON_DOWNLOAD.png.sha1 b/chrome/app/generated_resources_grd/IDS_BLOCK_REASON_UNCOMMON_DOWNLOAD.png.sha1
deleted file mode 100644
index 1bb62e0..0000000
--- a/chrome/app/generated_resources_grd/IDS_BLOCK_REASON_UNCOMMON_DOWNLOAD.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-bd35a8ce716bc11c39b7368e93758f01e61c1496
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DEV_TOOLS_SHARED_PROCESS_INFOBAR.png.sha1 b/chrome/app/generated_resources_grd/IDS_DEV_TOOLS_SHARED_PROCESS_INFOBAR.png.sha1
index b989231..b630098b 100644
--- a/chrome/app/generated_resources_grd/IDS_DEV_TOOLS_SHARED_PROCESS_INFOBAR.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_DEV_TOOLS_SHARED_PROCESS_INFOBAR.png.sha1
@@ -1 +1 @@
-a03a173c6543d90a4fb2867a28cc66ef726536e1
\ No newline at end of file
+06881217050a06bbe444b6be8da81d13e95ffc19
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DEV_TOOLS_SHARED_PROCESS_INFOBAR_LEARN_MORE.png.sha1 b/chrome/app/generated_resources_grd/IDS_DEV_TOOLS_SHARED_PROCESS_INFOBAR_LEARN_MORE.png.sha1
new file mode 100644
index 0000000..b630098b
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_DEV_TOOLS_SHARED_PROCESS_INFOBAR_LEARN_MORE.png.sha1
@@ -0,0 +1 @@
+06881217050a06bbe444b6be8da81d13e95ffc19
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BYPASS_DEEP_SCAN_UPDATED.png.sha1 b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BYPASS_DEEP_SCAN_UPDATED.png.sha1
deleted file mode 100644
index 274fcd0..0000000
--- a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BYPASS_DEEP_SCAN_UPDATED.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-3e76f944408c6eb46ba13e4e30bbad5334a54571
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_MOST_RELEVANT_TAB_RESUMPTION_SEE_MORE.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_MOST_RELEVANT_TAB_RESUMPTION_SEE_MORE.png.sha1
new file mode 100644
index 0000000..2717523
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_MOST_RELEVANT_TAB_RESUMPTION_SEE_MORE.png.sha1
@@ -0,0 +1 @@
+1fd6d5a975022e924892b0e89261169c1bdead6b
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_MOST_RELEVANT_TAB_RESUMPTION_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_MOST_RELEVANT_TAB_RESUMPTION_TITLE.png.sha1
new file mode 100644
index 0000000..2717523
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_MOST_RELEVANT_TAB_RESUMPTION_TITLE.png.sha1
@@ -0,0 +1 @@
+1fd6d5a975022e924892b0e89261169c1bdead6b
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_PERFORMANCE_INTERVENTION_BUTTON_ACCNAME.png.sha1 b/chrome/app/generated_resources_grd/IDS_PERFORMANCE_INTERVENTION_BUTTON_ACCNAME.png.sha1
new file mode 100644
index 0000000..efda1b5
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_PERFORMANCE_INTERVENTION_BUTTON_ACCNAME.png.sha1
@@ -0,0 +1 @@
+6ee293bf9938c7f88616c2f55b8501873d14ebb8
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_PERFORMANCE_INTERVENTION_BUTTON_TOOLTIP.png.sha1 b/chrome/app/generated_resources_grd/IDS_PERFORMANCE_INTERVENTION_BUTTON_TOOLTIP.png.sha1
new file mode 100644
index 0000000..efda1b5
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_PERFORMANCE_INTERVENTION_BUTTON_TOOLTIP.png.sha1
@@ -0,0 +1 @@
+6ee293bf9938c7f88616c2f55b8501873d14ebb8
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_WEBAUTHN_GPM_CREATE_PIN_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_WEBAUTHN_GPM_CREATE_PIN_TITLE.png.sha1
index 9a016974..5e73e56a 100644
--- a/chrome/app/generated_resources_grd/IDS_WEBAUTHN_GPM_CREATE_PIN_TITLE.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_WEBAUTHN_GPM_CREATE_PIN_TITLE.png.sha1
@@ -1 +1 @@
-e5d0cb4099c83226d6566ec7da7fd853e189bf92
\ No newline at end of file
+efbeae58211ba81b49542ff9b96ced5ecdb9d327
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_WEBAUTHN_USE_PASSKEY_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_WEBAUTHN_USE_PASSKEY_TITLE.png.sha1
index adbfbd7b..65dbf52f 100644
--- a/chrome/app/generated_resources_grd/IDS_WEBAUTHN_USE_PASSKEY_TITLE.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_WEBAUTHN_USE_PASSKEY_TITLE.png.sha1
@@ -1 +1 @@
-c8d39676519302a1e9bb5f5fbe5aa1ba0921c3af
\ No newline at end of file
+cffcb9792537664504ae9623deb103cc41bccbcb
\ No newline at end of file
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index efea622..8637c43 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -706,14 +706,6 @@
          desc="Message shown to the user to validate the download when the download content is classified to lead to malware by safebrowsing.">
         <ph name="FILE_NAME">$1<ex>malware.exe</ex></ph> is dangerous, so Chrome has blocked it.
       </message>
-      <message name="IDS_BLOCK_REASON_DANGEROUS_DOWNLOAD"
-         desc="Message shown to the user on chrome://downloads page to explain that this download is blocked because it is malware.">
-        This file is dangerous, so Chrome has blocked it.
-      </message>
-      <message name="IDS_BLOCK_REASON_UNWANTED_DOWNLOAD"
-         desc="Message shown to the user on chrome://downloads page to explain that this download is blocked because it is unwanted sofware.">
-        This file may be dangerous, so Chrome has blocked it.
-      </message>
       <message name="IDS_BLOCK_REASON_PROMPT_FOR_SCANNING"
          desc="Message shown to the user on chrome://downloads page to explain that this download is recommended to be scanned.">
         Chrome recommends scanning this file because it may be dangerous.
@@ -1085,6 +1077,11 @@
           </message>
         </if>
 
+         <message name="IDS_SIGNIN_CONTINUE_AS_BUTTON_ACCESSIBILITY_LABEL"
+          desc="Label of the 'Continue as' button of Chrome Signin promos. Spoken by screen readers when the button is focused.">
+          Sign in to Chrome as <ph name="USER_EMAIL">$1<ex>john@google.com</ex></ph>
+        </message>
+
         <!-- Autofill Sign In Promo Bubble -->
         <message name="IDS_AUTOFILL_SIGNIN_PROMO_SUBTITLE_PASSWORD"  desc="This is the body text of a confirmation message and means that the password was only saved locally to the user's device (not in their Google Account). It appears when the user is not signed in to Chrome and is after the 'Password saved to this device' string. If the user wants to save this data to their Google Account, they can click the 'Sign in to Chrome' button at the bottom of this message. The tone should be motivating.">
           To save and use passwords and more on all your devices, sign in to Chrome. This password will be saved in your Google Account after you sign in.
diff --git a/chrome/app/google_chrome_strings_grd/IDS_BLOCK_REASON_DANGEROUS_DOWNLOAD_IN_ADVANCED_PROTECTION.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_BLOCK_REASON_DANGEROUS_DOWNLOAD_IN_ADVANCED_PROTECTION.png.sha1
deleted file mode 100644
index c9dc4c0..0000000
--- a/chrome/app/google_chrome_strings_grd/IDS_BLOCK_REASON_DANGEROUS_DOWNLOAD_IN_ADVANCED_PROTECTION.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-d0737777f714f744ce780f8cbadeaa936a2d83b6
\ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_BLOCK_REASON_UNWANTED_DOWNLOAD_IN_ADVANCED_PROTECTION.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_BLOCK_REASON_UNWANTED_DOWNLOAD_IN_ADVANCED_PROTECTION.png.sha1
deleted file mode 100644
index a054aaa..0000000
--- a/chrome/app/google_chrome_strings_grd/IDS_BLOCK_REASON_UNWANTED_DOWNLOAD_IN_ADVANCED_PROTECTION.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-0baafa004c20bf074ebd2bafd80a196a7fa1b0ca
\ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_SIGNIN_CONTINUE_AS_BUTTON_ACCESSIBILITY_LABEL.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_SIGNIN_CONTINUE_AS_BUTTON_ACCESSIBILITY_LABEL.png.sha1
new file mode 100644
index 0000000..138931a
--- /dev/null
+++ b/chrome/app/google_chrome_strings_grd/IDS_SIGNIN_CONTINUE_AS_BUTTON_ACCESSIBILITY_LABEL.png.sha1
@@ -0,0 +1 @@
+f7c9b6eaabc6ad381178775fa026a616e6f37ff7
\ No newline at end of file
diff --git a/chrome/app/resources/chromium_strings_am.xtb b/chrome/app/resources/chromium_strings_am.xtb
index 5c8eaf7..f84cbf1a 100644
--- a/chrome/app/resources/chromium_strings_am.xtb
+++ b/chrome/app/resources/chromium_strings_am.xtb
@@ -118,6 +118,7 @@
 <translation id="2945997411976714835">የጭነት ስህተት፦ የጫኙ ሂደት መጀመር አልተሳካም።</translation>
 <translation id="2977470724722393594">Chromium የተዘመነ ነው</translation>
 <translation id="2977506796191543575">አንድ ጣቢያ የእርስዎን የይለፍ ቃል ለመስረቅ ከሞከረ ወይም ጎጂ ፋይል ሲያወርዱ Chromium እንዲሁም የገጽ ይዘት ቢትስንም ጨምሮ ዩአርኤሎችን ወደ የጥንቃቄ አሰሳ ሊልክ ይችላል</translation>
+<translation id="2987208172821108655">Chromium የአሰሳ ተሞክሮዎን ለማሻሻል እና ንብረቶችን ቦታ ለማስለቀቅ እነዚህን ትሮች ሊያቦዝናቸው ይችላል።</translation>
 <translation id="3013473503895162900"><ph name="URL" />ን በChromium ውስጥ በአዲስ ትር ይክፈቱ።</translation>
 <translation id="3032706164202344641">Chromium የእርስዎን የይለፍ ቃላት መፈተሽ አይችልም። ቆይተው እንደገና ይሞክሩ።</translation>
 <translation id="3032787606318309379">ወደ Chromium በማከል ላይ...</translation>
@@ -319,6 +320,7 @@
 <translation id="6248213926982192922">Chromium ነባሪውን አሳሽ ያድርጉ።</translation>
 <translation id="6266342355635466082">Chromium ዝማኔዎችን መፈተሽ አይችልም። የበይነመረብ ግንኙነትዎን ለመፈተሽ ይሞክሩ።</translation>
 <translation id="6268381023930128611">ከChromium ተዘግቶ ይውጣ?</translation>
+<translation id="6270547683008298381">እነዚህ ትሮች ተጨማሪ ንብረቶችን እየተጠቀሙ ነው። አፈፃፀምዎን ለማሻሻል Chromium እንዲያቦዝናቸው ይፍቀዱ።</translation>
 <translation id="6281746429495226318">የChromium መገለጫዎን ያብጁ</translation>
 <translation id="6290827346642914212">የChromium መገለጫዎን ይሰይሙ</translation>
 <translation id="6294831894865512704">አንድ ቅጥያ ወደ Chromium እንዲገቡ ይፈልጋል</translation>
@@ -327,6 +329,7 @@
 <translation id="6327105987658262776">ምንም ዝማኔ የለም።</translation>
 <translation id="6333502561965082103">ሌላ ሥርዓተ ክወና በChromium ላይ በሂደት ላይ ነው። እባክዎ ቆይተው እንደገና ይሞክሩ።</translation>
 <translation id="6334986366598267305">አሁን Chromiumን ከGoogle መለያዎ ጋር እና በተጋሩ ኮምፒውተሮች ላይ መጠቀም ይበልጥ ቀላል ነው።</translation>
+<translation id="633626832589656416">Chromium የአሰሳ ተሞክሮዎን ለማሻሻል እና ነገሮች ፍጥነት ኖሯቸው ለማቆየት እነዚህን ትሮች ሊያቦዝናቸው ይችላል።</translation>
 <translation id="6347933965114150440">የChromium አቋራጭ</translation>
 <translation id="6366160072964553914">ፋይሉ በተለምዶ ስላማይወርድ እና አደገኛ ሊሆን ስለሚችል Chromium ይህን ውርድ አግዷል</translation>
 <translation id="6373523479360886564">እርግጠኛ ነዎት Chromiumን ማራገፍ ይፈልጋሉ?</translation>
diff --git a/chrome/app/resources/chromium_strings_bn.xtb b/chrome/app/resources/chromium_strings_bn.xtb
index e0c8fcf..f902680 100644
--- a/chrome/app/resources/chromium_strings_bn.xtb
+++ b/chrome/app/resources/chromium_strings_bn.xtb
@@ -116,6 +116,7 @@
 <translation id="2945997411976714835">ইনস্টল সংক্রান্ত সমস্যা: ইনস্টলার প্রসেস শুরু করা যায়নি।</translation>
 <translation id="2977470724722393594">Chromium আপ-টু-ডেট আছে</translation>
 <translation id="2977506796191543575">যদি কোনও সাইট আপনার পাসওয়ার্ড চুরি করার চেষ্টা করে বা আপনি কোনও ক্ষতিকারক ফাইল ডাউনলোড করলে, Chromium, পৃষ্ঠার কিছু কন্টেন্ট সহ URL ও হয়ত Safe Browsing-এ পাঠাতে পারে</translation>
+<translation id="2987208172821108655">আপনার ব্রাউজ করার অভিজ্ঞতা উন্নত করার জন্য Chromium এইসব ট্যাব বন্ধ করে দিতে পারে, এর ফলে রিসোর্স কম ব্যবহার হবে।</translation>
 <translation id="3013473503895162900">Chromium-এর নতুন একটি ট্যাবে <ph name="URL" /> খুলুন।</translation>
 <translation id="3032706164202344641">Chromium আপনার পাসওয়ার্ড চেক করতে পারছে না। পরে আবার চেষ্টা করুন।</translation>
 <translation id="3032787606318309379">Chromium-এ জুড়ছে...</translation>
@@ -317,6 +318,7 @@
 <translation id="6248213926982192922">Chromium-কে ডিফল্ট ব্রাউজার করুন</translation>
 <translation id="6266342355635466082">কোনও আপডেট আছে কিনা, Chromium তা চেক করে দেখতে পারছে না। আপনার ইন্টারনেট কানেকশন চেক করে দেখে নিন।</translation>
 <translation id="6268381023930128611">Chromium থেকে সাইন-আউট করবেন?</translation>
+<translation id="6270547683008298381">এইসব ট্যাব অতিরিক্ত রিসোর্স ব্যবহার করছে। আপনার পারফর্ম্যান্স উন্নত করতে, Chromium-কে এগুলি বন্ধ করতে দিন।</translation>
 <translation id="6281746429495226318">আপনার Chromium প্রোফাইল কাস্টমাইজ করুন</translation>
 <translation id="6290827346642914212">আপনার Chromium প্রোফাইলের নাম লিখুন</translation>
 <translation id="6294831894865512704">এক্সটেনশন ব্যবহার করতে Chromium-এ সাইন-ইন করতে হবে</translation>
@@ -325,6 +327,7 @@
 <translation id="6327105987658262776">কোনও আপডেট উপলভ্য নেই।</translation>
 <translation id="6333502561965082103">Chromium এ আরেকটি ক্রিয়াকলাপ প্রক্রিয়ায় আছে। অনুগ্রহ করে পরে আবার চেষ্টা করুন।</translation>
 <translation id="6334986366598267305">এখন আপনার Google অ্যাকাউন্ট ও শেয়ার করা কম্পিউটারগুলিতে Chromium ব্যবহার করা আরো সহজ৷</translation>
+<translation id="633626832589656416">আপনার ব্রাউজ করার অভিজ্ঞতা উন্নত এবং দ্রুত করার জন্য Chromium এইসব ট্যাব বন্ধ করে দিতে পারে।</translation>
 <translation id="6347933965114150440">Chromium-এর শর্টকার্ট</translation>
 <translation id="6366160072964553914">এই ফাইলটি সাধারণত ডাউনলোড করা হয় না এবং এটি বিপজ্জনক হতে পারে, তাই Chromium এই ডাউনলোডটি ব্লক করে দিয়েছে</translation>
 <translation id="6373523479360886564">আপনি কি Chromium আনইনস্টল করার ব্যাপারে নিশ্চিত?</translation>
diff --git a/chrome/app/resources/chromium_strings_cy.xtb b/chrome/app/resources/chromium_strings_cy.xtb
index 309f309..3b58949 100644
--- a/chrome/app/resources/chromium_strings_cy.xtb
+++ b/chrome/app/resources/chromium_strings_cy.xtb
@@ -118,6 +118,7 @@
 <translation id="2945997411976714835">Gwall gosod: Gwnaeth y broses gosodwr fethu â chychwyn.</translation>
 <translation id="2977470724722393594">Mae Chromium yn gyfoes</translation>
 <translation id="2977506796191543575">Os yw gwefan yn ceisio dwyn eich cyfrinair, neu pan fyddwch yn lawrlwytho ffeil niweidiol, gall Chromium hefyd anfon cyfeiriadau URL, gan gynnwys darnau o gynnwys tudalen, i Pori'n Ddiogel</translation>
+<translation id="2987208172821108655">Gall Chromium wneud y tabiau hyn yn anweithredol i wella eich profiad pori a rhyddhau adnoddau.</translation>
 <translation id="3013473503895162900">Agor <ph name="URL" /> mewn tab newydd yn Chromium.</translation>
 <translation id="3032706164202344641">Ni all Chromium wirio'ch cyfrineiriau. Rhowch gynnig arall arni'n nes ymlaen.</translation>
 <translation id="3032787606318309379">Wrthi'n ychwanegu at Chromium...</translation>
@@ -319,6 +320,7 @@
 <translation id="6248213926982192922">Gwneud Chromium y porwr diofyn</translation>
 <translation id="6266342355635466082">Ni all Chromuim wirio am ddiweddariadau. Rhowch gynnig ar wirio'ch cysylltiad rhyngrwyd.</translation>
 <translation id="6268381023930128611">Allgofnodi o Chromium?</translation>
+<translation id="6270547683008298381">Mae'r tabiau hyn yn defnyddio adnoddau ychwanegol. Er mwyn gwella eich perfformiad, gadewch i Chromium eu gwneud yn anweithredol.</translation>
 <translation id="6281746429495226318">Personoleiddio'ch proffil Chromium</translation>
 <translation id="6290827346642914212">Enwch eich proffil Chromium</translation>
 <translation id="6294831894865512704">Mae estyniad eisiau i chi fewngofnodi i Chromium</translation>
@@ -327,6 +329,7 @@
 <translation id="6327105987658262776">Nid oes diweddariad ar gael.</translation>
 <translation id="6333502561965082103">Mae gweithred arall ar Chromium ar y gweill. Rhowch gynnig arall arni nes ymlaen.</translation>
 <translation id="6334986366598267305">Mae hi bellach yn haws defnyddio Chromium gyda'ch Cyfrif Google ar gyfrifiaduron cyffredin.</translation>
+<translation id="633626832589656416">Gall Chromium wneud y tabiau hyn yn anweithredol i wella'ch profiad pori a chadw pethau'n gyflym.</translation>
 <translation id="6347933965114150440">Llwybr Byr Chromium</translation>
 <translation id="6366160072964553914">Gwnaeth Chromium rwystro'r lawrlwythiad hwn oherwydd nid yw'r ffeil yn cael ei lawrlwytho'n aml a gall fod yn beryglus</translation>
 <translation id="6373523479360886564">Ydych chi'n siŵr eich bod am ddadosod Chromium?</translation>
diff --git a/chrome/app/resources/chromium_strings_da.xtb b/chrome/app/resources/chromium_strings_da.xtb
index 0c8204c..aa4cf9c 100644
--- a/chrome/app/resources/chromium_strings_da.xtb
+++ b/chrome/app/resources/chromium_strings_da.xtb
@@ -116,6 +116,7 @@
 <translation id="2945997411976714835">Installationsfejl: Installationsprocessen kunne ikke startes.</translation>
 <translation id="2977470724722393594">Chromium er opdateret</translation>
 <translation id="2977506796191543575">Hvis et website forsøger at stjæle din adgangskode, eller hvis du downloader en skadelig fil, sender Chromium muligvis også webadresser, bl.a. mindre mængder sideindhold, til Beskyttet browsing</translation>
+<translation id="2987208172821108655">Chromium kan gøre disse faner inaktive for at forbedre din browseroplevelse og frigøre ressourcer.</translation>
 <translation id="3013473503895162900">Åbn <ph name="URL" /> på en ny fane i Chromium.</translation>
 <translation id="3032706164202344641">Chromium kan ikke tjekke dine adgangskoder. Prøv igen senere.</translation>
 <translation id="3032787606318309379">Føjer til Chromium...</translation>
@@ -317,6 +318,7 @@
 <translation id="6248213926982192922">Gør Chromium til din standardbrowser</translation>
 <translation id="6266342355635466082">Chromium kan ikke søge efter opdateringer. Prøv at tjekke din internetforbindelse.</translation>
 <translation id="6268381023930128611">Vil du logge ud af Chromium?</translation>
+<translation id="6270547683008298381">Disse faner bruger ekstra ressourcer. Du kan forbedre ydeevnen ved at give Chromium tilladelse til at gøre dem inaktive.</translation>
 <translation id="6281746429495226318">Tilpas din Chromium-profil</translation>
 <translation id="6290827346642914212">Giv din Chromium-profil et navn</translation>
 <translation id="6294831894865512704">En udvidelse vil have dig til at logge ind i Chromium</translation>
@@ -325,6 +327,7 @@
 <translation id="6327105987658262776">Der er ingen opdatering tilgængelig.</translation>
 <translation id="6333502561965082103">En anden handling i Chromium er i gang. Prøv igen senere.</translation>
 <translation id="6334986366598267305">Det er nu blevet nemmere at bruge Chromium med din Google-konto og på delte computere.</translation>
+<translation id="633626832589656416">Chromium kan gøre disse faner inaktive for at forbedre din browseroplevelse og give dig hurtigere indlæsning.</translation>
 <translation id="6347933965114150440">Chromium-genvej</translation>
 <translation id="6366160072964553914">Chromium har blokeret denne download, fordi filen normalt ikke downloades og kan være skadelig</translation>
 <translation id="6373523479360886564">Er du sikker på, at du vil afinstallere Chromium?</translation>
diff --git a/chrome/app/resources/chromium_strings_en-GB.xtb b/chrome/app/resources/chromium_strings_en-GB.xtb
index ec0922eb..81647f5 100644
--- a/chrome/app/resources/chromium_strings_en-GB.xtb
+++ b/chrome/app/resources/chromium_strings_en-GB.xtb
@@ -118,6 +118,7 @@
 <translation id="2945997411976714835">Install error: The installer process failed to start.</translation>
 <translation id="2977470724722393594">Chromium is up to date</translation>
 <translation id="2977506796191543575">If a site tries to steal your password, or when you download a harmful file, Chromium may also send URLs, including bits of page content, to Safe Browsing</translation>
+<translation id="2987208172821108655">Chromium can make these tabs inactive to improve your browsing experience and free up resources.</translation>
 <translation id="3013473503895162900">Open <ph name="URL" /> in a new tab in Chromium.</translation>
 <translation id="3032706164202344641">Chromium can't check your passwords. Try again later.</translation>
 <translation id="3032787606318309379">Adding to Chromium ...</translation>
@@ -319,6 +320,7 @@
 <translation id="6248213926982192922">Make Chromium the default browser</translation>
 <translation id="6266342355635466082">Chromium can't check for updates. Try checking your Internet connection.</translation>
 <translation id="6268381023930128611">Sign out of Chromium?</translation>
+<translation id="6270547683008298381">These tabs are using extra resources. To improve your performance, let Chromium make them inactive.</translation>
 <translation id="6281746429495226318">Customise your Chromium profile</translation>
 <translation id="6290827346642914212">Name your Chromium profile</translation>
 <translation id="6294831894865512704">An extension wants you to sign in to Chromium</translation>
@@ -327,6 +329,7 @@
 <translation id="6327105987658262776">No update is available.</translation>
 <translation id="6333502561965082103">Another operation on Chromium is in progress. Please try again later.</translation>
 <translation id="6334986366598267305">Now it's easier to use Chromium with your Google Account and on shared computers.</translation>
+<translation id="633626832589656416">Chromium can make these tabs inactive to improve your browsing experience and keep things fast.</translation>
 <translation id="6347933965114150440">Chromium shortcut</translation>
 <translation id="6366160072964553914">Chromium blocked this download because the file isn't commonly downloaded and it may be dangerous</translation>
 <translation id="6373523479360886564">Are you sure you want to uninstall Chromium?</translation>
diff --git a/chrome/app/resources/chromium_strings_es.xtb b/chrome/app/resources/chromium_strings_es.xtb
index 62f0df6..bc2bdb1 100644
--- a/chrome/app/resources/chromium_strings_es.xtb
+++ b/chrome/app/resources/chromium_strings_es.xtb
@@ -118,6 +118,7 @@
 <translation id="2945997411976714835">Error de instalación: no se ha podido iniciar el proceso de instalación.</translation>
 <translation id="2977470724722393594">Chromium está actualizado</translation>
 <translation id="2977506796191543575">Si un sitio intenta robarte tu contraseña o si descargas un archivo dañino, es posible que Chromium también envíe URLs, incluidos fragmentos de contenido de la página, a Navegación segura.</translation>
+<translation id="2987208172821108655">Chromium puede inactivar estas pestañas para mejorar tu experiencia de navegación y liberar recursos.</translation>
 <translation id="3013473503895162900">Abre <ph name="URL" /> en una pestaña nueva de Chromium.</translation>
 <translation id="3032706164202344641">Chromium no puede comprobar tus contraseñas. Vuelve a intentarlo más tarde.</translation>
 <translation id="3032787606318309379">Añadiendo a Chromium...</translation>
@@ -319,6 +320,7 @@
 <translation id="6248213926982192922">Establecer Chromium como navegador predeterminado</translation>
 <translation id="6266342355635466082">Chromium no puede comprobar si hay actualizaciones. Revisa tu conexión a Internet.</translation>
 <translation id="6268381023930128611">¿Cerrar sesión en Chromium?</translation>
+<translation id="6270547683008298381">Estas pestañas están usando recursos adicionales. Para mejorar tu rendimiento, permite que Chromium las inactive.</translation>
 <translation id="6281746429495226318">Personaliza tu perfil de Chromium</translation>
 <translation id="6290827346642914212">Pon un nombre a tu perfil de Chromium</translation>
 <translation id="6294831894865512704">Una extensión quiere que inicies sesión en Chromium</translation>
@@ -327,6 +329,7 @@
 <translation id="6327105987658262776">No hay actualizaciones disponibles.</translation>
 <translation id="6333502561965082103">Hay otra operación en curso en Chromium. Vuelve a intentarlo más tarde.</translation>
 <translation id="6334986366598267305">Ahora es más fácil utilizar Chromium con tu cuenta de Google y en ordenadores compartidos.</translation>
+<translation id="633626832589656416">Chromium puede inactivar estas pestañas para mejorar y agilizar tu experiencia de navegación.</translation>
 <translation id="6347933965114150440">Acceso directo de Chromium</translation>
 <translation id="6366160072964553914">Chromium ha bloqueado esta descarga porque el archivo no se descarga habitualmente y podría ser peligroso</translation>
 <translation id="6373523479360886564">¿Seguro que quieres desinstalar Chromium?</translation>
diff --git a/chrome/app/resources/chromium_strings_eu.xtb b/chrome/app/resources/chromium_strings_eu.xtb
index ccee039..7dc450b5 100644
--- a/chrome/app/resources/chromium_strings_eu.xtb
+++ b/chrome/app/resources/chromium_strings_eu.xtb
@@ -118,6 +118,7 @@
 <translation id="2945997411976714835">Instalazio-errorea: instalatzailearen prozesua ezin izan da hasi.</translation>
 <translation id="2977470724722393594">Eguneratuta dago Chromium</translation>
 <translation id="2977506796191543575">Webguneren bat pasahitza lapurtzen saiatzen bada edo fitxategi kaltegarriren bat deskargatzen baduzu, baliteke Chromium-ek URLak ere bidaltzea (orriko edukiaren zati batzuk barne) Arakatze segurua eginbideari.</translation>
+<translation id="2987208172821108655">Chromium-ek inaktibo ezar ditzake fitxa hauek, arakatzea hobetzeko eta baliabideak libratzeko.</translation>
 <translation id="3013473503895162900">Ireki <ph name="URL" /> Chromium-eko fitxa berri batean.</translation>
 <translation id="3032706164202344641">Chromium-ek ezin ditu egiaztatu pasahitzak. Saiatu geroago.</translation>
 <translation id="3032787606318309379">Chromium-era gehitzen…</translation>
@@ -319,6 +320,7 @@
 <translation id="6248213926982192922">Ezarri Chromium arakatzaile lehenetsi gisa</translation>
 <translation id="6266342355635466082">Chromium-ek ezin du egiaztatu eguneratzerik dagoen. Egiaztatu Internetera konektatuta zaudela.</translation>
 <translation id="6268381023930128611">Chromium-eko saioa amaitu?</translation>
+<translation id="6270547683008298381">Fitxa hauek baliabide gehigarriak erabiltzen dituzte. Errendimendua hobetzeko, eman fitxa horiek inaktibo ezartzeko baimena Chromium-i.</translation>
 <translation id="6281746429495226318">Pertsonalizatu Chromium-eko profila</translation>
 <translation id="6290827346642914212">Eman izen bat Chromium-eko profilari</translation>
 <translation id="6294831894865512704">Luzapen batek Chromium-en saioa has dezazun behar du</translation>
@@ -327,6 +329,7 @@
 <translation id="6327105987658262776">Ez dago eguneratzerik erabilgarri.</translation>
 <translation id="6333502561965082103">Beste eragiketa bat egiten ari da Chromium. Saiatu berriro geroago.</translation>
 <translation id="6334986366598267305">Errazagoa da Chromium erabiltzea Google-ko kontuarekin eta partekatutako ordenagailuetan.</translation>
+<translation id="633626832589656416">Chromium-ek inaktibo ezar ditzake fitxa hauek, arakatzea hobetzeko eta bizkortzeko.</translation>
 <translation id="6347933965114150440">Chromium-en lasterbidea</translation>
 <translation id="6366160072964553914">Chromium-ek deskarga hau blokeatu du, fitxategia normalean deskargatzen ez delako eta agian arriskutsua delako</translation>
 <translation id="6373523479360886564">Ziur Chromium desinstalatu nahi duzula?</translation>
diff --git a/chrome/app/resources/chromium_strings_fa.xtb b/chrome/app/resources/chromium_strings_fa.xtb
index 9f8a5350..d254fc96 100644
--- a/chrome/app/resources/chromium_strings_fa.xtb
+++ b/chrome/app/resources/chromium_strings_fa.xtb
@@ -117,6 +117,7 @@
 <translation id="2945997411976714835">خطای نصب: فرایند نصب‌کننده شروع نشد.</translation>
 <translation id="2977470724722393594">‏Chromium به‌روز است</translation>
 <translation id="2977506796191543575">‏اگر سایتی تلاش کند گذرواژه شما را به‌سرقت ببرد، یا وقتی فایل مخربی بارگیری می‌کنید، Chromium ممکن است نشانی‌های وب را نیز به‌همراه بخش‌های کوچکی از محتوای صفحه به «مرور ایمن» ارسال کند</translation>
+<translation id="2987208172821108655">‏‫Chromium می‌تواند این برگه‌ها را غیرفعال کند تا تجربه مرور شما را بهبود بخشد و منابع را آزاد کند.</translation>
 <translation id="3013473503895162900">‏‫<ph name="URL" /> در برگه جدیدی در Chromium باز می‌شود.</translation>
 <translation id="3032706164202344641">‏Chromium نمی‌تواند گذرواژه‌هایتان را بررسی کند. بعداً دوباره امتحان کنید.</translation>
 <translation id="3032787606318309379">‏افزودن به Chromium…</translation>
@@ -318,6 +319,7 @@
 <translation id="6248213926982192922">‏Chromium  مرورگر پیش‌فرض شود</translation>
 <translation id="6266342355635466082">‏Chromium نمی‌تواند به‌روزرسانی‌ها را بررسی کند. اتصال اینترنت را بررسی کنید.</translation>
 <translation id="6268381023930128611">‏از Chromium خارج می‌شوید؟</translation>
+<translation id="6270547683008298381">‏این برگه‌ها از منابع بیشتری استفاده می‌کنند. برای بهبود عملکرد، اجازه دهید Chromium آن‌ها را غیرفعال کند.</translation>
 <translation id="6281746429495226318">‏سفارشی کردن نمایه Chromium</translation>
 <translation id="6290827346642914212">‏نام‌گذاری نمایه Chromium</translation>
 <translation id="6294831894865512704">‏یکی از افزونه‌ها از شما می‌خواهد به سیستم Chromium وارد شوید</translation>
@@ -326,6 +328,7 @@
 <translation id="6327105987658262776">به‌روزرسانی دردسترس نیست.</translation>
 <translation id="6333502561965082103">‏عملیات دیگری در Chromium درحال انجام است. لطفاً بعداً دوباره امتحان کنید.</translation>
 <translation id="6334986366598267305">‏اکنون استفاده از Chromium با حساب Google شما و در رایانه‌های مشترک آسان‌تر شده است.</translation>
+<translation id="633626832589656416">‏‫Chromium می‌تواند این برگه‌ها را غیرفعال کند تا تجربه مرور شما را بهبود بخشد و سرعت بالا را حفظ کند.</translation>
 <translation id="6347933965114150440">‏میان‌بر Chromium</translation>
 <translation id="6366160072964553914">‏‫Chromium این بارگیری را مسدود کرد زیرا این فایل معمولاً بارگیری نمی‌شود و ممکن است خطرناک باشد</translation>
 <translation id="6373523479360886564">‏آیا مطمئن هستید که می‌خواهید Chromium را حذف نصب کنید؟</translation>
diff --git a/chrome/app/resources/chromium_strings_fil.xtb b/chrome/app/resources/chromium_strings_fil.xtb
index 455cea2..0208607 100644
--- a/chrome/app/resources/chromium_strings_fil.xtb
+++ b/chrome/app/resources/chromium_strings_fil.xtb
@@ -118,6 +118,7 @@
 <translation id="2945997411976714835">Error sa pag-install: Hindi nagsimula ang proseso ng installer.</translation>
 <translation id="2977470724722393594">Napapanahon ang Chromium</translation>
 <translation id="2977506796191543575">Kung susubukan ng site na nakawin ang iyong password, o kapag nag-download ka ng mapaminsalang file, posible ring magpadala ang Chromium sa Ligtas na Pag-browse ng mga URL, kabilang ang ilang content ng page</translation>
+<translation id="2987208172821108655">Magagawa ng Chromium na gawing hindi aktibo ang mga tab na ito para pagandahin ang iyong experience sa pag-browse at bakantehin ang mga resource.</translation>
 <translation id="3013473503895162900">Buksan ang <ph name="URL" /> sa bagong tab sa Chromium.</translation>
 <translation id="3032706164202344641">Hindi masuri ng Chromium ang iyong mga password. Subukan ulit sa ibang pagkakataon.</translation>
 <translation id="3032787606318309379">Idinaragdag sa Chromium...</translation>
@@ -319,6 +320,7 @@
 <translation id="6248213926982192922">Gawing default na browser ang Chromium</translation>
 <translation id="6266342355635466082">Hindi matingnan ng Chromium kung may mga update. Subukang tingnan ang iyong koneksyon sa internet.</translation>
 <translation id="6268381023930128611">Mag-sign out sa Chromium?</translation>
+<translation id="6270547683008298381">Gumagamit ang mga tab na ito ng mga karagdagang resource. Para pahusayin ang iyong performance, hayaan ang Chromium na gawing hindi aktibo ang mga ito.</translation>
 <translation id="6281746429495226318">I-customize ang iyong profile sa Chromium</translation>
 <translation id="6290827346642914212">Pangalanan ang iyong profile sa Chromium</translation>
 <translation id="6294831894865512704">Gusto ng isang extension na mag-sign in ka sa Chromium</translation>
@@ -327,6 +329,7 @@
 <translation id="6327105987658262776">Walang available na update.</translation>
 <translation id="6333502561965082103">May kasalukuyang isinasagawang isa pang pagpapatakbo sa Chromium. Pakisubukang muli sa ibang pagkakataon.</translation>
 <translation id="6334986366598267305">Ngayon, mas madali nang gamitin ang Chromium sa iyong Google Account at sa mga nakabahaging computer.</translation>
+<translation id="633626832589656416">Magagawa ng Chromium na gawing hindi aktibo ang mga tab na ito para pagandahin ang iyong experience sa pag-browse at panatilihing mabilis ang mga bagay.</translation>
 <translation id="6347933965114150440">Shortcut ng Chromium</translation>
 <translation id="6366160072964553914">Na-block ng Chromium ang pag-download na ito dahil hindi karaniwang dina-download ang file at posibleng mapanganib ito</translation>
 <translation id="6373523479360886564">Sigurado ka bang nais mong i-uninstall ang Chromium?</translation>
diff --git a/chrome/app/resources/chromium_strings_fr-CA.xtb b/chrome/app/resources/chromium_strings_fr-CA.xtb
index b8e2b50..855d65f 100644
--- a/chrome/app/resources/chromium_strings_fr-CA.xtb
+++ b/chrome/app/resources/chromium_strings_fr-CA.xtb
@@ -118,6 +118,7 @@
 <translation id="2945997411976714835">Erreur d'installation : le processus d'installation n'a pas pu démarrer.</translation>
 <translation id="2977470724722393594">Chromium est à jour</translation>
 <translation id="2977506796191543575">Si un site tente de voler votre mot de passe ou si vous téléchargez un fichier dangereux, Chromium peut également envoyer les URL concernées, y compris des extraits du contenu de pages, à la navigation sécurisée</translation>
+<translation id="2987208172821108655">Chromium peut rendre ces onglets inactifs pour améliorer votre expérience de navigation et libérer des ressources.</translation>
 <translation id="3013473503895162900">Ouvrez l'URL <ph name="URL" /> dans un nouvel onglet dans Chromium.</translation>
 <translation id="3032706164202344641">Chromium ne peut pas vérifier vos mots de passe. Réessayez plus tard.</translation>
 <translation id="3032787606318309379">Ajout à Chromium en cours...</translation>
@@ -319,6 +320,7 @@
 <translation id="6248213926982192922">Faire de Chromium le navigateur par défaut</translation>
 <translation id="6266342355635466082">Chromium ne peut pas vérifier la présence de mises à jour. Essayez de vérifier votre connexion Internet.</translation>
 <translation id="6268381023930128611">Se déconnecter de Chromium?</translation>
+<translation id="6270547683008298381">Ces onglets utilisent des ressources supplémentaires. Pour améliorer vos performances, laissez Chromium les rendre inactifs.</translation>
 <translation id="6281746429495226318">Personnaliser votre profil Chromium</translation>
 <translation id="6290827346642914212">Nommer votre profil Chromium</translation>
 <translation id="6294831894865512704">Une extension souhaite que vous vous connectiez à Chromium</translation>
@@ -327,6 +329,7 @@
 <translation id="6327105987658262776">Aucune mise à jour n'est proposée.</translation>
 <translation id="6333502561965082103">Une autre opération est en cours sur Chromium. Veuillez réessayer plus tard.</translation>
 <translation id="6334986366598267305">Il est maintenant plus facile d'utiliser Chromium avec votre compte Google et sur des ordinateurs partagés.</translation>
+<translation id="633626832589656416">Chromium peut rendre ces onglets inactifs pour améliorer votre expérience de navigation et garantir un fonctionnement rapide.</translation>
 <translation id="6347933965114150440">Raccourci Chromium</translation>
 <translation id="6366160072964553914">Chromium a bloqué ce téléchargement, car le fichier n'est pas souvent téléchargé et pourrait être dangereux</translation>
 <translation id="6373523479360886564">Voulez-vous vraiment désinstaller Chromium?</translation>
diff --git a/chrome/app/resources/chromium_strings_hi.xtb b/chrome/app/resources/chromium_strings_hi.xtb
index f2bd03b..6a597f9 100644
--- a/chrome/app/resources/chromium_strings_hi.xtb
+++ b/chrome/app/resources/chromium_strings_hi.xtb
@@ -116,6 +116,7 @@
 <translation id="2945997411976714835">इंस्टॉल करने में गड़बड़ी हुई: इंस्टॉल करने की प्रोसेस शुरू नहीं हो सकी.</translation>
 <translation id="2977470724722393594">क्रोमियम अप टू डेट है</translation>
 <translation id="2977506796191543575">अगर कोई साइट आपका पासवर्ड चुराने की कोशिश करती है या नुकसान पहुंचाने वाली कोई फ़ाइल डाउनलोड होने पर Chromium, सुरक्षित ब्राउज़िंग की सेवा को उनके यूआरएल भेज सकता है. यूआरएल के साथ-साथ पेज का कुछ कॉन्टेंट भी भेजा जाता है</translation>
+<translation id="2987208172821108655">Chromium आपके ब्राउज़िंग अनुभव को बेहतर बनाने और संसाधनों को कम करने के लिए, इन टैब को बंद कर सकता है.</translation>
 <translation id="3013473503895162900"><ph name="URL" /> को Chromium के नए टैब में खोलें.</translation>
 <translation id="3032706164202344641">क्रोमियम आपके पासवर्ड की जांच नहीं कर सकता. बाद में कोशिश करें.</translation>
 <translation id="3032787606318309379">क्रोमियम में जोड़ रहा है...</translation>
@@ -317,6 +318,7 @@
 <translation id="6248213926982192922">क्रोमियम को डिफ़ॉल्ट ब्राउज़र बनाएं</translation>
 <translation id="6266342355635466082">क्रोमियम आपके अपडेट की जांच नहीं कर सकता. अपने इंटरनेट कनेक्शन की जांच करें.</translation>
 <translation id="6268381023930128611">क्रोमियम से प्रस्थान करें?</translation>
+<translation id="6270547683008298381">ये टैब ज़्यादा संसाधनों का इस्तेमाल कर रहे हैं. परफ़ॉर्मेंस को बेहतर बनाने के लिए, Chromium को इन्हें बंद करने की अनुमति दें.</translation>
 <translation id="6281746429495226318">अपनी Chromium प्रोफ़ाइल को पसंद के मुताबिक बनाएं</translation>
 <translation id="6290827346642914212">अपने Chromium प्रोफ़ाइल को नाम दें</translation>
 <translation id="6294831894865512704">एक्सटेंशन का इस्तेमाल करने के लिए, आपको Chromium में साइन इन करना होगा</translation>
@@ -325,6 +327,7 @@
 <translation id="6327105987658262776">कोई अपडेट उपलब्ध नहीं है.</translation>
 <translation id="6333502561965082103">क्रोमियम पर एक अन्य क्रिया चल रही है. कृपया बाद में फिर से कोशिश करें.</translation>
 <translation id="6334986366598267305">अब अपने Google खाते के साथ और शेयर किए गए कंप्यूटर पर क्रोमियम का उपयोग करना आसान हो गया है.</translation>
+<translation id="633626832589656416">Chromium आपके ब्राउज़िंग अनुभव को बेहतर बनाने और चीज़ों को आसान बनाए रखने के लिए, इन टैब को बंद कर सकता है.</translation>
 <translation id="6347933965114150440">Chromium का शॉर्टकट</translation>
 <translation id="6366160072964553914">Chromium ने इस डाउनलोड को ब्लॉक कर दिया है, क्योंकि यह फ़ाइल आम तौर पर डाउनलोड नहीं की जाती और यह खतरनाक हो सकती है</translation>
 <translation id="6373523479360886564">क्या आप वाकई क्रोमियम को अनइंस्टाल करना चाहते हैं?</translation>
diff --git a/chrome/app/resources/chromium_strings_hy.xtb b/chrome/app/resources/chromium_strings_hy.xtb
index 10af6e8..a1adc72 100644
--- a/chrome/app/resources/chromium_strings_hy.xtb
+++ b/chrome/app/resources/chromium_strings_hy.xtb
@@ -15,6 +15,7 @@
 <translation id="1131805035311359397">Որպեսզի պաշտպանեք ձեր գաղտնաբառերը տվյալների արտահոսքից և խուսափեք անվտանգության հետ կապված այլ խնդիրներից, <ph name="BEGIN_LINK" />մտեք հաշիվ Chromium դիտարկիչում<ph name="END_LINK" />։</translation>
 <translation id="1153368717515616349">Սեղմեք Chromium-ի ընտրացանկը</translation>
 <translation id="1185134272377778587">Chromium-ի մասին</translation>
+<translation id="1188705220418984327">Ձեր պատուհանով կիսվելու համար Համակարգի կարգավորումներում թույլատրեք էկրանի տեսագրումը Chromium-ի համար։</translation>
 <translation id="1203500561924088507">Շնորհակալություն տեղադրելու համար։ Նախքան <ph name="BUNDLE_NAME" />-ն օգտագործելը դուք պետք է վերագործարկեք ձեր դիտարկիչը։</translation>
 <translation id="1262876892872089030">Մինչ այս ներդիրն ակտիվ չէր, Chromium-ի աշխատանքի արագությունը պահպանելու համար տարածք է ազատվել։ Դուք կարող եք ընտրել, որ այս կայքը միշտ ակտիվ մնա։</translation>
 <translation id="1265577313130862557">Chromium-ն արգելափակել է այս ներբեռնումը, քանի որ ֆայլը վտանգավոր է</translation>
@@ -160,6 +161,7 @@
 <translation id="364817392622123556">{COUNT,plural, =0{Chromium-ի այս տարբերակի համար առկա է թարմացում: Այն կտեղադրվի, երբ դիտարկիչը վերագործարկվի։}=1{Chromium-ի այս տարբերակի համար առկա է թարմացում: Այն կտեղադրվի, երբ դիտարկիչը վերագործարկվի։ Ձեր ինկոգնիտո պատուհանը նորից չի բացվի։}one{Chromium-ի այս տարբերակի համար առկա է թարմացում: Այն կտեղադրվի, երբ դիտարկիչը վերագործարկվի։ Ձեր # ինկոգնիտո պատուհանը նորից չի բացվի։}other{Chromium-ի այս տարբերակի համար առկա է թարմացում: Այն կտեղադրվի, երբ դիտարկիչը վերագործարկվի։ Ձեր # ինկոգնիտո պատուհանները նորից չեն բացվի։}}</translation>
 <translation id="3651803019964686660">Հեռախոսահամարը <ph name="ORIGIN" /> կայքից ձեր Android հեռախոսին ուղարկելու համար երկու սարքերի Chromium դիտարկիչներում մտեք հաշիվ։</translation>
 <translation id="3667616615096815454">Չհաջողվեց տեղադրել․ հավելվածն անծանոթ է սերվերի համար։</translation>
+<translation id="3669334504579945026">Ձեր էկրանով կիսվելու համար Համակարգի կարգավորումներում թույլատրեք էկրանի տեսագրումը Chromium-ի համար։</translation>
 <translation id="3685209450716071127">Chromium-ը չի կարող ստուգել ձեր գաղտնաբառերը։ Ստուգեք ինտերնետ կապը։</translation>
 <translation id="3702352323269013324">Իմանալ ավելին Chromium-ում գովազդի անհատականացման մասին</translation>
 <translation id="370962675267501463">{COUNT,plural, =0{Այս թարմացումը կիրառելու համար ադմինիստրատորը խնդրում է վերագործարկել Chromium-ը}=1{Այս թարմացումը կիրառելու համար ադմինիստրատորը խնդրում է վերագործարկել Chromium-ը։ Ձեր ինկոգնիտո պատուհանը նորից չի բացվի։}one{Այս թարմացումը կիրառելու համար ադմինիստրատորը խնդրում է վերագործարկել Chromium-ը։ Ձեր # ինկոգնիտո պատուհանը նորից չի բացվի։}other{Այս թարմացումը կիրառելու համար ադմինիստրատորը խնդրում է վերագործարկել Chromium-ը։ Ձեր # ինկոգնիտո պատուհանները նորից չեն բացվի։}}</translation>
@@ -459,6 +461,7 @@
 <translation id="8357820681460164151">Chromium դիտարկիչի ձեր տվյալները ձեր բոլոր սարքերում օգտագործելու համար մուտք գործեք և միացրեք համաժամացումը</translation>
 <translation id="8360718212975266891">Chromium-ի հետագա թարմացումները ստանալու համար ձեզ անհրաժեշտ է Windows 10 կամ ավելի նոր տարբերակ։ Այս համակարգիչն օգտագործում է Windows 8 տարբերակը։</translation>
 <translation id="8370517070665726704">© Google LLC <ph name="YEAR" />։ Բոլոր իրավունքները պահպանված են:</translation>
+<translation id="837460953767177950">Այնուհետև անհրաժեշտ կլինի վերագործարկել Chromium-ը։</translation>
 <translation id="8401454788024434101">Այս ընդլայնման հրապարակումը չեղարկվել է մշակողի կողմից, և այն կարող է վտանգավոր լինել։ Հեռացրեք ընդլայնումը Chromium-ից, որպեսզի այն այլևս չկարողանա տեսնել և փոփոխել ձեր տվյալները, այդ թվում՝ անձնական տեղեկությունները, ձեր այցելած կայքերում։</translation>
 <translation id="8417404458978023919">{0,plural, =1{Վերագործարկեք Chromium-ը մեկ օրվա ընթացքում}one{Վերագործարկեք Chromium-ը # օրվա ընթացքում}other{Վերագործարկեք Chromium-ը # օրվա ընթացքում}}</translation>
 <translation id="8453117565092476964">Տեղադրիչի արխիվը վնասված է կամ անվավեր: Նորից ներբեռնեք Chromium-ը:</translation>
diff --git a/chrome/app/resources/chromium_strings_id.xtb b/chrome/app/resources/chromium_strings_id.xtb
index 7f4d10e6..ddb3e5d 100644
--- a/chrome/app/resources/chromium_strings_id.xtb
+++ b/chrome/app/resources/chromium_strings_id.xtb
@@ -116,6 +116,7 @@
 <translation id="2945997411976714835">Error penginstalan: Proses penginstal gagal dimulai.</translation>
 <translation id="2977470724722393594">Chromium sudah diperbarui</translation>
 <translation id="2977506796191543575">Jika situs berusaha mencuri sandi Anda, atau jika Anda mendownload file berbahaya, Chromium mungkin juga mengirimkan URL, termasuk bit konten halaman, ke Safe Browsing</translation>
+<translation id="2987208172821108655">Chromium dapat menonaktifkan tab ini untuk meningkatkan pengalaman penjelajahan dan mengosongkan resource.</translation>
 <translation id="3013473503895162900">Buka <ph name="URL" /> di tab baru di Chromium.</translation>
 <translation id="3032706164202344641">Chromium tidak dapat memeriksa sandi Anda. Coba lagi nanti.</translation>
 <translation id="3032787606318309379">Menambahkan Chromium...</translation>
@@ -317,6 +318,7 @@
 <translation id="6248213926982192922">Jadikan Chromium browser default</translation>
 <translation id="6266342355635466082">Chromium tidak dapat memeriksa update. Coba periksa koneksi internet Anda.</translation>
 <translation id="6268381023930128611">Keluar dari Chromium?</translation>
+<translation id="6270547683008298381">Tab ini menggunakan lebih banyak resource. Untuk meningkatkan performa, izinkan Chromium menonaktifkannya.</translation>
 <translation id="6281746429495226318">Sesuaikan profil Chromium Anda</translation>
 <translation id="6290827346642914212">Beri nama profil Chromium Anda</translation>
 <translation id="6294831894865512704">Salah satu ekstensi ingin Anda login ke Chromium</translation>
@@ -325,6 +327,7 @@
 <translation id="6327105987658262776">Tidak ada update yang tersedia.</translation>
 <translation id="6333502561965082103">Operasi lain di Chromium sedang berlangsung. Coba lagi nanti.</translation>
 <translation id="6334986366598267305">Kini, menggunakan Chromium dengan Akun Google Anda dan di komputer bersama jadi lebih mudah.</translation>
+<translation id="633626832589656416">Chromium dapat menonaktifkan tab ini untuk meningkatkan pengalaman penjelajahan dan menjaga agar performanya tetap cepat.</translation>
 <translation id="6347933965114150440">Pintasan Chromium</translation>
 <translation id="6366160072964553914">Chromium memblokir download ini karena file tersebut tidak biasa didownload dan mungkin berbahaya</translation>
 <translation id="6373523479360886564">Anda yakin ingin meng-uninstal Chromium?</translation>
diff --git a/chrome/app/resources/chromium_strings_is.xtb b/chrome/app/resources/chromium_strings_is.xtb
index 2e33cfe..4ffcbd7 100644
--- a/chrome/app/resources/chromium_strings_is.xtb
+++ b/chrome/app/resources/chromium_strings_is.xtb
@@ -118,6 +118,7 @@
 <translation id="2945997411976714835">Uppsetningarvilla: Ekki tókst að ræsa ferli uppsetningarforrits.</translation>
 <translation id="2977470724722393594">Chromium er uppfært</translation>
 <translation id="2977506796191543575">Ef vefsvæði reynir að stela aðgangsorðinu þínu, eða ef þú sækir skaðlega skrá, gæti Chromium einnig sent vefslóðir í örugga vefskoðun, þar á meðal hluta af innihaldi síðna</translation>
+<translation id="2987208172821108655">Chromium getur óvirkjað þessa flipa til að bæta upplifunina þína í vafranum og losa um gögn.</translation>
 <translation id="3013473503895162900">Opna <ph name="URL" /> í nýjum flipa í Chromium.</translation>
 <translation id="3032706164202344641">Chromium getur ekki athugað aðgangsorðin þín. Reyndu aftur síðar.</translation>
 <translation id="3032787606318309379">Bætir við Chromium...</translation>
@@ -319,6 +320,7 @@
 <translation id="6248213926982192922">Gera Chromium að sjálfgefnum vafra</translation>
 <translation id="6266342355635466082">Chromium getur ekki athugað með uppfærslur. Athugaðu nettenginguna þína.</translation>
 <translation id="6268381023930128611">Skrá út af Chromium?</translation>
+<translation id="6270547683008298381">Þessir flipar nota aukagögn. Leyfðu Chromium að óvirkja þá til að bæta afköstin.</translation>
 <translation id="6281746429495226318">Sérsníða Chromium prófílinn þinn</translation>
 <translation id="6290827346642914212">Gefðu Chromium prófílnum þínum heiti</translation>
 <translation id="6294831894865512704">Viðbót vill að þú skráir þig inn á Chromium</translation>
@@ -327,6 +329,7 @@
 <translation id="6327105987658262776">Uppfærsla er ekki tiltæk.</translation>
 <translation id="6333502561965082103">Önnur aðgerð er í gangi í Chromium. Reyndu aftur síðar.</translation>
 <translation id="6334986366598267305">Nú er auðveldara að nota Chromium með Google reikningnum þínum og í samnýttum tölvum.</translation>
+<translation id="633626832589656416">Chromium getur óvirkjað þessa flipa til að bæta upplifunina þína í vafranum og halda hraða.</translation>
 <translation id="6347933965114150440">Chromium-flýtilykill</translation>
 <translation id="6366160072964553914">Chromium lokaði á þetta niðurhal vegna þess að skráin er ekki sótt oft og gæti verið hættuleg</translation>
 <translation id="6373523479360886564">Viltu örugglega fjarlægja Chromium?</translation>
diff --git a/chrome/app/resources/chromium_strings_iw.xtb b/chrome/app/resources/chromium_strings_iw.xtb
index 76f6bfe..4fda080a 100644
--- a/chrome/app/resources/chromium_strings_iw.xtb
+++ b/chrome/app/resources/chromium_strings_iw.xtb
@@ -34,6 +34,7 @@
 <translation id="1640672724030957280">מוריד...</translation>
 <translation id="1708666629004767631">‏גרסה חדשה ובטוחה יותר של Chromium זמינה כעת.</translation>
 <translation id="1715127912119967311">‏כדי לשפר את התכונות האלו, Chromium שולח את האינטראקציות שלך איתן ל-Google. בודקים אנושיים יכולים לקרוא את הנתונים האלה, לעבד אותם ולהוסיף להם הערות.</translation>
+<translation id="1722488837206509557">כך תהיה לך אפשרות לבחור מבין המכשירים הזמינים ולהציג בהם תוכן.</translation>
 <translation id="17264556997921157">‏יש לך אפשרות לראות ולהסיר את תחומי העניין שלפיהם האתרים מציגים לך את המודעות. ההערכה של תחומי העניין ב-Chromium מתבססת על היסטוריית הגלישה שלך מהזמן האחרון.</translation>
 <translation id="1733725117201708356">‏נתוני הגלישה ב-Chromium יימחקו בקרוב</translation>
 <translation id="1736443181683099871">‏Chromium ינסה לשדרג את הניווטים ל-HTTPS</translation>
diff --git a/chrome/app/resources/chromium_strings_ja.xtb b/chrome/app/resources/chromium_strings_ja.xtb
index 6337f2e2..c9338e75 100644
--- a/chrome/app/resources/chromium_strings_ja.xtb
+++ b/chrome/app/resources/chromium_strings_ja.xtb
@@ -116,6 +116,7 @@
 <translation id="2945997411976714835">インストール エラー: インストーラのプロセスを開始できませんでした。</translation>
 <translation id="2977470724722393594">Chromium は最新版です</translation>
 <translation id="2977506796191543575">サイトがパスワードを不正に取得しようとしている場合や、ユーザーが安全でないファイルをダウンロードしようとした場合は、URL とページ コンテンツの一部をセーフ ブラウジングに送信することがあります</translation>
+<translation id="2987208172821108655">Chromium では、これらのタブを非アクティブにして、ブラウジング環境を改善し、リソースを解放できます。</translation>
 <translation id="3013473503895162900">Chromium の新しいタブで <ph name="URL" /> を開きます。</translation>
 <translation id="3032706164202344641">Chromium でパスワードを確認できません。しばらくしてからもう一度お試しください。</translation>
 <translation id="3032787606318309379">Chromium に追加...</translation>
@@ -317,6 +318,7 @@
 <translation id="6248213926982192922">Chromium を既定のブラウザにする</translation>
 <translation id="6266342355635466082">Chromium がアップデートを確認できません。インターネット接続を確認してみてください。</translation>
 <translation id="6268381023930128611">Chromium からログアウトしますか?</translation>
+<translation id="6270547683008298381">これらのタブでは追加のリソースが使用されています。パフォーマンスを改善するには、Chromium でこれらのタブを非アクティブにしてください。</translation>
 <translation id="6281746429495226318">Chromium プロフィールをカスタマイズ</translation>
 <translation id="6290827346642914212">Chromium プロフィールの名前を設定</translation>
 <translation id="6294831894865512704">拡張機能が Chromium へのログインを求めています</translation>
@@ -325,6 +327,7 @@
 <translation id="6327105987658262776">利用できるアップデートはありません。</translation>
 <translation id="6333502561965082103">Chromium で別の処理が行われています。しばらくしてからもう一度お試しください。</translation>
 <translation id="6334986366598267305">共有パソコンの Chromium で Google アカウントが簡単に使用できるようになりました。</translation>
+<translation id="633626832589656416">Chromium では、これらのタブを非アクティブにして、ブラウジング環境を改善し、処理を高速に保つことができます。</translation>
 <translation id="6347933965114150440">Chromium のショートカット</translation>
 <translation id="6366160072964553914">このダウンロードは Chromium でブロックされました。ファイルが一般的にダウンロードされるものではなく、危害を及ぼす可能性があります</translation>
 <translation id="6373523479360886564">Chromium をアンインストールしてもよろしいですか?</translation>
diff --git a/chrome/app/resources/chromium_strings_ko.xtb b/chrome/app/resources/chromium_strings_ko.xtb
index 5856a55b..6fb8cfb3 100644
--- a/chrome/app/resources/chromium_strings_ko.xtb
+++ b/chrome/app/resources/chromium_strings_ko.xtb
@@ -118,6 +118,7 @@
 <translation id="2945997411976714835">설치 오류: 설치 프로그램 프로세스를 시작할 수 없습니다.</translation>
 <translation id="2977470724722393594">Chromium이 최신 버전임</translation>
 <translation id="2977506796191543575">사이트에서 사용자의 비밀번호를 도용하려고 하거나 사용자가 유해한 파일을 다운로드하는 경우, Chromium에서 페이지 콘텐츠 일부를 비롯한 URL을 세이프 브라우징 서비스에 보낼 수 있습니다.</translation>
+<translation id="2987208172821108655">Chromium은 이러한 탭을 비활성화하여 탐색 환경을 개선하고 리소스를 확보할 수 있습니다.</translation>
 <translation id="3013473503895162900">Chromium의 새 탭에서 <ph name="URL" /> 주소가 열립니다.</translation>
 <translation id="3032706164202344641">Chromium에서 비밀번호를 확인할 수 없습니다. 나중에 다시 시도하세요.</translation>
 <translation id="3032787606318309379">Chromium에 추가하는 중...</translation>
@@ -319,6 +320,7 @@
 <translation id="6248213926982192922">Chromium을 기본 브라우저로 설정</translation>
 <translation id="6266342355635466082">Chromium에서 업데이트를 확인할 수 없습니다. 인터넷 연결 상태를 확인하세요.</translation>
 <translation id="6268381023930128611">Chromium에서 로그아웃</translation>
+<translation id="6270547683008298381">이러한 탭은 추가 리소스를 사용하고 있습니다. 성능을 개선하려면 Chromium에서 이러한 탭을 비활성화하도록 허용하세요.</translation>
 <translation id="6281746429495226318">Chromium 프로필 맞춤설정</translation>
 <translation id="6290827346642914212">Chromium 프로필 이름 지정</translation>
 <translation id="6294831894865512704">확장 프로그램에서 Chromium에 로그인하도록 요청합니다</translation>
@@ -327,6 +329,7 @@
 <translation id="6327105987658262776">사용 가능한 업데이트가 없습니다.</translation>
 <translation id="6333502561965082103">Chromium에서 다른 작업이 진행 중입니다. 나중에 다시 시도해 주세요.</translation>
 <translation id="6334986366598267305">이제 Google 계정으로 공유 컴퓨터에서 Chromium을 손쉽게 사용할 수 있습니다.</translation>
+<translation id="633626832589656416">Chromium은 이러한 탭을 비활성화하여 탐색 환경을 개선하고 빠른 속도를 유지할 수 있습니다.</translation>
 <translation id="6347933965114150440">Chromium 바로가기</translation>
 <translation id="6366160072964553914">일반적으로 다운로드하지 않는 파일이며 위험할 가능성이 있기 때문에 Chromium에서 이 다운로드를 차단했습니다.</translation>
 <translation id="6373523479360886564">Chromium을 제거하시겠습니까?</translation>
diff --git a/chrome/app/resources/chromium_strings_lo.xtb b/chrome/app/resources/chromium_strings_lo.xtb
index 6b05021..9b4ce34 100644
--- a/chrome/app/resources/chromium_strings_lo.xtb
+++ b/chrome/app/resources/chromium_strings_lo.xtb
@@ -118,6 +118,7 @@
 <translation id="2945997411976714835">ຂໍ້ຜິດພາດໃນການຕິດຕັ້ງ: ເລີ່ມຂັ້ນຕອນຂອງຕົວຕິດຕັ້ງບໍ່ສຳເລັດ.</translation>
 <translation id="2977470724722393594">Chromium ແມ່ນເວີຊັນໃໝ່ຫຼ້າສຸດແລ້ວ</translation>
 <translation id="2977506796191543575">ຖ້າມີເວັບໄຊໃດໜຶ່ງພະຍາຍາມລັກເອົາລະຫັດຜ່ານຂອງທ່ານ ຫຼື ເມື່ອທ່ານດາວໂຫຼດໄຟລ໌ອັນຕະລາຍ, Chromium ອາດສົ່ງ URL, ຮວມທັງເນື້ອຫາບາງສ່ວນຂອງໜ້າໄປໃຫ້ Safe Browsing</translation>
+<translation id="2987208172821108655">Chromium ສາມາດເຮັດໃຫ້ແຖບເຫຼົ່ານີ້ບໍ່ເຮັດວຽກເພື່ອປັບປຸງປະສົບການໃນການເລືອກເບິ່ງຂອງທ່ານ ແລະ ຊ່ວຍປະຢັດຊັບພະຍາກອນ.</translation>
 <translation id="3013473503895162900">ເປີດ <ph name="URL" /> ໃນແຖບໃໝ່ໃນ Chromium.</translation>
 <translation id="3032706164202344641">Chromium ບໍ່ສາມາດກວດລະຫັດຜ່ານຂອງທ່ານໄດ້. ກະລຸນາລອງໃໝ່ໃນພາຍຫລັງ.</translation>
 <translation id="3032787606318309379">ກໍາລັງເພີ່ມ Chromium...</translation>
@@ -319,6 +320,7 @@
 <translation id="6248213926982192922">ເຮັດ Chromium ເປັນບຣາວ​ເຊີມາດຕະຖານ</translation>
 <translation id="6266342355635466082">Chromium ບໍ່ສາມາດກວດຫາການອັບເດດໄດ້. ລອງກວດເບິ່ງການເຊື່ອມຕໍ່ອິນເຕີເນັດຂອງທ່ານ.</translation>
 <translation id="6268381023930128611">ອອກຈາກລະບົບ Chromium ບໍ?</translation>
+<translation id="6270547683008298381">ແຖບເຫຼົ່ານີ້ໃຊ້ຊັບພະຍາກອນຫຼາຍເປັນພິເສດ. ເພື່ອປັບປຸງປະສິດທິພາບຂອງທ່ານ, ກະລຸນາໃຫ້ Chromium ຊ່ວຍປິດນຳໃຊ້ແຖບເຫຼົ່ານີ້.</translation>
 <translation id="6281746429495226318">ປັບແຕ່ງໂປຣໄຟລ໌ Chromium ຂອງທ່ານ</translation>
 <translation id="6290827346642914212">ຕັ້ງຊື່ໂປຣໄຟລ໌ Chromium ຂອງທ່ານ</translation>
 <translation id="6294831894865512704">ສ່ວນຂະຫຍາຍຕ້ອງການໃຫ້ທ່ານເຂົ້າສູ່ລະບົບ Chromium</translation>
@@ -327,6 +329,7 @@
 <translation id="6327105987658262776">ບໍ່ມີອັບເດດເທື່ອ.</translation>
 <translation id="6333502561965082103">ການດຳເນີນການອື່ນໃນ Chromium ພວມດຳເນີນຢູ່. ກະລຸນາລອງອີກຄັ້ງໃນພາຍຫຼັງ.</translation>
 <translation id="6334986366598267305">ດຽວນີ້ມັນງ່າຍທີ່ຈະໃຊ້ Chromium ກັບບັນຊີ Google ຂອງທ່ານ ແລະຢູ່ໃນຄອມພິວເຕີທີ່ແຊຣ໌ແລ້ວ.</translation>
+<translation id="633626832589656416">Chromium ສາມາດເຮັດໃຫ້ແຖບເຫຼົ່ານີ້ບໍ່ເຮັດວຽກເພື່ອປັບປຸງປະສົບການໃນການເລືອກເບິ່ງຂອງທ່ານ ແລະ ເຮັດໃຫ້ສິ່ງຕ່າງໆເຮັດວຽກໄດ້ໄວຂຶ້ນ.</translation>
 <translation id="6347933965114150440">ທາງລັດ Chromium</translation>
 <translation id="6366160072964553914">Chromium ບລັອກການດາວໂຫຼດນີ້ ເນື່ອງຈາກໄຟລ໌ບໍ່ໄດ້ມີການດາວໂຫຼດໂດຍທົ່ວໄປ ແລະ ອາດເປັນອັນຕະລາຍ</translation>
 <translation id="6373523479360886564">ທ່ານແນ່ໃຈບໍວ່າ ທ່ານຕ້ອງການຖອນຕິດຕັ້ງ Chromium?</translation>
diff --git a/chrome/app/resources/chromium_strings_mn.xtb b/chrome/app/resources/chromium_strings_mn.xtb
index 6760e53..6e5da86 100644
--- a/chrome/app/resources/chromium_strings_mn.xtb
+++ b/chrome/app/resources/chromium_strings_mn.xtb
@@ -118,6 +118,7 @@
 <translation id="2945997411976714835">Суулгах үед алдаа гарлаа: Суулгагч явцыг эхлүүлж чадсангүй.</translation>
 <translation id="2977470724722393594">Chromium-г шинэчилсэн байна</translation>
 <translation id="2977506796191543575">Хэрэв сайт таны нууц үгийг хулгайлахаар оролдох эсвэл таныг аюултай файл татах үед Chromium URL-г хуудасны бага зэрэг контентын хамт Аюулгүй үзэх рүү мөн илгээж болзошгүй</translation>
+<translation id="2987208172821108655">Chromium таны үзэх хэрэглээг сайжруулж, нөөцүүдийг чөлөөлөхийн тулд эдгээр табыг идэвхгүй болгох боломжтой.</translation>
 <translation id="3013473503895162900"><ph name="URL" />-г Chromium-д шинэ табд нээнэ үү.</translation>
 <translation id="3032706164202344641">Chromium таны нууц үгсийг шалгах боломжгүй байна. Дараа дахин оролдоно уу.</translation>
 <translation id="3032787606318309379">Chromium-д өгөгдөл нэмэх нь ...</translation>
@@ -317,6 +318,7 @@
 <translation id="6248213926982192922">Chromium-ыг анхдагч веб хөтөч болгох</translation>
 <translation id="6266342355635466082">Chromium нь шинэчлэлтийг шалгах боломжгүй байна. Интернэт холболтоо шалгаж үзнэ үү.</translation>
 <translation id="6268381023930128611">Chromium-с гарах уу?</translation>
+<translation id="6270547683008298381">Эдгээр таб нэмэлт нөөцүүдийг ашиглаж байна. Гүйцэтгэлээ сайжруулахын тулд Chromium-д эдгээр табыг идэвхгүй болгохыг зөвшөөрнө үү.</translation>
 <translation id="6281746429495226318">Chromium-н профайлаа өөрчлөх</translation>
 <translation id="6290827346642914212">Chromium-н профайлаа нэрлэнэ үү</translation>
 <translation id="6294831894865512704">Өргөтгөл таныг Chromium-д нэвтрэхийг хүсэж байна</translation>
@@ -325,6 +327,7 @@
 <translation id="6327105987658262776">Шинэчлэлт боломжгүй байна.</translation>
 <translation id="6333502561965082103">Chromium-д өөр үйл ажиллагаа явагдаж байна. Дараа дахин оролдоно уу.</translation>
 <translation id="6334986366598267305">Одоо та Google хаягаа ашиглан мөн өөр бусад компьютер дээр Chromium-г ашиглахад хялбар боллоо.</translation>
+<translation id="633626832589656416">Таны үзэх хэрэглээг сайжруулж, зүйлсийг хурдан байлгахын тулд Chromium эдгээр табыг идэвхгүй болгох боломжтой.</translation>
 <translation id="6347933965114150440">Chromium-н товчлол</translation>
 <translation id="6366160072964553914">Файлыг ихэвчлэн татдаггүй бөгөөд энэ нь аюултай байж магадгүй тул Chromium энэ таталтыг блоклосон</translation>
 <translation id="6373523479360886564">Та Chromium-ыг устгахыг хүсэж байгаадаа итгэлтэй байна уу?</translation>
diff --git a/chrome/app/resources/chromium_strings_mr.xtb b/chrome/app/resources/chromium_strings_mr.xtb
index db37b984..33b1237 100644
--- a/chrome/app/resources/chromium_strings_mr.xtb
+++ b/chrome/app/resources/chromium_strings_mr.xtb
@@ -14,6 +14,7 @@
 <translation id="1131805035311359397">तुमचे पासवर्ड डेटा भंग आणि इतर सुरक्षा समस्यांपासून सुरक्षित आहेत हे तपासण्यासाठी, <ph name="BEGIN_LINK" />Chromium मध्ये साइन इन करा<ph name="END_LINK" />.</translation>
 <translation id="1153368717515616349">Chromium मेनूवर क्लिक करा</translation>
 <translation id="1185134272377778587">Chromium बद्दल</translation>
+<translation id="1188705220418984327">तुमची विंडो शेअर करण्यासाठी, सिस्टीम प्राधान्ये यांमध्ये Chromium साठी स्क्रीन रेकॉर्डिंगला अनुमती द्या.</translation>
 <translation id="1203500561924088507">इंस्टॉल केल्याबद्दल धन्यवाद. तुम्ही <ph name="BUNDLE_NAME" /> वापरण्यापूर्वी तुमचा ब्राउझर रीस्टार्ट करणे आवश्यक आहे.</translation>
 <translation id="1262876892872089030">हा टॅब इनॅक्टिव्ह असताना, Chromium ला जलद ठेवण्यासाठी मेमरी मोकळी करण्यात आली होती. ही साइट इनॅक्टिव्ह राहण्यापासून नेहमी वगळली जावी असे तुम्ही निवडू शकता.</translation>
 <translation id="1265577313130862557">फाइल धोकादायक असल्याने Chromium ने हे डाउनलोड ब्लॉक केले आहे</translation>
@@ -117,6 +118,7 @@
 <translation id="2945997411976714835">इंस्टॉलसंबंधित एरर: इंस्टॉलर प्रक्रिया सुरू झाली नाही.</translation>
 <translation id="2977470724722393594">Chromium अद्ययावत आहे</translation>
 <translation id="2977506796191543575">साइटने तुमचा पासवर्ड चोरण्याचा प्रयत्न केल्यास किंवा तुम्ही हानिकारक फाइल डाउनलोड केल्यास, Chromium कदाचित पेज आशयाच्या भागांसह, URLs देखील सुरक्षित ब्राउझिंग ला पाठवेल</translation>
+<translation id="2987208172821108655">तुमच्या ब्राउझिंग अनुभवामध्ये सुधारणा करण्यासाठी आणि स्रोत रिक्त करण्यासाठी Chromium हे टॅब इनॅक्टिव्ह करू शकते.</translation>
 <translation id="3013473503895162900">Chromium मध्ये नवीन टॅबमध्ये <ph name="URL" />उघडा.</translation>
 <translation id="3032706164202344641">Chromium तुमचे पासवर्ड तपासू शकत नाही. नंतर पुन्हा प्रयत्न करा.</translation>
 <translation id="3032787606318309379">Chromium वर जोडत आहे...</translation>
@@ -159,6 +161,7 @@
 <translation id="364817392622123556">{COUNT,plural, =0{Chromium चे नवीन अपडेट उपलब्ध आहे आणि तुम्ही ते पुन्हा लाँच करताच लागू केले जाईल.}=1{Chromium चे नवीन अपडेट उपलब्ध आहे आणि तुम्ही ते पुन्हा लाँच करताच लागू केले जाईल. तुमची गुप्त विंडो पुन्हा उघडणार नाही.}other{Chromium चे नवीन अपडेट उपलब्ध आहे आणि तुम्ही ते पुन्हा लाँच करताच लागू केले जाईल. तुमच्या # गुप्त विंडो पुन्हा उघडणार नाहीत.}}</translation>
 <translation id="3651803019964686660"><ph name="ORIGIN" /> वरून तुमच्या Android फोनवर नंबर पाठवण्यासाठी, दोन्ही डिव्हाइसवर Chromium मध्ये साइन इन करा.</translation>
 <translation id="3667616615096815454">इंस्टॉल करता आले नाही, सर्व्हरला अ‍ॅप्लिकेशन माहीत नाही.</translation>
+<translation id="3669334504579945026">तुमची स्क्रीन शेअर करण्यासाठी, सिस्टीम प्राधान्ये यांमध्ये Chromium साठी स्क्रीन रेकॉर्डिंगला अनुमती द्या.</translation>
 <translation id="3685209450716071127">Chromium तुमचे पासवर्ड तपासू शकत नाही. तुमचे इंटरनेट कनेक्शन तपासून पहा.</translation>
 <translation id="3702352323269013324">Chromium मध्ये जाहिरात पर्सनलायझेशनबद्दल अधिक जाणून घ्या</translation>
 <translation id="370962675267501463">{COUNT,plural, =0{तुमच्या ॲडमिनिस्ट्रेटरने तुम्हाला हे अपडेट लागू करण्यासाठी Chromium पुन्हा लाँच करण्यास सांगितले आहे}=1{तुमच्या ॲडमिनिस्ट्रेटरने तुम्हाला हे अपडेट लागू करण्यासाठी Chromium पुन्हा लाँच करण्यास सांगितले आहे. तुमची गुप्त विंडो पुन्हा उघडणार नाही.}other{तुमच्या ॲडमिनिस्ट्रेटरने तुम्हाला हे अपडेट लागू करण्यासाठी Chromium पुन्हा लाँच करण्यास सांगितले आहे. तुमच्या # गुप्त विंडो पुन्हा उघडणार नाहीत.}}</translation>
@@ -318,6 +321,7 @@
 <translation id="6248213926982192922">Chromium ला डीफॉल्‍ट ब्राउझर बनवा</translation>
 <translation id="6266342355635466082">Chromium अपडेट तपासू शकत नाही. तुमचे इंटरनेट कनेक्शन तपासून पहा.</translation>
 <translation id="6268381023930128611">Chromium मधून साइन आउट करायचे?</translation>
+<translation id="6270547683008298381">हे टॅब अतिरिक्त स्रोत वापरत आहेत. तुमच्या परफॉर्मन्समध्ये सुधारणा करण्यासाठी, Chromium ला ते इनॅक्टिव्ह करू द्या.</translation>
 <translation id="6281746429495226318">तुमची Chromium प्रोफाइल कस्टमाइझ करा</translation>
 <translation id="6290827346642914212">तुमच्या Chromium प्रोफाइलला नाव द्या</translation>
 <translation id="6294831894865512704">एक्स्टेंशनसाठी तुम्हाला Chromium मध्ये साइन इन करावे लागेल</translation>
@@ -326,6 +330,7 @@
 <translation id="6327105987658262776">कोणतेही अपडेट उपलब्ध नाही.</translation>
 <translation id="6333502561965082103">Chromium वर दुसरे ऑपरेशन प्रगतीपथावर आहे. कृपया नंतर पुन्हा प्रयत्न करा.</translation>
 <translation id="6334986366598267305">आता आपल्या Google खात्यावर आणि शेअर केलेल्या संगणकांवर Chromium वापरणे अधिक सुलभ आहे.</translation>
+<translation id="633626832589656416">तुमच्या ब्राउझिंग अनुभवामध्ये सुधारणा करण्यासाठी आणि जलद काम करण्यासाठी Chromium हे टॅब इनॅक्टिव्ह करू शकते.</translation>
 <translation id="6347933965114150440">Chromium शॉर्टकट</translation>
 <translation id="6366160072964553914">फाइल सामान्यतः डाउनलोड केली जात नसल्याने Chromium ने हे डाउनलोड ब्लॉक केले आहे आणि ती धोकादायक असू शकते</translation>
 <translation id="6373523479360886564">तुम्हाला खात्री आहे की तुम्ही Chromium अनइंस्टॉल करू इच्‍छिता?</translation>
@@ -459,6 +464,7 @@
 <translation id="8357820681460164151">तुमच्या Chromium ब्राउझरवरील आशय तुमच्या सर्व डिव्हाइसवर अ‍ॅक्सेस करण्यासाठी साइन इन करा, त्यानंतर सिंक सुरू करा</translation>
 <translation id="8360718212975266891">भविष्यातील Chromium अपडेट मिळवण्यासाठी, तुमच्याकडे Windows 10 किंवा त्यापुढील आवृत्ती असणे आवश्यक आहे. हा कॉंप्युटर Windows 8 वापरत आहे.</translation>
 <translation id="8370517070665726704">कॉपीराइट <ph name="YEAR" /> Google LLC. सर्व हक्क राखीव.</translation>
+<translation id="837460953767177950">तुम्हाला त्यानंतर Chromium रीस्टार्ट करावे लागेल.</translation>
 <translation id="8401454788024434101">हे एक्स्टेंशन त्याच्या डेव्हलपरने अप्रकाशित केले होते आणि ते असुरक्षित असू शकते. ते Chromium वरून काढून टाका, जेणेकरून ते तुमच्या वैयक्तिक माहितीच्या समावेशासह तुम्ही भेट देत असलेल्या साइटवरील तुमचा डेटा आता पाहू आणि बदलू शकत नाही.</translation>
 <translation id="8417404458978023919">{0,plural, =1{Chromium एका दिवसामध्ये पुन्हा लाँच करा}other{Chromium # दिवसांमध्ये पुन्हा लाँच करा}}</translation>
 <translation id="8453117565092476964">इन्स्टॉलर संग्रहण दूषित किंवा चुकीचे आहे. कृपया Chromium पुन्हा डाउनलोड करा.</translation>
diff --git a/chrome/app/resources/chromium_strings_ms.xtb b/chrome/app/resources/chromium_strings_ms.xtb
index 2b07363..4732938 100644
--- a/chrome/app/resources/chromium_strings_ms.xtb
+++ b/chrome/app/resources/chromium_strings_ms.xtb
@@ -13,6 +13,7 @@
 <translation id="1131805035311359397">Untuk menyemak sama ada kata laluan anda selamat daripada pelanggaran data dan isu keselamatan lain, <ph name="BEGIN_LINK" />log masuk ke Chromium<ph name="END_LINK" />.</translation>
 <translation id="1153368717515616349">Klik menu Chromium</translation>
 <translation id="1185134272377778587">Mengenai Chromium</translation>
+<translation id="1188705220418984327">Untuk berkongsi tetingkap anda, benarkan rakaman skrin untuk Chromium dalam Pilihan Sistem.</translation>
 <translation id="1203500561924088507">Terima kasih kerana memasang. Anda perlu memulakan semula penyemak imbas anda sebelum menggunakan <ph name="BUNDLE_NAME" />.</translation>
 <translation id="1262876892872089030">Semasa tab ini tidak aktif, memori dikosongkan untuk mengekalkan kepantasan Chromium. Anda boleh memilih untuk sentiasa mengecualikan laman ini daripada menjadi tidak aktif.</translation>
 <translation id="1265577313130862557">Chromium menyekat muat turun ini kerana fail ini berbahaya</translation>
@@ -159,6 +160,7 @@
 <translation id="364817392622123556">{COUNT,plural, =0{Kemas kini baharu tersedia untuk Chromium dan akan digunakan sebaik sahaja anda melancarkan semula Chromium.}=1{Kemas kini baharu tersedia untuk Chromium dan akan digunakan sebaik sahaja anda melancarkan semula Chromium. Tetingkap Inkognito anda tidak dapat dibuka semula.}other{Kemas kini baharu tersedia untuk Chromium dan akan digunakan sebaik sahaja anda melancarkan semula Chromium. # tetingkap Inkognito anda tidak dapat dibuka semula.}}</translation>
 <translation id="3651803019964686660">Untuk menghantar nombor daripada <ph name="ORIGIN" /> ke telefon Android anda, log masuk ke Chromium pada kedua-dua peranti.</translation>
 <translation id="3667616615096815454">Tidak dapat memasang, aplikasi tidak dikenali oleh pelayan.</translation>
+<translation id="3669334504579945026">Untuk berkongsi skrin anda, benarkan rakaman skrin untuk Chromium dalam Pilihan Sistem.</translation>
 <translation id="3685209450716071127">Chromium tidak dapat menyemak kata laluan anda. Cuba periksa sambungan Internet anda.</translation>
 <translation id="3702352323269013324">Ketahui lebih lanjut tentang pemeribadian iklan dalam Chromium</translation>
 <translation id="370962675267501463">{COUNT,plural, =0{Pentadbir anda meminta anda melancarkan semula Chromium untuk menggunakan kemas kini ini}=1{Pentadbir anda meminta anda melancarkan semula Chromium untuk menggunakan kemas kini ini. Tetingkap Inkognito anda tidak dapat dibuka semula.}other{Pentadbir anda meminta anda melancarkan semula Chromium untuk menggunakan kemas kini ini. # tetingkap Inkognito anda tidak dapat dibuka semula.}}</translation>
@@ -461,6 +463,7 @@
 <translation id="8357820681460164151">Untuk mengakses bahan penyemak imbas Chromium anda pada semua peranti anda, log masuk, kemudian hidupkan penyegerakan</translation>
 <translation id="8360718212975266891">Untuk mendapatkan kemaskinian Chromium yang akan datang, anda memerlukan Windows 10 atau yang lebih baharu. Komputer ini menggunakan Windows 8.</translation>
 <translation id="8370517070665726704">Hak Cipta <ph name="YEAR" /> Google LLC. Hak cipta terpelihara.</translation>
+<translation id="837460953767177950">Kemudian, anda perlu memulakan semula Chromium.</translation>
 <translation id="8401454788024434101">Sambungan ini telah dinyahterbitkan boleh pembangun dan mungkin tidak selamat. Alih keluar sambungan ini daripada Chromium supaya sambungan ini tidak dapat melihat dan mengubah data anda pada laman yang anda lawati lagi, termasuk maklumat peribadi anda.</translation>
 <translation id="8417404458978023919">{0,plural, =1{Lancarkan semula Chromium dalam masa sehari}other{Lancarkan semula Chromium dalam masa # hari}}</translation>
 <translation id="8453117565092476964">Arkib pemasang rosak atau tidak sah. Sila muat turun Chromium sekali lagi.</translation>
diff --git a/chrome/app/resources/chromium_strings_my.xtb b/chrome/app/resources/chromium_strings_my.xtb
index fe05258..f3698e2 100644
--- a/chrome/app/resources/chromium_strings_my.xtb
+++ b/chrome/app/resources/chromium_strings_my.xtb
@@ -119,6 +119,7 @@
 <translation id="2945997411976714835">ထည့်သွင်းမှုအမှား- ထည့်သွင်းစနစ်လုပ်ဆောင်မှုကို စ၍မရပါ။</translation>
 <translation id="2977470724722393594">Chroumium ကို အပ်ဒိတ်လုပ်ထားပြီးပါပြီ</translation>
 <translation id="2977506796191543575">ဝဘ်ဆိုက်တစ်ခုက သင့်စကားဝှက်ကို ခိုးယူရန်ကြိုးပမ်းပါက (သို့) အန္တရာယ်ဖိုင်ကို သင်ဒေါင်းလုဒ်လုပ်ပါက Chromium သည် ‘လုံခြုံစွာကြည့်ရှုခြင်း’ သို့ URL များအပြင် စာမျက်နှာပါ အကြောင်းအရာအချို့ကို ပို့နိုင်သည်</translation>
+<translation id="2987208172821108655">သင်၏ဘရောက်စ်လုပ်ခြင်း ပိုကောင်းစေရန်နှင့် ရင်းမြစ်များတွင် နေရာလွတ် ပြုလုပ်ရန် Chromium က ဤတဘ်များကို ပိတ်စေနိုင်သည်။</translation>
 <translation id="3013473503895162900"><ph name="URL" /> ကို Chromium ၌ တဘ်အသစ်တွင် ဖွင့်မည်။</translation>
 <translation id="3032706164202344641">Chromium က သင့်စကားဝှက်များကို စစ်ဆေး၍မရပါ။ နောက်မှ ထပ်စမ်းကြည့်ပါ။</translation>
 <translation id="3032787606318309379">Chromium သို့ ထပ်ထည့်နေခြင်း...</translation>
@@ -321,6 +322,7 @@
 <translation id="6248213926982192922">Chromium ကို ပုံသေ ဘရောင်ဇာ လုပ်လိုက်ရန်</translation>
 <translation id="6266342355635466082">Chromium က အပ်ဒိတ်များကို စစ်ဆေး၍မရပါ။ သင့်အင်တာနက် ချိတ်ဆက်မှုကို စစ်ဆေးပါ။</translation>
 <translation id="6268381023930128611">Chromium မှထွက်မလား။</translation>
+<translation id="6270547683008298381">ဤတဘ်များသည် အပိုဆောင်းရင်းမြစ်များကို သုံးနေသည်။ သင့်စွမ်းဆောင်ရည် ပိုကောင်းစေရန် ၎င်းတို့ကို Chromium အား ပိတ်ခွင့်ပြုပါ။</translation>
 <translation id="6281746429495226318">သင့် Chromium ပရိုဖိုင်ကို စိတ်ကြိုက်လုပ်ရန်</translation>
 <translation id="6290827346642914212">သင်၏ Chromium ပရိုဖိုင်ကို အမည်ပေးပါ</translation>
 <translation id="6294831894865512704">နောက်ဆက်တွဲတစ်ခုက Chromium သို့ လက်မှတ်ထိုးဝင်စေလိုသည်</translation>
@@ -329,6 +331,7 @@
 <translation id="6327105987658262776">အပ်ဒိတ် မရှိပါ။</translation>
 <translation id="6333502561965082103">Chromium တွင် အခြားလုပ်ဆောင်ချက်တစ်ခု မပြီးပြတ်သေးပါ။ ခဏကြာမှ ထပ်လုပ်ကြည့်ပါ။</translation>
 <translation id="6334986366598267305">ယခုအခါ သင့် Google အကောင့်ဖြင့် Chromium နှင့် မျှဝေထားသည့် ကွန်ပျူတာများတွင် အသုံးပြုရ ပိုမိုလွယ်ကူလာပါသည်။</translation>
+<translation id="633626832589656416">သင်၏ဘရောက်စ်လုပ်ခြင်း ပိုကောင်းစေရန်နှင့် အရာရာကို မြန်ဆန်စေရန် Chromium က ဤတဘ်များကို ပိတ်စေနိုင်သည်။</translation>
 <translation id="6347933965114150440">Chromium ဖြတ်လမ်းလင့်ခ်</translation>
 <translation id="6366160072964553914">ဤဖိုင်ကို ဒေါင်းလုဒ်လုပ်လေ့မရှိသည့်အပြင် အန္တရာယ်ရှိနိုင်သဖြင့် Chromium က ဤဒေါင်းလုဒ်ကို ပိတ်ထားသည်</translation>
 <translation id="6373523479360886564">သင်သည် Google Chromium ကို ဖြုတ်ချင်တာ သေချာလား?</translation>
diff --git a/chrome/app/resources/chromium_strings_ne.xtb b/chrome/app/resources/chromium_strings_ne.xtb
index b3fdc6a5..00f8e19 100644
--- a/chrome/app/resources/chromium_strings_ne.xtb
+++ b/chrome/app/resources/chromium_strings_ne.xtb
@@ -119,6 +119,7 @@
 <translation id="2945997411976714835">इन्स्टल गर्ने क्रममा त्रुटि भयो: इन्स्टल गर्ने प्रक्रिया सुरु गर्न सकिएन।</translation>
 <translation id="2977470724722393594">Chromium अद्यावधिक छ</translation>
 <translation id="2977506796191543575">कुनै साइटले तपाईंको पासवर्ड चोरी गर्न खोज्दा वा तपाईंले कुनै हानिकारक फाइल डाउनलोड गर्दा Chromium ले पेजमा भएका केही सामग्रीसहित उक्त साइटका URL हरू Safe Browsing मा पठाउन पनि सक्छ</translation>
+<translation id="2987208172821108655">तपाईंलाई अझ राम्रो ब्राउजिङ सुविधा प्रदान गर्न र स्रोतहरू खाली पार्न Chromium ले यी ट्याब निष्क्रिय बनाउन सक्छ।</translation>
 <translation id="3013473503895162900">Chromium को नयाँ ट्याबमा <ph name="URL" /> खोल्नुहोस्।</translation>
 <translation id="3032706164202344641">Chromium ले तपाईंका पासवर्डहरूको जाँच गर्न सकेन। पछि फेरि प्रयास गर्नुहोस्।</translation>
 <translation id="3032787606318309379">Chromium मा थप्दै...</translation>
@@ -319,6 +320,7 @@
 <translation id="6248213926982192922">क्रोमियमलाई डिफल्ट ब्राउजर बनाउनुहोस्</translation>
 <translation id="6266342355635466082">Chromium ले अद्यावधिक छ वा छैन भन्ने कुराको जाँच गर्न सकेन। आफ्नो इन्टरनेट जडान जाँच गरी हेर्नुहोस्।</translation>
 <translation id="6268381023930128611">Chromium बाट साइन आउट गर्ने हो?</translation>
+<translation id="6270547683008298381">यी ट्याबले अतिरिक्त स्रोतहरू प्रयोग गरिरहेका छन्। पर्फर्मेन्स अझ राम्रो बनाउन Chromium लाई यी ट्याब निष्क्रिय बनाउन दिनुहोस्।</translation>
 <translation id="6281746429495226318">आफ्नो Chromium प्रोफाइल आफूले चाहे जस्तो बनाउनुहोस्</translation>
 <translation id="6290827346642914212">आफ्नो Chromium प्रोफाइलको नाम राख्नुहोस्</translation>
 <translation id="6294831894865512704">एउटा एक्स्टेन्सनले तपाईंलाई Chromium मा साइन गर्न अनुरोध गरिरहेको छ</translation>
@@ -327,6 +329,7 @@
 <translation id="6327105987658262776">कुनै पनि अपडेट उपलब्ध छैन।</translation>
 <translation id="6333502561965082103">Chromium मा अर्को कारबाही जारी छ। कृपया पछि फेरि प्रयास गर्नुहोस्।</translation>
 <translation id="6334986366598267305">अब तपाइँको Google खातासँग र साझा गरिएका कम्प्युटरहरूसँग Chromium प्रयोग गर्न सजिलो छ।</translation>
+<translation id="633626832589656416">तपाईंलाई अझ राम्रो ब्राउजिङ सुविधा प्रदान गर्न र साइटहरू छिटो खुल्ने बनाउन Chromium ले यी ट्याब निष्क्रिय बनाउन सक्छ।</translation>
 <translation id="6347933965114150440">Chromium को सर्टकट</translation>
 <translation id="6366160072964553914">यो फाइल सामान्यतया डाउनलोड नगरिने र खतरनाक हुन सक्ने भएकाले Chromium ले यो फाइल डाउनलोड गर्ने कार्य ब्लक गरेको छ</translation>
 <translation id="6373523479360886564">के तपाइँ पक्का हुनुहुन्छ कि तपाइँ Chromium विस्थापित गर्न चाहनुहुन्छ?</translation>
diff --git a/chrome/app/resources/chromium_strings_nl.xtb b/chrome/app/resources/chromium_strings_nl.xtb
index b3dc0e9..bd5ff79d 100644
--- a/chrome/app/resources/chromium_strings_nl.xtb
+++ b/chrome/app/resources/chromium_strings_nl.xtb
@@ -15,6 +15,7 @@
 <translation id="1131805035311359397">Als je wilt checken of je wachtwoorden zijn beveiligd tegen gegevenslekken en andere beveiligingsproblemen, <ph name="BEGIN_LINK" />log je in bij Chromium<ph name="END_LINK" />.</translation>
 <translation id="1153368717515616349">Klik op het Chromium-menu</translation>
 <translation id="1185134272377778587">Over Chromium</translation>
+<translation id="1188705220418984327">Als je je venster wilt delen, sta je schermopname voor Chromium toe in Systeemvoorkeuren.</translation>
 <translation id="1203500561924088507">Bedankt voor het installeren. Je moet de browser opnieuw opstarten voordat je <ph name="BUNDLE_NAME" /> kunt gebruiken.</translation>
 <translation id="1262876892872089030">Terwijl dit tabblad inactief was, is er geheugen vrijgemaakt om Chromium snel te houden. Je kunt ervoor kiezen deze site altijd uit te sluiten van inactiviteit.</translation>
 <translation id="1265577313130862557">Chromium heeft deze download geblokkeerd, omdat het bestand gevaarlijk is</translation>
@@ -161,6 +162,7 @@
 <translation id="364817392622123556">{COUNT,plural, =0{Er is een nieuwe update voor Chromium beschikbaar die wordt uitgevoerd zodra je het programma opnieuw start.}=1{Er is een nieuwe update voor Chromium beschikbaar die wordt uitgevoerd zodra je het programma opnieuw start. Je incognitovenster kan niet opnieuw worden geopend.}other{Er is een nieuwe update voor Chromium beschikbaar die wordt uitgevoerd zodra je het programma opnieuw start. Je # incognitovensters kunnen niet opnieuw worden geopend.}}</translation>
 <translation id="3651803019964686660">Als je een nummer vanaf <ph name="ORIGIN" /> naar je Android-telefoon wilt sturen, log je in bij Chromium op beide apparaten.</translation>
 <translation id="3667616615096815454">Kan niet installeren. De app is niet bekend bij de server.</translation>
+<translation id="3669334504579945026">Als je je scherm wilt delen, sta je schermopname voor Chromium toe in Systeemvoorkeuren.</translation>
 <translation id="3685209450716071127">Chromium kan je wachtwoorden niet checken. Check de internetverbinding.</translation>
 <translation id="3702352323269013324">Meer informatie over advertentiepersonalisatie in Chromium</translation>
 <translation id="370962675267501463">{COUNT,plural, =0{Je beheerder vraagt je Chromium opnieuw te starten om deze update uit te voeren.}=1{Je beheerder vraagt je Chromium opnieuw te starten om deze update uit te voeren. Je incognitovenster kan niet opnieuw worden geopend.}other{Je beheerder vraagt je Chromium opnieuw te starten om deze update uit te voeren. Je # incognitovensters kunnen niet opnieuw worden geopend.}}</translation>
@@ -462,6 +464,7 @@
 <translation id="8357820681460164151">Log in en zet synchronisatie aan voor toegang tot je Chromium-browsergegevens op al je apparaten</translation>
 <translation id="8360718212975266891">Als je toekomstige Chromium-updates wilt krijgen, heb je Windows 10 of hoger nodig. Deze computer gebruikt Windows 8.</translation>
 <translation id="8370517070665726704">Copyright <ph name="YEAR" /> Google LLC. Alle rechten voorbehouden.</translation>
+<translation id="837460953767177950">Start Chromium daarna opnieuw op.</translation>
 <translation id="8401454788024434101">De publicatie van deze extensie is ongedaan gemaakt door de ontwikkelaar en deze is mogelijk onveilig. Verwijder de extensie van Chromium zodat deze je gegevens (waaronder je persoonlijke informatie) niet meer kan bekijken en wijzigen op sites die je bezoekt.</translation>
 <translation id="8417404458978023919">{0,plural, =1{Start Chromium binnen een dag opnieuw}other{Start Chromium binnen # dagen opnieuw}}</translation>
 <translation id="8453117565092476964">Het archief van het installatieprogramma is beschadigd of ongeldig. Download Chromium opnieuw.</translation>
diff --git a/chrome/app/resources/chromium_strings_ro.xtb b/chrome/app/resources/chromium_strings_ro.xtb
index 3409d1d..cd086272 100644
--- a/chrome/app/resources/chromium_strings_ro.xtb
+++ b/chrome/app/resources/chromium_strings_ro.xtb
@@ -116,6 +116,7 @@
 <translation id="2945997411976714835">Eroare la instalare: procesul programului de instalare nu a început.</translation>
 <translation id="2977470724722393594">Chromium este actualizat</translation>
 <translation id="2977506796191543575">Dacă un site încearcă să îți fure parola sau descarci un fișier dăunător, Chromium poate să trimită adresele URL, inclusiv fragmente din conținutul paginilor, către funcția Navigare sigură</translation>
+<translation id="2987208172821108655">Chromium poate dezactiva aceste file pentru a-ți îmbunătăți experiența de navigare și pentru a elibera resurse.</translation>
 <translation id="3013473503895162900">Deschide <ph name="URL" /> într-o filă nouă în Chromium.</translation>
 <translation id="3032706164202344641">Chromium nu îți poate verifica parolele. Încearcă din nou mai târziu.</translation>
 <translation id="3032787606318309379">Se adaugă la Chromium...</translation>
@@ -317,6 +318,7 @@
 <translation id="6248213926982192922">Setați Chromium ca browser prestabilit</translation>
 <translation id="6266342355635466082">Chromium nu poate căuta actualizări. Verifică-ți conexiunea la internet.</translation>
 <translation id="6268381023930128611">Te deconectezi de la Chromium?</translation>
+<translation id="6270547683008298381">Aceste file folosesc resurse suplimentare. Pentru a îmbunătăți performanța, permite-i browserului Chromium să le dezactiveze.</translation>
 <translation id="6281746429495226318">Personalizează-ți profilul Chromium</translation>
 <translation id="6290827346642914212">Denumește profilul Chromium</translation>
 <translation id="6294831894865512704">O extensie solicită să te conectezi la Chromium</translation>
@@ -325,6 +327,7 @@
 <translation id="6327105987658262776">Nu este disponibilă nicio actualizare.</translation>
 <translation id="6333502561965082103">O altă operație din Chromium este în curs de desfășurare. Încearcă din nou mai târziu.</translation>
 <translation id="6334986366598267305">Acum este mai ușor să folosiți Chromium cu Contul Google și pe computerele utilizate în comun.</translation>
+<translation id="633626832589656416">Chromium poate dezactiva aceste file pentru a-ți îmbunătăți experiența de navigare și pentru a menține viteza ridicată.</translation>
 <translation id="6347933965114150440">Comandă rapidă pentru Chromium</translation>
 <translation id="6366160072964553914">Chromium a blocat descărcarea, deoarece fișierul nu este descărcat frecvent și ar putea fi periculos</translation>
 <translation id="6373523479360886564">Sigur doriți să dezinstalați Chromium?</translation>
diff --git a/chrome/app/resources/chromium_strings_ru.xtb b/chrome/app/resources/chromium_strings_ru.xtb
index f4693bc..2223a20 100644
--- a/chrome/app/resources/chromium_strings_ru.xtb
+++ b/chrome/app/resources/chromium_strings_ru.xtb
@@ -116,6 +116,7 @@
 <translation id="2945997411976714835">Произошла ошибка. Не удалось начать установку.</translation>
 <translation id="2977470724722393594">Вы используете последнюю версию Chromium</translation>
 <translation id="2977506796191543575">Если вы скачаете вредоносный файл или сайт попытается похитить ваш пароль, Chromium может отправить URL с образцами контента на проверку с помощью Безопасного просмотра.</translation>
+<translation id="2987208172821108655">Чтобы повысить производительность браузера Chromium и удобство работы в нем, эти вкладки можно сделать неактивными.</translation>
 <translation id="3013473503895162900">Открыть <ph name="URL" /> в новой вкладке в Chromium.</translation>
 <translation id="3032706164202344641">Не удается запустить проверку паролей в Chromium. Повторите попытку позже.</translation>
 <translation id="3032787606318309379">Добавление в Chromium...</translation>
@@ -315,6 +316,7 @@
 <translation id="6248213926982192922">Назначить Chromium браузером по умолчанию</translation>
 <translation id="6266342355635466082">Не удалось проверить наличие обновлений в Chromium. Проверьте подключение к Интернету.</translation>
 <translation id="6268381023930128611">Выйти из Chromium?</translation>
+<translation id="6270547683008298381">Чтобы поддерживать работу этих вкладок, используется оперативная память. Разрешите Chromium сделать их неактивными, и производительность повысится.</translation>
 <translation id="6281746429495226318">Настроить профиль Chromium</translation>
 <translation id="6290827346642914212">Настройте профиль Chromium</translation>
 <translation id="6294831894865512704">Расширение запрашивает вход в Chromium</translation>
@@ -323,6 +325,7 @@
 <translation id="6327105987658262776">Нет обновлений.</translation>
 <translation id="6333502561965082103">Chromium выполняет другую операцию. Повторите попытку позже.</translation>
 <translation id="6334986366598267305">Теперь с Chromium ещё удобнее работать в аккаунте Google, в том числе на общих компьютерах.</translation>
+<translation id="633626832589656416">Чтобы повысить скорость браузера Chromium и удобство работы в нем, эти вкладки можно сделать неактивными.</translation>
 <translation id="6347933965114150440">Ярлык Chromium</translation>
 <translation id="6366160072964553914">Chromium заблокировал скачивание, поскольку этот файл скачивают редко и он может быть опасен</translation>
 <translation id="6373523479360886564">Вы действительно хотите удалить Chromium?</translation>
diff --git a/chrome/app/resources/chromium_strings_sk.xtb b/chrome/app/resources/chromium_strings_sk.xtb
index 861eb0a..8510fd5 100644
--- a/chrome/app/resources/chromium_strings_sk.xtb
+++ b/chrome/app/resources/chromium_strings_sk.xtb
@@ -118,6 +118,7 @@
 <translation id="2945997411976714835">Chyba inštalácie: proces inštalátora sa nespustil.</translation>
 <translation id="2977470724722393594">Prehliadač Chromium bol aktualizovaný</translation>
 <translation id="2977506796191543575">Ak sa vám určitý web pokúsi ukradnúť heslo alebo stiahnete škodlivý súbor, Chromium môže odoslať Bezpečnému prehliadaniu aj webové adresy vrátane častí obsahu stránok</translation>
+<translation id="2987208172821108655">Prehliadač Chromium môže tieto karty deaktivovať, aby zlepšil prehliadanie a uvoľnil zdroje.</translation>
 <translation id="3013473503895162900">Otvorte <ph name="URL" /> na novej karte v prehliadači Chromium.</translation>
 <translation id="3032706164202344641">Chromium nemôže skontrolovať heslá. Skúste to neskôr.</translation>
 <translation id="3032787606318309379">Pridáva sa do prehliadača Chromium...</translation>
@@ -319,6 +320,7 @@
 <translation id="6248213926982192922">Nastavte Chromium ako svoj predvolený prehliadač</translation>
 <translation id="6266342355635466082">Chromium nemôže skontrolovať dostupnosť aktualizácií. Skontrolujte internetové pripojenie.</translation>
 <translation id="6268381023930128611">Odhlásiť sa z prehliadača Chromium?</translation>
+<translation id="6270547683008298381">Tieto karty spotrebúvajú dodatočné zdroje. Prehliadač Chromium ich môže deaktivovať, aby zlepšil výkon.</translation>
 <translation id="6281746429495226318">Prispôsobiť profil prehliadača Chromium</translation>
 <translation id="6290827346642914212">Názov vášho profilu Chromium</translation>
 <translation id="6294831894865512704">Rozšírenie vyžaduje, aby ste sa prihlásili do prehliadača Chromium</translation>
@@ -327,6 +329,7 @@
 <translation id="6327105987658262776">K dispozícii nie je žiadna aktualizácia.</translation>
 <translation id="6333502561965082103">V prehliadači Chromium práve prebieha iná operácia. Skúste to neskôr.</translation>
 <translation id="6334986366598267305">Teraz je používanie prehliadača Chromium s účtom Google a na zdieľaných počítačoch oveľa ľahšie.</translation>
+<translation id="633626832589656416">Prehliadač Chromium môže tieto karty deaktivovať, aby zlepšil prehliadanie a zachoval rýchlosť.</translation>
 <translation id="6347933965114150440">Odkaz na Chromium</translation>
 <translation id="6366160072964553914">Prehliadač Chromium toto sťahovanie zablokoval, pretože používatelia tento súbor bežne nesťahujú a môže byť nebezpečný</translation>
 <translation id="6373523479360886564">Naozaj chcete Chromium odinštalovať?</translation>
diff --git a/chrome/app/resources/chromium_strings_sw.xtb b/chrome/app/resources/chromium_strings_sw.xtb
index fa6c3ab..fdfced6 100644
--- a/chrome/app/resources/chromium_strings_sw.xtb
+++ b/chrome/app/resources/chromium_strings_sw.xtb
@@ -118,6 +118,7 @@
 <translation id="2945997411976714835">Hitilafu ya kusakinisha: Mchakato wa kisakinishaji umeshindwa kuanza.</translation>
 <translation id="2977470724722393594">Chromium imesasishwa</translation>
 <translation id="2977506796191543575">Ikiwa tovuti inajaribu kuiba nenosiri lako au unapopakua faili hatari, Chromium inaweza pia kutuma URL, ikiwa ni pamoja na sehemu za maudhui ya ukurasa, kwenye kipengele cha Kuvinjari Salama</translation>
+<translation id="2987208172821108655">Chromium inaweza kufanya vichupo hivi visitumike ili kuboresha hali yako ya kuvinjari na kufuta data ili upate nyenzo.</translation>
 <translation id="3013473503895162900">Fungua <ph name="URL" /> kwenye kichupo kipya katika Chromium.</translation>
 <translation id="3032706164202344641">Chromium imeshindwa kukagua manenosiri yako. Jaribu tena baadaye.</translation>
 <translation id="3032787606318309379">Inaongeza kwenye Chromium...</translation>
@@ -319,6 +320,7 @@
 <translation id="6248213926982192922">Fanya Chromium kuwa kivinjari chaguomsingi</translation>
 <translation id="6266342355635466082">Chromium imeshindwa kukagua masasisho. Jaribu kuangalia muunganisho wako wa Intaneti.</translation>
 <translation id="6268381023930128611">Ungependa kuondoka kwenye Chromium?</translation>
+<translation id="6270547683008298381">Vichupo hivi vinatumia nyenzo za ziada. Ili kuboresha utendaji wako, ruhusu Chromium ivifanye visitumike.</translation>
 <translation id="6281746429495226318">Weka mapendeleo ya wasifu wako kwenye Chromium</translation>
 <translation id="6290827346642914212">Upe wasifu wako wa Chromium jina</translation>
 <translation id="6294831894865512704">Kiendelezi kinakuhitaji uingie katika akaunti kwenye Chromium</translation>
@@ -327,6 +329,7 @@
 <translation id="6327105987658262776">Hakuna sasisho linalopatikana.</translation>
 <translation id="6333502561965082103">Shughuli nyingine zinaendelea kwenye Chromium. Tafadhali jaribu tena baadaye.</translation>
 <translation id="6334986366598267305">Sasa ni rahisi zaidi kutumia Chromium pamoja na Akaunti yako ya Google na kwenye kompyuta zinazoshirikiwa.</translation>
+<translation id="633626832589656416">Chromium inaweza kufanya vichupo hivi visitumike ili kuboresha hali yako ya kuvinjari na kutekeleza shughuli kwa haraka.</translation>
 <translation id="6347933965114150440">Njia ya Mkato ya Chromium</translation>
 <translation id="6366160072964553914">Chromium imezuia upakuaji huu kwa sababu faili hii kwa kawaida haipakuliwi na huenda si salama</translation>
 <translation id="6373523479360886564">Je, una hakika unataka kusanidua Chromium?</translation>
diff --git a/chrome/app/resources/chromium_strings_uz.xtb b/chrome/app/resources/chromium_strings_uz.xtb
index 2a44fa1f..525ef75 100644
--- a/chrome/app/resources/chromium_strings_uz.xtb
+++ b/chrome/app/resources/chromium_strings_uz.xtb
@@ -13,6 +13,7 @@
 <translation id="1131805035311359397">Parollarni axborotlar sizib chiqishi va xavfsizlikka oid boshqa muammolardan himoyalash uchun <ph name="BEGIN_LINK" />Chromium hisobingizga kiring<ph name="END_LINK" />.</translation>
 <translation id="1153368717515616349">Chromium menyusini bosing</translation>
 <translation id="1185134272377778587">Chromium haqida</translation>
+<translation id="1188705220418984327">Oynani ulashish uchun tizim sozlamalarida Chromium brauzeriga ekranni yozib olish uchun ruxsat bering.</translation>
 <translation id="1203500561924088507">Oʻrnatganingiz uchun tashakkur! <ph name="BUNDLE_NAME" />ni ishlatishdan oldin brauzerni qayta ishga tushirishingiz lozim.</translation>
 <translation id="1262876892872089030">Bu varaq nonfaol boʻlganida Chromium tezroq ishlashi uchun xotira boʻshatiladi. Bu saytni har doim nofaol boʻlmasligini tanlash mumkin.</translation>
 <translation id="1265577313130862557">Chromium bu yuklamani blokladi, chunki bu fayl xavfli</translation>
@@ -157,6 +158,7 @@
 <translation id="364817392622123556">{COUNT,plural, =0{Chromium uchun yangilanish mavjud va brauzer qayta ishga tushirilganda oʻrnatiladi.}=1{Chromium uchun yangilanish mavjud va brauzer qayta ishga tushirilganda oʻrnatiladi. Inkognito oynalar qayta ochilmaydi.}other{Chromium uchun yangilanish mavjud va brauzer qayta ishga tushirilganda oʻrnatiladi. # ta inkognito oyna qayta ochilmaydi.}}</translation>
 <translation id="3651803019964686660"><ph name="ORIGIN" /> orqali Android telefoningizga raqam yuborish uchun ikkala qurilmada Chromium hisobingizga kiring.</translation>
 <translation id="3667616615096815454">Oʻrnatilmadi, ilova serverga nomaʼlum.</translation>
+<translation id="3669334504579945026">Ekranni ulashish uchun tizim sozlamalarida Chromium uchun ekranni yozib olishga ruxsat bering.</translation>
 <translation id="3685209450716071127">Chromium parollaringizni tekshira olmadi. Internet aloqasini tekshiring.</translation>
 <translation id="3702352323269013324">Chromiumda reklamani moslashtirish haqida batafsil</translation>
 <translation id="370962675267501463">{COUNT,plural, =0{Administrator yangilishlarni oʻrnatish uchun Chromium brauzerini qayta ishga tushirishni soʻramoqda}=1{Administrator yangilishlarni oʻrnatish uchun Chromium brauzerini qayta ishga tushirishni soʻramoqda Inkognito oynalar qayta ochilmaydi.}other{Administrator yangilishlarni oʻrnatish uchun Chromium brauzerini qayta ishga tushirishni soʻramoqda # ta inkognito oyna qayta ochilmaydi.}}</translation>
@@ -459,6 +461,7 @@
 <translation id="8357820681460164151">Chromium brauzeridagi axborotlardan barcha qurilmalaringizda foydalanish uchun hisobingizga kiring va sinxronizatsiyani yoqing</translation>
 <translation id="8360718212975266891">Chromium yangilanishlari Windows 10 yoki undan yuqori versiyalarda ishlaydi. Bu kompyuterdagi versiya: Windows 8.</translation>
 <translation id="8370517070665726704">© Google LLC, <ph name="YEAR" /> Barcha huquqlar himoyalangan.</translation>
+<translation id="837460953767177950">Keyin Chromium qayta ishga tushirilishi kerak.</translation>
 <translation id="8401454788024434101">Bu kengaytma dasturchisi uning nashrini bekor qildi va u xavfli boʻlishi mumkin. Ochilgan saytlarda shaxsiy axborot kabi maʼlumotlarni koʻrishi va oʻzgartirishini tugatish uchun uni Chromiumdan olib tashlang.</translation>
 <translation id="8417404458978023919">{0,plural, =1{Chromiumni 1 kun ichida qayta ishga tushiring}other{Chromiumni # kun ichida qayta ishga tushiring}}</translation>
 <translation id="8453117565092476964">O‘rnatish dasturi arxivi shikastlangan. Chromium‘ni qaytadan yuklab oling.</translation>
diff --git a/chrome/app/resources/chromium_strings_vi.xtb b/chrome/app/resources/chromium_strings_vi.xtb
index 008608e..63c9d9a4 100644
--- a/chrome/app/resources/chromium_strings_vi.xtb
+++ b/chrome/app/resources/chromium_strings_vi.xtb
@@ -117,6 +117,7 @@
 <translation id="2945997411976714835">Lỗi cài đặt: Trình cài đặt không thể bắt đầu quá trình.</translation>
 <translation id="2977470724722393594">Chromium đã được cập nhật</translation>
 <translation id="2977506796191543575">Nếu một trang web cố ăn cắp mật khẩu của bạn hoặc nếu bạn tải một tệp gây hại xuống, thì Chromium cũng có thể gửi các URL đến tính năng Duyệt web an toàn, bao gồm cả các đoạn nội dung trên trang</translation>
+<translation id="2987208172821108655">Chromium có thể dừng hoạt động của các thẻ này để cải thiện trải nghiệm duyệt web của bạn và giải phóng tài nguyên.</translation>
 <translation id="3013473503895162900">Mở <ph name="URL" /> trong một thẻ mới trên Chromium.</translation>
 <translation id="3032706164202344641">Chromium không thể kiểm tra mật khẩu của bạn. Hãy thử lại sau.</translation>
 <translation id="3032787606318309379">Đang thêm vào Chromium...</translation>
@@ -319,6 +320,7 @@
 <translation id="6248213926982192922">Đặt Chromium làm trình duyệt mặc định</translation>
 <translation id="6266342355635466082">Chromium không thể kiểm tra các bản cập nhật. Hãy thử kiểm tra kết nối Internet.</translation>
 <translation id="6268381023930128611">Đăng xuất khỏi Chromium?</translation>
+<translation id="6270547683008298381">Các thẻ này đang sử dụng thêm tài nguyên. Để cải thiện hiệu suất, hãy cho phép Chromium dừng hoạt động của các thẻ này.</translation>
 <translation id="6281746429495226318">Tùy chỉnh hồ sơ Chromium của bạn</translation>
 <translation id="6290827346642914212">Đặt tên cho hồ sơ của bạn trên Chromium</translation>
 <translation id="6294831894865512704">Một tiện ích muốn bạn đăng nhập vào Chromium</translation>
@@ -327,6 +329,7 @@
 <translation id="6327105987658262776">Hiện không có bản cập nhật nào.</translation>
 <translation id="6333502561965082103">Một hoạt động khác trên Chromium đang diễn ra. Vui lòng thử lại sau.</translation>
 <translation id="6334986366598267305">Giờ đây, việc sử dụng Chromium bằng tài khoản Google của bạn và trên máy tính dùng chung trở nên dễ dàng hơn.</translation>
+<translation id="633626832589656416">Chromium có thể dừng hoạt động của các thẻ này để cải thiện và tăng tốc trải nghiệm duyệt web của bạn.</translation>
 <translation id="6347933965114150440">Lối tắt tới Chromium</translation>
 <translation id="6366160072964553914">Chromium đã chặn tệp tải xuống này vì tệp này ít được tải xuống và có thể nguy hiểm</translation>
 <translation id="6373523479360886564">Bạn có chắc chắn muốn gỡ cài đặt Chromium không?</translation>
diff --git a/chrome/app/resources/chromium_strings_zh-HK.xtb b/chrome/app/resources/chromium_strings_zh-HK.xtb
index ca173e0..2b19a3fa 100644
--- a/chrome/app/resources/chromium_strings_zh-HK.xtb
+++ b/chrome/app/resources/chromium_strings_zh-HK.xtb
@@ -118,6 +118,7 @@
 <translation id="2945997411976714835">安裝錯誤:安裝程式程序無法開始。</translation>
 <translation id="2977470724722393594">Chromium 已是最新版本</translation>
 <translation id="2977506796191543575">如果有網站試圖盜取您的密碼,或當您下載有害檔案時,Chromium 亦可能將網址 (包括部分網頁內容) 傳送至「安全瀏覽」功能</translation>
+<translation id="2987208172821108655">Chromium 可讓這些分頁處於閒置狀態,改善瀏覽體驗並釋出資源。</translation>
 <translation id="3013473503895162900">在 Chromium 中的新分頁開啟 <ph name="URL" />。</translation>
 <translation id="3032706164202344641">Chromium 無法檢查密碼,請稍後再試。</translation>
 <translation id="3032787606318309379">正在新增至 Chromium…</translation>
@@ -319,6 +320,7 @@
 <translation id="6248213926982192922">將 Chromium 設為預設瀏覽器</translation>
 <translation id="6266342355635466082">Chromium 無法檢查更新,請檢查互聯網連線。</translation>
 <translation id="6268381023930128611">要登出 Chromium 嗎?</translation>
+<translation id="6270547683008298381">這些分頁正在使用額外的資源。為提升效能,請讓 Chromium 將其設定為閒置分頁。</translation>
 <translation id="6281746429495226318">自訂您的 Chromium 設定檔</translation>
 <translation id="6290827346642914212">為 Chromium 設定檔命名</translation>
 <translation id="6294831894865512704">擴充程式需要你登入 Chromium</translation>
@@ -327,6 +329,7 @@
 <translation id="6327105987658262776">沒有可用的更新。</translation>
 <translation id="6333502561965082103">Chromium 正在執行另一項操作,請稍後再試。</translation>
 <translation id="6334986366598267305">無論是登入 Google 帳戶使用 Chromium,還是以 Google 帳戶使用共用電腦,現在都更輕而易舉。</translation>
+<translation id="633626832589656416">Chromium 可讓這些分頁處於閒置狀態,改善瀏覽體驗並維持快速運作。</translation>
 <translation id="6347933965114150440">Chromium 捷徑</translation>
 <translation id="6366160072964553914">由於此檔案不是常見的下載項目,可能含有危險內容,因此 Chromium 已禁止下載</translation>
 <translation id="6373523479360886564">您確定要解除安裝 Chromium 嗎?</translation>
diff --git a/chrome/app/resources/chromium_strings_zu.xtb b/chrome/app/resources/chromium_strings_zu.xtb
index 2f5c98e..9a07a5dc 100644
--- a/chrome/app/resources/chromium_strings_zu.xtb
+++ b/chrome/app/resources/chromium_strings_zu.xtb
@@ -118,6 +118,7 @@
 <translation id="2945997411976714835">Iphutha lokufaka: Inqubo yesifaki yehlulekile ukuqala.</translation>
 <translation id="2977470724722393594">I-Chromium isesikhathini samanje</translation>
 <translation id="2977506796191543575">Uma isayithi lizama ukuntshontsha iphasiwedi yakho, noma uma ulanda ifayela eliyingozi, i-Chromium ingathumela nama-URL, kuhlanganise nokuthile okuqukethwe kulelo khasi, Ekuphequluleni Okuphephile</translation>
+<translation id="2987208172821108655">IChromium ingenza lawa mathebhu angasebenzi ukuze ithuthukise okwenzekayo lapho ubhrawuza iphinde ikhulule izinsiza.</translation>
 <translation id="3013473503895162900">Vula i-<ph name="URL" /> kuthebhu entsha ku-Chromium.</translation>
 <translation id="3032706164202344641">I-Chromium ayikwazi ukuhlola iphasiwedi yakho. Zama futhi emuva kwesikhathi.</translation>
 <translation id="3032787606318309379">Ingeza ku-Chromium...</translation>
@@ -319,6 +320,7 @@
 <translation id="6248213926982192922">Yenza i-Chromium ibe yisiphequluli esizenzakalelayo</translation>
 <translation id="6266342355635466082">I-Chromium ayikwazi ukuhlola izibuyekezo. Zama ukuhlola ukuxhumeka kwakho ku-inthanethi.</translation>
 <translation id="6268381023930128611">Phuma ku-Chromium?</translation>
+<translation id="6270547683008298381">Lawa mathebhu asebenzisa izinsiza ezengeziwe. Ukuze uthuthukise ukusebenza kwakho, vumela iChromium iwenze angasebenzi.</translation>
 <translation id="6281746429495226318">Yenza ngokwezifiso iphrofayela yakho ye-Chromium</translation>
 <translation id="6290827346642914212">Qama iphrofayela lakho le-Chromium</translation>
 <translation id="6294831894865512704">Isandiso sifuna ukuthi ungene kuChromium</translation>
@@ -327,6 +329,7 @@
 <translation id="6327105987658262776">Asikho isibuyekezo esitholakalayo.</translation>
 <translation id="6333502561965082103">Okunye ukusebenza ku-Chromium kuyaqhubeka. Sicela uzame futhi emuva kwesikhathi.</translation>
 <translation id="6334986366598267305">Manje kulula ukusebenzisa i-Chromium nge-Akhawunti yakho ye-Google nakumakhompyutha abiwe.</translation>
+<translation id="633626832589656416">IChromium ingenza lawa mathebhu engasebenzi ukuze ithuthukise okwenzekayo lapho ubhrawuza iphinde igcine izinto zishesha.</translation>
 <translation id="6347933965114150440">Isinqamuleli se-Chromium</translation>
 <translation id="6366160072964553914">I-Chromium ivimbele lokhu kudawunilodwa ngoba ifayela alivamile ukudawunilodwa futhi lingase libe yingozi</translation>
 <translation id="6373523479360886564">Ingabe uqinisekile ukuthi ufuna ukukhipha i-Chromium?</translation>
diff --git a/chrome/app/resources/generated_resources_am.xtb b/chrome/app/resources/generated_resources_am.xtb
index 83c216a..c72ef06 100644
--- a/chrome/app/resources/generated_resources_am.xtb
+++ b/chrome/app/resources/generated_resources_am.xtb
@@ -973,6 +973,7 @@
 <translation id="1697150536837697295">ሥነ ጥበብ</translation>
 <translation id="1697686431566694143">ፋይል አርትዕ ያድርጉ</translation>
 <translation id="1698796500103229697">&amp;የመክፈያ ዘዴዎች</translation>
+<translation id="1698899521169711967">የጽሑፍ ጠቋሚ አሰሳ</translation>
 <translation id="1699807488537653303">የይለፍ ቃል ስህተትን ያስተካክሉ</translation>
 <translation id="1700201317341192482">ምናባዊ ካርድዎን ያስወግዱ</translation>
 <translation id="1700517974991662022">ተጎብኝቷል</translation>
@@ -2478,6 +2479,7 @@
 <translation id="2771816809568414714">ቺዝ</translation>
 <translation id="2772936498786524345">Sneaky</translation>
 <translation id="2773288106548584039">የቆየ የአሳሽ ድጋፍ</translation>
+<translation id="2773621783913034737">ትሮችን አቦዝን</translation>
 <translation id="2773802008104670137">ይህ የፋይል ዓይነት የእርስዎን ኮምፒውተር ሊጎዳ ይችላል።</translation>
 <translation id="2775104091073479743">የጣት አሻራዎችን አርትዕ</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{ቅጥያ «<ph name="EXTENSION" />» መሣሪያዎችን እየደረሰ ነበር}=1{ቅጥያ «<ph name="EXTENSION" />» {0} መሣሪያ እየደረሰ ነው}one{ቅጥያ «<ph name="EXTENSION" />» {0} መሣሪያ እየደረሰ ነው}other{ቅጥያ «<ph name="EXTENSION" />» {0} መሣሪያዎችን እየደረሰ ነው}}</translation>
@@ -2558,6 +2560,7 @@
 <translation id="2830528677948328648">የእርስዎን Google መለያ ያስተዳድሩ</translation>
 <translation id="2831430281393059038">መሣሪያ ይደገፋል</translation>
 <translation id="2832124733806557606">ልጅዎ ወደ መሣሪያው ለመግባት ወይም ለመክፈት ፒን መጠቀም ይችላል።</translation>
+<translation id="2833144527504272627">በጽሁፍ ጠቋሚ ያስሱ</translation>
 <translation id="2835177225987815960">ማናቸውም የተመደቡ መቀየሪያዎች እና የራስ-ቅኝት ፍጥነት ምርጫዎች ጨምሮ የአሁኑ የፍተሻ ውቅረትዎ ዳግም ይጀመራል።</translation>
 <translation id="2835547721736623118">የንግግር ማወቂያ አገልግሎት</translation>
 <translation id="2835761321523638096">በንባብ ዝርዝሩ ውስጥ ያሉ ግቤቶችን ያንብቡ እና ይለውጡ</translation>
@@ -4114,6 +4117,7 @@
 <translation id="3978325380690188371">ተጣባቂ ቁልፎች ChromeVox በሚበራበት ጊዜ አይገኙም</translation>
 <translation id="3979395879372752341">አዲስ ቅጥያ ታክሏል (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326"><ph name="NETWORKDEVICE" />ን አንቃ</translation>
+<translation id="398095528354975981">እነዚህን ትሮች ደብቅ</translation>
 <translation id="3981058120448670012">ለ<ph name="REMAINING_TIME" /> በአቅራቢያ ላሉ መሣሪያዎች እንደ <ph name="DEVICE_NAME" /> ሆኖ ይታያል...</translation>
 <translation id="3981760180856053153">ልክ ያልሆነ የማስቀመጥ ዓይነት ገብቷል።</translation>
 <translation id="3982375475032951137">የእርስዎን አሳሽ በጥቂት ቀላል እርምጃዎችን ያቀናብሩ</translation>
@@ -6304,6 +6308,7 @@
 <translation id="5642508497713047">CRL ፈራሚ</translation>
 <translation id="5643191124441701136">የደህንነት ኮድዎ በካርድዎ ፊት ለፊት ነው</translation>
 <translation id="5643321261065707929">የሚለካ አውታረ መረብ</translation>
+<translation id="5643717184207603910">አፈጻጸምን ፈጣን አድርገው ያቆዩ</translation>
 <translation id="5646376287012673985">አካባቢ</translation>
 <translation id="5646558797914161501">ነጋዴ</translation>
 <translation id="5648021990716966815">የማይክሮፎን መሰኪያ</translation>
@@ -6408,6 +6413,7 @@
 <translation id="5733109311583381874">የልወጣ እጩዎችን ለማበጀት የራስዎን ቃላት ወደ የተጠቃሚ መዝገበ ቃላት ያክሉ።</translation>
 <translation id="5734362860645681824">ተግባቦት</translation>
 <translation id="5734697361979786483">ፋይል አጋራን ያክሉ</translation>
+<translation id="5735513236153491131">አሁን ጨምር</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{ይህ ውሂብ ወይም የእርስዎ መሣሪያ አንዳንድ የድርጅትዎን የደህንነት መመሪያዎች አያሟላም። ምን መስተካከል እንዳለበት ለማወቅ አስተዳዳሪዎን ያነጋግሩ።}=1{ይህ ፋይል ወይም የእርስዎ መሣሪያ አንዳንድ የድርጅትዎን የደህንነት መመሪያዎች አያሟላም። ምን መስተካከል እንዳለበት ለማወቅ አስተዳዳሪዎን ያነጋግሩ።}one{ይህ ፋይል አንዳንድ የድርጅትዎን የደህንነት መመሪያዎች አያሟላም። ምን መስተካከል እንዳለበት ለማወቅ አስተዳዳሪዎን ያነጋግሩ።}other{እነዚህ ፋይሎች አንዳንድ የድርጅትዎን የደህንነት መመሪያዎች አያሟሉም። ምን መስተካከል እንዳለበት ለማወቅ አስተዳዳሪዎን ያነጋግሩ።}}</translation>
 <translation id="5738093759615225354">ወደ የእርስዎ ኮምፒውተር ለመግባት ይህ የይለፍ ቁልፍ ያስፈልገዎታል</translation>
 <translation id="5739017626473506901"><ph name="USER_NAME" /> የትምህርት መለያ እንዲያክሉ ለማገዝ ወደ መለያ ይግቡ</translation>
@@ -8221,6 +8227,7 @@
 <translation id="7114054701490058191">የይለፍ ቃላት አይዛመዱም</translation>
 <translation id="7114648273807173152">Smart Lockን ተጠቅመው ወደ የGoogle መለያዎ ለመግባት ወደ ቅንብሮች &gt; የተገናኙ መሣሪያዎች &gt; የእርስዎ ስልክ &gt; Smart Lock ይሂዱ።</translation>
 <translation id="7115361495406486998">ሊደረስባቸው የሚችሉ እውቂያዎች የሉም</translation>
+<translation id="7115731767122970828">አሁን ጨምር</translation>
 <translation id="7116554090938189816">የማተሚያ የኤስኤስኤል የዕውቅና ማረጋገጫ ጊዜው አልፎበታል። ማተሚያን እንደገና ያስጀመሩ እና እንደገና ይሞክሩ።</translation>
 <translation id="7117228822971127758">እባክዎ ቆይተው እንደገና ይሞክሩ</translation>
 <translation id="7118268675952955085">ቅጽበታዊ ገፅ ዕይታ</translation>
@@ -8376,6 +8383,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (ምርጥ)</translation>
 <translation id="7246230585855757313">የእርስዎን የደህንነት ቁልፍ እንደገና ያስገቡ እና ደግመው ይሞክሩ</translation>
 <translation id="724835896049478274">ለAndroid መተግበሪያዎች የሚገኙ መለያዎች</translation>
+<translation id="7248802599439396696">ትሮችን አቦዝን</translation>
 <translation id="7249197363678284330">ይህን ቅንብር በአድራሻ አሞሌው ውስጥ ይቀይሩት።</translation>
 <translation id="7249764475759804559">ፋይሎችን ሲከፍቱ ይህን መተግበሪያ እንደ አማራጭ ያካትቱ</translation>
 <translation id="7250616558727237648">እያጋሩት ያለው መሣሪያ ምላሽ አልሰጠም። እባክዎ እንደገና ይሞክሩ።</translation>
@@ -9976,6 +9984,7 @@
 <translation id="8390392581097975659">የመቃኛ ሶፍትዌርን በመጫን ላይ</translation>
 <translation id="8390449457866780408">አገልጋይ አይገኝም።</translation>
 <translation id="8391218455464584335">ቪኒል</translation>
+<translation id="8391918125842702622">የአፈጻጸም ችግር ማንቂያ</translation>
 <translation id="8392726714909453725">የለመናገር ምረጥ ቅንብሮች</translation>
 <translation id="8393511274964623038">ተሰኪውን አቁም</translation>
 <translation id="839363317075970734">የብሉቱዝ መሣሪያ ዝርዝሮች</translation>
@@ -10076,6 +10085,7 @@
 <translation id="8466052016039127321">ቀዳሚ ክፍለ ጊዜን ከቆመበት መቀጠል አልተቻለም</translation>
 <translation id="8467326454809944210">ሌላ ቋንቋ ይምረጡ</translation>
 <translation id="8468087214092422866">የብሉቱዝ መሣሪያዎችን ለመፈለግ አይፈቀድም</translation>
+<translation id="8469863130477774813">የአፈጻጸም መጨመር አለ</translation>
 <translation id="8470513973197838199">የተቀመጡ የ<ph name="ORIGIN" /> የይለፍ ቃላት</translation>
 <translation id="8471525937465764768">ጣቢያዎች እንደ ሰነድ ማተም ወይም ወደ የማከማቻ መሣሪያ ማስቀመጥ ያሉ ባህሪያትን ለማግኘት አብዛኛው ጊዜ ከዩኤስቢ መሣሪያዎች ጋር ይገናኛሉ</translation>
 <translation id="8471959340398751476">ቅናሾች ጠፍተዋል። በአብጅ ምናሌ ውስጥ ሊያበሩዋቸው ይችላሉ</translation>
diff --git a/chrome/app/resources/generated_resources_bn.xtb b/chrome/app/resources/generated_resources_bn.xtb
index 83527a5..1acf9c9 100644
--- a/chrome/app/resources/generated_resources_bn.xtb
+++ b/chrome/app/resources/generated_resources_bn.xtb
@@ -974,6 +974,7 @@
 <translation id="1697150536837697295">শিল্পকলা</translation>
 <translation id="1697686431566694143">ফাইল এডিট করতে পারবে</translation>
 <translation id="1698796500103229697">&amp;পেমেন্ট পদ্ধতি</translation>
+<translation id="1698899521169711967">ক্যারেট ব্রাউজিং</translation>
 <translation id="1699807488537653303">পাসওয়ার্ড সংক্রান্ত সমস্যার সমাধান করুন</translation>
 <translation id="1700201317341192482">আপনার ভার্চুয়াল কার্ড সরিয়ে দিন</translation>
 <translation id="1700517974991662022">ঘুরে দেখা হয়েছে</translation>
@@ -2484,6 +2485,7 @@
 <translation id="2771816809568414714">চিজ</translation>
 <translation id="2772936498786524345">নিনজা</translation>
 <translation id="2773288106548584039">পুরনো ব্রাউজারের জন্য সমর্থন</translation>
+<translation id="2773621783913034737">ট্যাব বন্ধ করুন</translation>
 <translation id="2773802008104670137">এই ধরনের ফাইল আপনার কম্পিউটারের ক্ষতি করতে পারে।</translation>
 <translation id="2775104091073479743">আঙ্গুলের ছাপ সম্পাদনা করুন</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{"<ph name="EXTENSION" />" এক্সটেনশন ডিভাইসগুলি অ্যাক্সেস করছিল}=1{"<ph name="EXTENSION" />" এক্সটেনশন {0}টি ডিভাইস অ্যাক্সেস করছে}one{"<ph name="EXTENSION" />" এক্সটেনশন {0}টি ডিভাইস অ্যাক্সেস করছে}other{"<ph name="EXTENSION" />" এক্সটেনশন {0}টি ডিভাইস অ্যাক্সেস করছে}}</translation>
@@ -2564,6 +2566,7 @@
 <translation id="2830528677948328648">আপনার &amp;Google অ্যাকাউন্ট ম্যানেজ করুন</translation>
 <translation id="2831430281393059038">ডিভাইস কাজ করে</translation>
 <translation id="2832124733806557606">ডিভাইস আনলক করতে বা সাইন-ইন করতে আপনার সন্তান পিন ব্যবহার করতে পারবে।</translation>
+<translation id="2833144527504272627">টেক্সট কার্সরের মাধ্যমে নেভিগেট করুন</translation>
 <translation id="2835177225987815960">যেকোনও অ্যাসাইন করা পরিবর্তন এবং অটো-স্ক্যান স্পিড পছন্দ সহ আপনার বর্তমান স্ক্যান সেট-আপ আবার সেট করা হবে।</translation>
 <translation id="2835547721736623118">স্পিচ শনাক্তকরণ পরিষেবা</translation>
 <translation id="2835761321523638096">পড়ার তালিকার এন্ট্রি পড়ে পরিবর্তন করুন</translation>
@@ -4119,6 +4122,7 @@
 <translation id="3978325380690188371">ChromeVox চালু থাকলে, স্টিকি কী উপলভ্য হবে না</translation>
 <translation id="3979395879372752341">নতুন এক্সটেনশন যোগ করা হয়েছে (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326"><ph name="NETWORKDEVICE" /> সক্ষম করুন</translation>
+<translation id="398095528354975981">এইসব ট্যাব লুকান</translation>
 <translation id="3981058120448670012">কাছাকাছি থাকা ডিভাইসগুলিতে, <ph name="REMAINING_TIME" />-এর জন্য <ph name="DEVICE_NAME" /> হিসেবে দেখা যাবে...</translation>
 <translation id="3981760180856053153">ভুল সেভ করার ধরণ লেখা হয়েছে৷</translation>
 <translation id="3982375475032951137">কয়েকটি সহজ ধাপে আপনার ব্রাউজার সেট-আপ করুন</translation>
@@ -6314,6 +6318,7 @@
 <translation id="5642508497713047">CRL স্বাক্ষরকারী</translation>
 <translation id="5643191124441701136">আপনার কার্ডের সামনে আপনার নিরাপত্তা কোড রয়েছে</translation>
 <translation id="5643321261065707929">মিটার্ড নেটওয়ার্ক</translation>
+<translation id="5643717184207603910">পারফর্ম্যান্স আরও ভালো করুন</translation>
 <translation id="5646376287012673985">লোকেশন</translation>
 <translation id="5646558797914161501">ব্যবসায়ী</translation>
 <translation id="5648021990716966815">মাইক জ্যাক</translation>
@@ -6418,6 +6423,7 @@
 <translation id="5733109311583381874">টেক্সট কনভার্সন সংক্রান্ত সাজেশন কাস্টমাইজ করতে, আপনার নিজস্ব শব্দ ব্যবহারকারীর অভিধানে যোগ করুন।</translation>
 <translation id="5734362860645681824">যোগাযোগগুলি</translation>
 <translation id="5734697361979786483">'ফাইল শেয়ার' যোগ করুন</translation>
+<translation id="5735513236153491131">এখনই বুস্ট করুন</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{এই ডেটা বা আপনার ডিভাইস, সংস্থার কিছু নিরাপত্তা সংক্রান্ত নীতি পূরণ করেনি। সমাধানের জন্য কী করতে হবে তা জানতে আপনার অ্যাডমিনের সাথে যোগাযোগ করুন।}=1{এই ফাইল বা আপনার ডিভাইস, সংস্থার কিছু নিরাপত্তা সংক্রান্ত নীতি পূরণ করেনি। সমাধানের জন্য কী করতে হবে তা জানতে আপনার অ্যাডমিনের সাথে যোগাযোগ করুন।}one{এইসব ফাইল সংস্থার কিছু নিরাপত্তা সংক্রান্ত নীতি পূরণ করেনি। সমাধানের জন্য কী করতে হবে তা জানতে আপনার অ্যাডমিনের সাথে যোগাযোগ করুন।}other{এইসব ফাইল সংস্থার কিছু নিরাপত্তা সংক্রান্ত নীতি পূরণ করেনি। সমাধানের জন্য কী করতে হবে তা জানতে আপনার অ্যাডমিনের সাথে যোগাযোগ করুন।}}</translation>
 <translation id="5738093759615225354">আপনার কম্পিউটারে সাইন-ইন করতে, এই 'পাসকী' প্রয়োজন হবে</translation>
 <translation id="5739017626473506901">একটি স্কুল অ্যাকাউন্ট যোগ করার জন্য <ph name="USER_NAME" />-কে সাহায্য করতে সাইন-ইন করুন</translation>
@@ -8232,6 +8238,7 @@
 <translation id="7114054701490058191">পাসওয়ার্ডগুলি মিলছে না</translation>
 <translation id="7114648273807173152">Smart Lock ব্যবহার করতে আপনার Google অ্যাকাউন্টে সাইন-ইন করে সেটিংস &gt; কানেক্ট করা ডিভাইস &gt; আপনার ফোন &gt; Smart Lock বিকল্পে যান।</translation>
 <translation id="7115361495406486998">যোগাযোগ করা যেতে পারে এমন কোনও পরিচিত নেই</translation>
+<translation id="7115731767122970828">এখনই বুস্ট করুন</translation>
 <translation id="7116554090938189816">প্রিন্টারের SSL সার্টিফিকেটের মেয়াদ শেষ হয়ে গেছে। প্রিন্টার রিস্টার্ট করে আবার চেষ্টা করুন।</translation>
 <translation id="7117228822971127758">পরে আবার চেষ্টা করুন</translation>
 <translation id="7118268675952955085">স্ক্রিনশট</translation>
@@ -8387,6 +8394,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (সর্বোত্তম)</translation>
 <translation id="7246230585855757313">আপনার নিরাপত্তা কী আবার লিখুন এবং আবার চেষ্টা করুন</translation>
 <translation id="724835896049478274">Android অ্যাপের জন্য উপলভ্য অ্যাকাউন্ট</translation>
+<translation id="7248802599439396696">ট্যাব বন্ধ করুন</translation>
 <translation id="7249197363678284330">অ্যাড্রেস বার থেকে এই সেটিং পরিবর্তন করুন।</translation>
 <translation id="7249764475759804559">ফাইল খোলার সময় একটি বিকল্প হিসেবে এই অ্যাপ অন্তর্ভুক্ত করুন</translation>
 <translation id="7250616558727237648">আপনি যে ডিভাইস শেয়ার করছেন সেটি থেকে কোনও প্রতিক্রিয়া পাওয়া যায়নি। আবার চেষ্টা করুন।</translation>
@@ -9981,6 +9989,7 @@
 <translation id="8390392581097975659">স্ক্যানার সফ্টওয়্যার ইনস্টল করা হচ্ছে</translation>
 <translation id="8390449457866780408">সার্ভার অনুপলব্ধ৷</translation>
 <translation id="8391218455464584335">ভিনাইল</translation>
+<translation id="8391918125842702622">পারফর্ম্যান্সের সমস্যা সংক্রান্ত সতর্কতা</translation>
 <translation id="8392726714909453725">'বাছুন ও শুনুন'-এর সেটিংস</translation>
 <translation id="8393511274964623038">প্লাগ-ইন বন্ধ করুন</translation>
 <translation id="839363317075970734">ব্লুটুথ ডিভাইসের বিবরণ</translation>
@@ -10081,6 +10090,7 @@
 <translation id="8466052016039127321">আগের সেশন চালু করা যাচ্ছে না</translation>
 <translation id="8467326454809944210">অন্য ভাষা বেছে নিন</translation>
 <translation id="8468087214092422866">ব্লুটুথ ডিভাইস খোঁজার অনুমতি নেই</translation>
+<translation id="8469863130477774813">পারফর্ম্যান্স বুস্ট করার সুবিধা উপলভ্য আছে</translation>
 <translation id="8470513973197838199"><ph name="ORIGIN" /> এর জন্য সেভ করা পাসওয়ার্ডগুলি</translation>
 <translation id="8471525937465764768">ডকুমেন্ট প্রিন্ট করা অথবা স্টোরেজ ডিভাইসে সেভ করার মতো ফিচারের জন্য সাইট সাধারণত USB ডিভাইসের সাথে কানেক্ট করে</translation>
 <translation id="8471959340398751476">ছাড়ের সুবিধা বন্ধ করা আছে। আপনি কাস্টমাইজ মেনু থেকে এই সুবিধা চালু করতে পারবেন</translation>
diff --git a/chrome/app/resources/generated_resources_bs.xtb b/chrome/app/resources/generated_resources_bs.xtb
index 92158f7..e6880669 100644
--- a/chrome/app/resources/generated_resources_bs.xtb
+++ b/chrome/app/resources/generated_resources_bs.xtb
@@ -67,6 +67,7 @@
 <translation id="1043505821207197890">Nešto nije uredu. Moguće da je Linux samo djelimično nadograđen. Više informacija potražite u zapisnicima. Zapisnici su sačuvani u Fajlovima &gt; Moji fajlovi &gt; <ph name="LOG_FILE" /></translation>
 <translation id="104419033123549300">Stil mape tipki</translation>
 <translation id="1046521327593783388">{NUM_PASSWORDS,plural, =1{1 lozinka je uvezena na uslugu <ph name="BRAND" /> na ovom uređaju}one{{NUM_PASSWORDS} lozinka je uvezena na uslugu <ph name="BRAND" /> na ovom uređaju}few{{NUM_PASSWORDS} lozinke su uvezene na uslugu <ph name="BRAND" /> na ovom uređaju}other{{NUM_PASSWORDS} lozinki je uvezeno na uslugu <ph name="BRAND" /> na ovom uređaju}}</translation>
+<translation id="1046572983040892965">Prozor je premješten prema gore i ulijevo</translation>
 <translation id="104710386808485638">Ponovno pokrenuti Linux?</translation>
 <translation id="1047431265488717055">Kopiraj tekst linka</translation>
 <translation id="1048286738600630630">Ekrani</translation>
@@ -187,6 +188,7 @@
 <translation id="1130589222747246278"><ph name="WINDOW_TITLE" /> – dio grupe <ph name="GROUP_NAME" /></translation>
 <translation id="1130676589211693127">Nivo napunjenosti desne baterije: <ph name="PERCENTAGE" />%.</translation>
 <translation id="1133418583142946603">Dodaj trenutnu karticu</translation>
+<translation id="1134363466745332968">Povijest pregledavanja možete pretraživati na temelju općeg sadržaja stranice, a ne samo naslova i URL-a stranice. Time ćete dobiti poboljšane rezultate, bez obzira na to pretražujete li povijest pregledavanja u adresnoj traci pomoću oznake @history ili putem stranice Povijest.</translation>
 <translation id="1136179794690960030"><ph name="EMOJI_NAME" />. <ph name="EMOJI_INDEX" /> od <ph name="EMOJI_COUNT" />.</translation>
 <translation id="1136712381129578788">Sigurnosni ključ je zaključan zato što je pogrešan PIN unesen više puta. Uklonite i ponovo umetnite sigurnosni ključ da ga otključate.</translation>
 <translation id="1137589305610962734">privremeni podaci</translation>
@@ -218,6 +220,7 @@
 <translation id="1158080958325422608">Promijeni u velika slova</translation>
 <translation id="1158238185437008462">Prikaži uspomene</translation>
 <translation id="1159879754517035595">Upravljajte postavkama ekstenzije</translation>
+<translation id="1160800016654917722">Prozor je premješten prema dolje i ulijevo</translation>
 <translation id="1161575384898972166">Prijavite se na <ph name="TOKEN_NAME" /> za izvoz potvrde klijenta.</translation>
 <translation id="116173250649946226">Vaš administrator je postavio zadanu temu koju nije moguće promijeniti.</translation>
 <translation id="1162213688509394031">Sakrijte traku s naslovom</translation>
@@ -326,6 +329,7 @@
 <translation id="1227993798763400520">Emitiranje nije uspjelo. Pokušajte ponovo.</translation>
 <translation id="1230417814058465809">Standardna zaštita je uključena. Za još veću sigurnost koristite poboljšanu zaštitu.</translation>
 <translation id="1231426483209637778">Zapamtit ćemo vašu mrežu prilikom sljedećeg korištenja uređaja <ph name="DEVICE_TYPE" /></translation>
+<translation id="1231572247662419826">Web-lokacije mogu tražiti dopuštenje za bilježenje i upotrebu unosa mišem</translation>
 <translation id="1232569758102978740">Bez naslova</translation>
 <translation id="1233497634904001272">Dodirnite ponovo sigurnosni ključ da dovršite zahtjev.</translation>
 <translation id="1233721473400465416">Postavke lokacije</translation>
@@ -546,6 +550,7 @@
 <translation id="1407069428457324124">Tamna tema</translation>
 <translation id="1407135791313364759">Otvori sve</translation>
 <translation id="140723521119632973">Aktiviranje mobilne mreže</translation>
+<translation id="1407970155431887387">Kliknite da biste otvorili dijaloški okvir za uređivanje za tražilicu <ph name="SEARCH_ENGINE_NAME" /></translation>
 <translation id="1408504635543854729">Istražite sadržaj uređaja u aplikaciji Files. Administrator ograničava sadržaj i ne možete ga izmijeniti.</translation>
 <translation id="1408980562518920698">Upravljajte ličnim informacijama</translation>
 <translation id="1410197035576869800">Ikona aplikacije</translation>
@@ -1115,6 +1120,7 @@
 <translation id="1803531841600994172">Jezik na koji se prevodi</translation>
 <translation id="1803545009660609783">Uvježbaj ponovo</translation>
 <translation id="1804195280859010019">Prikazivat će vam se korisnije informacije ili prijedlozi u funkcijama kao što je bočna ploča u Google Pretraživanju.</translation>
+<translation id="180441032496361123">Kliknite da biste aktivirali tražilicu <ph name="SEARCH_ENGINE_NAME" /></translation>
 <translation id="1805738995123446102">Kartica u pozadini koristi vaš mikrofon</translation>
 <translation id="1805822111539868586">Pregledajte prikaze</translation>
 <translation id="1805888043020974594">Server za štampanje</translation>
@@ -1188,6 +1194,7 @@
 <translation id="1848219224579402567">Odjavi me kada se poklopac zatvori</translation>
 <translation id="184862733444771842">Zahtjev za funkcijom</translation>
 <translation id="1849016657376805933">Bilo koji HID uređaj</translation>
+<translation id="1849022541429818637">Dopušteno je bilježiti i upotrebljavati unose mišem</translation>
 <translation id="1850145825777333687">Akreditivi uređaja</translation>
 <translation id="1850508293116537636">Rotiraj u smjeru kazaljke na satu</translation>
 <translation id="185111092974636561"><ph name="BEGIN_PARAGRAPH1" />Prije prijave morate obrisati TPM da <ph name="DEVICE_OS" /> može preuzeti vlasništvo nad uređajem.<ph name="END_PARAGRAPH1" />
@@ -1735,6 +1742,7 @@
 <translation id="2251809247798634662">Novi anonimni prozor</translation>
 <translation id="2252017960592955005">Zaštita od pregleda (beta verzija)</translation>
 <translation id="2253318212986772520">Nije moguće dohvatiti PPD za štampač <ph name="PRINTER_NAME" />.</translation>
+<translation id="2253797136365098595">Saznajte više o pretraživanjima povijesti</translation>
 <translation id="2253927598983295051">Odaberite šta ćete dijeliti s aplikacijom <ph name="APP_NAME" /></translation>
 <translation id="2255077166240162850">Ovaj uređaj je bio zaključan za neku drugu domenu ili način rada.</translation>
 <translation id="2255317897038918278">Microsoft vremensko označavanje</translation>
@@ -2132,6 +2140,7 @@
 <translation id="2515586267016047495">Alt</translation>
 <translation id="251722524540674480">Potvrdite korisničko ime</translation>
 <translation id="2517472476991765520">Skeniraj</translation>
+<translation id="2517851527960406492">Web-lokacije mogu tražiti dopuštenje za bilježenje i upotrebu unosa pomoću tipkovnice</translation>
 <translation id="2518024842978892609">Korištenje potvrda klijenata</translation>
 <translation id="2518620532958109495">Dozvoljen je automatski prikaz preko cijelog ekrana</translation>
 <translation id="2519250377986324805">Pogledajte kako</translation>
@@ -2310,6 +2319,7 @@
 <translation id="265748523151262387">Ostanite povezani putem telefona</translation>
 <translation id="2657612187216250073">Postavke pristupačnosti pokazivača</translation>
 <translation id="2658941648214598230">Prikazati originalni sadržaj?</translation>
+<translation id="2659694935349347275">Prozor je premješten prema dolje i udesno</translation>
 <translation id="2659971421398561408">Promjena veličine diska na Crostiniju</translation>
 <translation id="2660115748527982021">Savjet: na webu je dostupno mnogo Android aplikacija. Informacije o dostupnosti potražite na web lokaciji aplikacije ili programera.</translation>
 <translation id="2660779039299703961">Događaj</translation>
@@ -2355,6 +2365,7 @@
 <translation id="2690024944919328218">Prikaži opcije jezika</translation>
 <translation id="2691385045260836588">Model</translation>
 <translation id="2691440343905273290">Promijenite postavke unosa</translation>
+<translation id="2691811116976138467">Web-lokacije upotrebljavaju tu značajku kako bi bilježile i upotrebljavale unose izvršene pomoću vaše tipkovnice, primjerice za igre ili aplikacije udaljene radne površine</translation>
 <translation id="2692503699962701720">Promijenite visinu glasa prilikom izgovaranja vrsta elemenata i formatiranog teksta</translation>
 <translation id="2692901429679246677">Tirkizno plava</translation>
 <translation id="2693134906590795721">Zvukovi punjenja</translation>
@@ -3124,6 +3135,7 @@
 <translation id="3261090393424563833">Povećaj brzinu</translation>
 <translation id="3261268979727295785">Za stariju djecu možete dodati roditeljski nadzor kada završite postavljanje. Informacije o roditeljskom nadzoru možete pronaći u aplikaciji Istražite.</translation>
 <translation id="3261832505033014216">Pristupni ključ za <ph name="USER_EMAIL" /></translation>
+<translation id="3262261769033093854">Ne dopuštaj web-lokacijama bilježenje i upotrebu unosa mišem</translation>
 <translation id="3262336253311870293">S obzirom na to da ovim računom upravlja <ph name="DOMAIN" />, nećete se odjaviti s Google računa. Vaše oznake, historija, lozinke i druge postavke se više neće sinhronizirati. Međutim, prethodno sinhronizirani podaci će ostati pohranjeni na vašem Google računu i njima možete upravljati na <ph name="BEGIN_LINK" />Google kontrolnoj tabli<ph name="END_LINK" />.</translation>
 <translation id="3262986719682892278">Preveliko</translation>
 <translation id="3264544094376351444">Sans-serif font</translation>
@@ -3437,6 +3449,7 @@
 <translation id="3497501929010263034">USB uređaj dobavljača <ph name="VENDOR_NAME" /> (proizvod: <ph name="PRODUCT_ID" />)</translation>
 <translation id="3497560059572256875">Dijeli crtež</translation>
 <translation id="3497915391670770295">Pošaljite na svoje &amp;uređaje</translation>
+<translation id="3499091376302796297">Dok pregledavate web-lokacije, sadržaj njihovih stranica sprema se u šifriranom obliku na vašem uređaju.</translation>
 <translation id="3500417806337761827">Greška prilikom aktiviranja dijeljenja. Previše MSP dijeljenja je već aktivirano.</translation>
 <translation id="3500764001796099683">Omogućite izolirane web aplikacije</translation>
 <translation id="350397915809787283">Ako nemate račun, odaberite prvu opciju da ga kreirate.</translation>
@@ -4244,6 +4257,7 @@
 <translation id="4062561150282203854">Sinhronizirajte aplikacije, postavke i ostali sadržaj uređaja <ph name="DEVICE_TYPE" /></translation>
 <translation id="4065876735068446555">Mreža koju koristite (<ph name="NETWORK_ID" />) može zahtijevati da posjetite stranicu za prijavu.</translation>
 <translation id="4066207411788646768">Provjerite vezu da vidite dostupne štampače na svojoj mreži</translation>
+<translation id="4066458014195202324">Dopušteno je bilježiti i upotrebljavati unose pomoću tipkovnice</translation>
 <translation id="4067839975993712852">Označi trenutnu karticu kao pročitanu</translation>
 <translation id="4068776064906523561">Sačuvani otisci prstiju</translation>
 <translation id="4070132839822635162">Ne prijavljuj me</translation>
@@ -4383,6 +4397,7 @@
 <translation id="4184803915913850597">HID uređaj (<ph name="VENDOR_ID" />:<ph name="PRODUCT_ID" />)</translation>
 <translation id="4186749321808907788"><ph name="QUERY_NAME" /> – <ph name="DEFAULT_SEARCH_ENGINE_NAME" /> Pretraživanje</translation>
 <translation id="4187424053537113647">Postavljanje aplikacije <ph name="APP_NAME" />...</translation>
+<translation id="4190446002599583608">Pretraživanje povijesti pomoću AI-ja</translation>
 <translation id="4190492351494485814">Za početno postavljanje se trebate povezati s internetom da se fajlovi mogu sinhronizirati s Chromebookom</translation>
 <translation id="4190828427319282529">Isticanje fokusa tastature</translation>
 <translation id="4191892134568599822">Primiti putem funkcije <ph name="FEATURE_NAME" />?</translation>
@@ -4878,6 +4893,7 @@
 <translation id="4562155214028662640">Dodajte otisak prsta</translation>
 <translation id="4562155266774382038">Odbacite prijedlog</translation>
 <translation id="4562364000855074606">Blokirajte aplikacije instalirane na uređaju <ph name="DEVICE_TYPE" />. Da ograničite preuzimanje aplikacija ili sadržaja, idite u Postavke Google Playa. <ph name="BEGIN_LINK_LEARN_MORE" />Saznajte više<ph name="END_LINK_LEARN_MORE" /></translation>
+<translation id="4562925006886238518">Koristite svakodnevni jezik da biste pretraživali svoju povijest pregledavanja i pronašli web-lokacije koje ste posjetili.</translation>
 <translation id="4563210852471260509">Početni jezik unosa je kineski</translation>
 <translation id="4563382028841851106">Ukloni s računa</translation>
 <translation id="4563880231729913339">3. prst</translation>
@@ -4929,6 +4945,7 @@
 <translation id="4598549027014564149">U anonimnom načinu rada web lokacije ne mogu koristiti kolačiće da vide vašu aktivnost pregledanja na web lokacijama, čak ni na srodnim web lokacijama. Aktivnost pregledanja se ne koristi za stvari kao što je personaliziranje oglasa. Moguće je da funkcije neće raditi na nekim web lokacijama.</translation>
 <translation id="4598556348158889687">Upravljanje pohranom</translation>
 <translation id="4598776695426288251">WiFi mreža je dostupna putem više uređaja</translation>
+<translation id="4599323532350839656">Nije dopušteno bilježiti i upotrebljavati unose pomoću tipkovnice</translation>
 <translation id="4600071396330666617">Broj prijedloga</translation>
 <translation id="4601095002996233687">Detaljna skeniranja radi provjere sumnjivih preuzimanja.</translation>
 <translation id="4601426376352205922">Označi kao nepročitano</translation>
@@ -5242,6 +5259,7 @@
 <translation id="484462545196658690">Automatski</translation>
 <translation id="4846628405149428620">Odaberite gdje ova web lokacija može sačuvati izmjene</translation>
 <translation id="4846680374085650406">U skladu ste s preporukom administratora za ovu postavku.</translation>
+<translation id="4846897209694249040">Nije dopušteno bilježiti i upotrebljavati unose mišem</translation>
 <translation id="4847242508757499006">Odaberite "Pokušaj ponovo" ili "Otvori u osnovnom uređivaču" da koristite ograničene opcije prikaza i uređivanja.</translation>
 <translation id="4847742514726489375">Smanjeno kretanje</translation>
 <translation id="4848191975108266266">Google Asistent "Ok Google"</translation>
@@ -5362,6 +5380,7 @@
 <translation id="4927753642311223124">Ovdje nema ništa, nastavi dalje.</translation>
 <translation id="4928629450964837566">Koristite sigurniju lozinku</translation>
 <translation id="4929386379796360314">Odredišta za štampanje</translation>
+<translation id="4930406318748549391">Položaj bočne ploče</translation>
 <translation id="4930447554870711875">Programeri</translation>
 <translation id="4930714375720679147">Uključi</translation>
 <translation id="4931347390544064118">Sigurne veze možda neće uvijek biti dostupne kada koristite zadanu postavku mreže. Možete odabrati drugog pružaoca usluga da osigurate da uvijek koristite sigurnu vezu.</translation>
@@ -5710,6 +5729,7 @@
 <translation id="5195074424945754995">URL-ovi koji se podudaraju s ovim pravilima neće aktivirati prekidač preglednika, a mogu se otvarati u pregledniku <ph name="BROWSER_NAME" /> ili <ph name="ALTERNATIVE_BROWSER_NAME" />.</translation>
 <translation id="5195863934285556588"><ph name="BEGIN_PARAGRAPH1" />Googleova usluga lokacije koristi izvore poput WiFi-ja, mobilnih mreža i senzora radi lakše procjene lokacije ovog uređaja.<ph name="END_PARAGRAPH1" />
     <ph name="BEGIN_PARAGRAPH2" />Možete isključiti lokaciju Androida na ovom uređaju bilo kada u Postavkama &gt; Aplikacije &gt; Google Play trgovina &gt; Upravljajte postavkama Androida &gt; Sigurnost i lokacija &gt; Lokacija. Također možete isključiti korištenje WiFi-ja, mobilnih mreža i senzora za lokaciju Androida isključivanjem "Googleove preciznosti lokacije" u istom meniju.<ph name="END_PARAGRAPH2" /></translation>
+<translation id="5197150086680615104">Prijedloge grupa kartica uvijek možete provjeriti</translation>
 <translation id="5197255632782567636">Internet</translation>
 <translation id="5198430103906431024">Šaljite podatke o korištenju i dijagnostici. Ovaj uređaj trenutno automatski šalje Googleu podatke o dijagnostici, uređaju i korištenju aplikacija. To će pomoći stabilnosti sistema i aplikacija, kao i drugim poboljšanjima. Neki zbirni podaci će također pomoći Googleovim aplikacijama i partnerima, kao što su Androidovi programeri. Ako vam je uključena postavka dodatna Aktivnost na webu i u aplikacijama, ti podaci će možda biti sačuvani na vašem Google računu.</translation>
 <translation id="5199729219167945352">Eksperimenti</translation>
@@ -7226,6 +7246,7 @@
 <translation id="6341850831632289108">Otkrivanje vaše fizičke lokacije</translation>
 <translation id="6342069812937806050">Maloprije</translation>
 <translation id="6343003829431264373">Samo parne stranice</translation>
+<translation id="6343981313228733146">Prozor je premješten prema gore i udesno</translation>
 <translation id="6344170822609224263">Pristupiti spisku mrežnih veza</translation>
 <translation id="6344576354370880196">Sačuvani štampači</translation>
 <translation id="6344608411615208519">Roditelj <ph name="BEGIN_LINK" />upravlja tvojim preglednikom<ph name="END_LINK" /></translation>
@@ -7810,6 +7831,7 @@
 <translation id="6798780071646309401">velika slova su uključena</translation>
 <translation id="6798954102094737107">Dodatak: <ph name="PLUGIN_NAME" /></translation>
 <translation id="679905836499387150">Sakrivena dugmad alatne trake</translation>
+<translation id="6800623240347398745">Nema grupe za tu karticu, ali pogledajte ove grupe</translation>
 <translation id="6800893479155997609">Najpopularnije aplikacije za <ph name="DEVICE_TYPE" /></translation>
 <translation id="6801308659697002152">{NUM_EXTENSIONS,plural, =1{Odaberite može li ova ekstenzija čitati ili mijenjati ovu web lokaciju}one{Odaberite mogu li ove ekstenzije čitati ili mijenjati ovu web lokaciju}few{Odaberite mogu li ove ekstenzije čitati ili mijenjati ovu web lokaciju}other{Odaberite mogu li ove ekstenzije čitati ili mijenjati ovu web lokaciju}}</translation>
 <translation id="6801435275744557998">Kalibriraj ekran osjetljiv na dodir</translation>
@@ -7851,6 +7873,7 @@
 <translation id="6818920801736417483">Sačuvati lozinke?</translation>
 <translation id="6820079682647046800">Autentifikacija Kerberos nije uspjela</translation>
 <translation id="6821439254917412979">Otkačivanje ekstenzije <ph name="EXTENSION_NAME" /></translation>
+<translation id="6823097506504975234">Kada pretražujete povijest pregledavanja, vaši pojmovi za pretraživanje povijesti, sadržaj stranica s najboljim podudaranjima i generirani rezultati obrade šalju se Googleu i pregledavatelji ih mogu vidjeti kako bi poboljšali tu značajku.</translation>
 <translation id="6823174134746916417">Dodir za klik dodirne podloge</translation>
 <translation id="6823561724060793716">Iz trake za adresu možete otvoriti informacije o stranici da pogledate dodatne informacije o stranici koju posjećujete</translation>
 <translation id="6824564591481349393">Kopiraj adresu &amp;e-pošte</translation>
@@ -8882,6 +8905,7 @@
 <translation id="761530003705945209">Izradite sigurnosne kopije na Google disku. Jednostavno u svakom trenutku vratite svoje podatke ili promijenite uređaj. Vaša sigurnosna kopija obuhvata podatke o aplikacijama. Vaše sigurnosne kopije se otpremaju na Google i šifriraju pomoću lozinke Google računa.</translation>
 <translation id="7615365294369022248">Došlo je do greške prilikom dodavanja računa</translation>
 <translation id="7616214729753637086">Prijava uređaja...</translation>
+<translation id="7616964248951412133">Web-lokacije upotrebljavaju tu značajku kako bi bilježile i upotrebljavale unose izvršene pomoću vašeg miša, primjerice za igre ili aplikacije udaljene radne površine</translation>
 <translation id="7617263010641145920">Uključite Play trgovinu</translation>
 <translation id="7617648809369507487">Koristite tiše poruke</translation>
 <translation id="7619937211696316184">Održavanje je gotovo</translation>
@@ -9385,6 +9409,7 @@
 <translation id="7959665254555683862">Nova anonimna &amp;kartica</translation>
 <translation id="7961015016161918242">Nikada</translation>
 <translation id="7963001036288347286">Ubrzanje dodirne podloge</translation>
+<translation id="7963513503134856713">Prozor je premješten udesno</translation>
 <translation id="7963608432878156675">Ovaj naziv je vidljiv drugim uređajima za Bluetooth i mrežne veze</translation>
 <translation id="7963826112438303517">Asistent koristi te snimke i vaše izgovorene zahtjeve za kreiranje i ažuriranje modela vašeg glasa koji se pohranjuje samo na uređajima na kojim ste uključili Voice Match. Aktivnost glasa možete pregledati ili ponovo uvježbati u Postavkama Asistenta.</translation>
 <translation id="7964458523224581615">Plavo-zelena</translation>
@@ -10038,6 +10063,7 @@
 <translation id="8428271547607112339">Dodaj školski račun</translation>
 <translation id="8428634594422941299">Razumijem</translation>
 <translation id="84297032718407999">Bit ćete odjavljeni za <ph name="LOGOUT_TIME_LEFT" /></translation>
+<translation id="8429928917752180743">Više opcija za proširenje <ph name="EXTENSION_NAME" /></translation>
 <translation id="8431190899827883166">Prikaži dodire</translation>
 <translation id="843173223122814223">Kreirajte pozadine pomoću AI-ja</translation>
 <translation id="8433186206711564395">Postavke mreže</translation>
@@ -10128,6 +10154,7 @@
 <translation id="8498214519255567734">Olakšajte gledanje u ekran ili čitanje pri slabom svjetlu</translation>
 <translation id="8499083585497694743">Uključi mikrofon</translation>
 <translation id="8500044868721690197">Web lokaciji je blokirano da kontrolira i reprogramira MIDI uređaje</translation>
+<translation id="8500123638242682652">Prozor je premješten prema gore</translation>
 <translation id="8502536196501630039">Da koristite aplikacije iz trgovine Google Play, prvo morate vratiti aplikacije. Neki podaci su možda izgubljeni.</translation>
 <translation id="8503813439785031346">Korisničko ime</translation>
 <translation id="850382998924680137">Pregledano danas</translation>
@@ -10227,6 +10254,7 @@
 <translation id="8577052309681449949">Automatski klikovi, veličina kursora, boja kursora i još mnogo toga</translation>
 <translation id="8578639784464423491">Ne možete unijeti više od 99 slova</translation>
 <translation id="8581809080475256101">Pritisnite da idete naprijed i na kontekstni meni da vidite historiju</translation>
+<translation id="8583122761178401199">Ne dopuštaj web-lokacijama bilježenje i upotrebu unosa pomoću tipkovnice</translation>
 <translation id="8584280235376696778">&amp;Otvori videozapis u novoj kartici</translation>
 <translation id="858451212965845553">Pošaljite na svoje &amp;uređaje</translation>
 <translation id="8584843865238667486">HID uređaji koji koriste <ph name="USAGE" /> sa stranice <ph name="USAGE_PAGE" /></translation>
@@ -10242,6 +10270,7 @@
 <translation id="859246725979739260">Ovoj web lokaciji je blokiran pristup vašoj lokaciji.</translation>
 <translation id="8593450223647418235">Nećete moći otvoriti fajlove u softveru Microsoft 365 dok se ne završi postavljanje.</translation>
 <translation id="8593686980889923154">Aplikacija <ph name="APP_NAME" /> je blokirana na uređaju <ph name="DEVICE_TYPE" /></translation>
+<translation id="8596400097994526901">Više radnji za <ph name="SEARCH_ENGINE_NAME" /></translation>
 <translation id="8596540852772265699">Prilagođeni fajlovi</translation>
 <translation id="8597845839771543242">Format atributa:</translation>
 <translation id="8598249292448297523">štampanje</translation>
@@ -10327,6 +10356,7 @@
 <translation id="8657393004602556571">Želite li odbaciti povratne informacije?</translation>
 <translation id="8657542881463614516">Prevlačenjem se krećite između stranica</translation>
 <translation id="8659608856364348875">Kontakti za funkciju <ph name="FEATURE_NAME" /></translation>
+<translation id="8659609431223166673">Prozor je premješten prema dolje</translation>
 <translation id="8661290697478713397">Otvori link u anonimnom prozoru</translation>
 <translation id="8662474268934425487">Prijava na uslugu <ph name="SITE_ETLD_PLUS_ONE" /></translation>
 <translation id="8662671328352114214">Pridružite se <ph name="TYPE" /> mreži</translation>
@@ -10373,6 +10403,7 @@
 <translation id="8682730193597992579">Štampač <ph name="PRINTER_NAME" /> je povezan i spreman</translation>
 <translation id="8684471948980641888">Dozvolite sinhronizaciju na mrežama s naplatom</translation>
 <translation id="8685540043423825702">Vaš profil u Chromeu</translation>
+<translation id="8685882652128627032">Kliknite da biste otvorili dijaloški okvir za dodavanje pretraživanja web-lokacija</translation>
 <translation id="8686142379631285985">Prijavljeni ste kao <ph name="BEGIN_BOLD" /><ph name="DRIVE_ACCOUNT_EMAIL" /><ph name="END_BOLD" /></translation>
 <translation id="8687103160920393343">Otkazivanje preuzimanja fajla <ph name="FILE_NAME" /></translation>
 <translation id="8687527282898211955">Postavite PIN</translation>
@@ -10563,6 +10594,7 @@
 <translation id="881799181680267069">Sakrij ostale</translation>
 <translation id="8818152010000655963">Pozadinska slika</translation>
 <translation id="8818958672113348984">Potvrdite putem telefona</translation>
+<translation id="8818988764764862764">Prozor je premješten ulijevo</translation>
 <translation id="8819510664278523111">EID uređaja je <ph name="EID_NUMBER" />, IMEI uređaja je <ph name="IMEI_NUMBER" />, a serijski broj uređaja je <ph name="SERIAL_NUMBER" />. Ovi brojevi mogu pomoći prilikom aktiviranja usluge.</translation>
 <translation id="8820817407110198400">Oznake</translation>
 <translation id="8821045908425223359">Konfiguriraj IP adresu automatski</translation>
@@ -10641,6 +10673,7 @@
 <translation id="8872506776304248286">Otvori u aplikaciji</translation>
 <translation id="8872774989979382243">Zvuk je isključen. Uključivanje zvuka.</translation>
 <translation id="887292602123626481">Saznajte više o zadanim pretraživačima</translation>
+<translation id="8873075098103007382">Ostanite organizirani pomoću grupa kartica</translation>
 <translation id="8874341931345877644">Emitirajte na uređaj:</translation>
 <translation id="8874790741333031443">Pokušajte privremeno dozvoliti kolačiće treće strane, što podrazumijeva manju zaštitu prilikom pregledanja, ali i veću vjerovatnost da će funkcije web lokacije funkcionirati prema očekivanjima.</translation>
 <translation id="8875520811099717934">Nadogradnja Linuxa</translation>
@@ -10773,6 +10806,7 @@
 <translation id="8973557916016709913">Uklonite nivo zumiranja</translation>
 <translation id="8973596347849323817">Ovaj uređaj možete prilagoditi svojim potrebama. Ove funkcije pristupačnosti možete kasnije izmijeniti u Postavkama.</translation>
 <translation id="897414447285476047">Odredišni fajl je bio nepotpun zbog problema s vezom.</translation>
+<translation id="8974261761101622391">Pronađite alternativu za proširenje <ph name="EXTENSION_NAME" /></translation>
 <translation id="897525204902889653">Usluga karantina</translation>
 <translation id="8975396729541388937">Otkažite pretplatu bilo kada klikom na link u e-porukama koje primite.</translation>
 <translation id="8975562453115131273">{NUM_OTHER_TABS,plural, =0{"<ph name="TAB_TITLE" />"}=1{"<ph name="TAB_TITLE" />" i još jedna kartica}one{"<ph name="TAB_TITLE" />" i još # kartica}few{"<ph name="TAB_TITLE" />" i još # kartice}other{"<ph name="TAB_TITLE" />" i još # kartica}}</translation>
diff --git a/chrome/app/resources/generated_resources_cy.xtb b/chrome/app/resources/generated_resources_cy.xtb
index 5dcf995..59b95158 100644
--- a/chrome/app/resources/generated_resources_cy.xtb
+++ b/chrome/app/resources/generated_resources_cy.xtb
@@ -976,6 +976,7 @@
 <translation id="1697150536837697295">Celf</translation>
 <translation id="1697686431566694143">Golygu ffeil</translation>
 <translation id="1698796500103229697">&amp;Dulliau Talu</translation>
+<translation id="1698899521169711967">Pori caret</translation>
 <translation id="1699807488537653303">Trwsio gwall cyfrinair</translation>
 <translation id="1700201317341192482">Tynnu eich cerdyn rhithwir</translation>
 <translation id="1700517974991662022">Ymwelwyd</translation>
@@ -2486,6 +2487,7 @@
 <translation id="2771816809568414714">Caws</translation>
 <translation id="2772936498786524345">Dirgel</translation>
 <translation id="2773288106548584039">Cefnogaeth Porwr Etifeddiaeth</translation>
+<translation id="2773621783913034737">Gwneud Tabiau'n Anweithredol</translation>
 <translation id="2773802008104670137">Gall y math hwn o ffeil niweidio eich cyfrifiadur.</translation>
 <translation id="2775104091073479743">Golygu Olion Bysedd</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{Roedd yr estyniad "<ph name="EXTENSION" />" yn cyrchu dyfeisiau}=1{Mae'r estyniad "<ph name="EXTENSION" />" yn cyrchu {0} ddyfais}two{Mae'r estyniad "<ph name="EXTENSION" />" yn cyrchu {0} ddyfais}few{Mae'r estyniad "<ph name="EXTENSION" />" yn cyrchu {0} dyfais}many{Mae'r estyniad "<ph name="EXTENSION" />" yn cyrchu {0} dyfais}other{Mae'r estyniad "<ph name="EXTENSION" />" yn cyrchu {0} dyfais}}</translation>
@@ -2566,6 +2568,7 @@
 <translation id="2830528677948328648">Rheoli eich &amp;Cyfrif Google</translation>
 <translation id="2831430281393059038">Cefnogir y ddyfais</translation>
 <translation id="2832124733806557606">Gall eich plentyn ddefnyddio PIN i fewngofnodi neu ddatgloi'r ddyfais.</translation>
+<translation id="2833144527504272627">Llywio gyda chyrchwr testun</translation>
 <translation id="2835177225987815960">Bydd eich gosodiad sganio presennol yn cael ei ailosod, gan gynnwys unrhyw switshis sydd wedi'u haseinio a dewisiadau cyflymder awtosganio.</translation>
 <translation id="2835547721736623118">Gwasanaeth adnabod llais</translation>
 <translation id="2835761321523638096">Darllen a newid cofnodion yn y rhestr ddarllen</translation>
@@ -4122,6 +4125,7 @@
 <translation id="3978325380690188371">Nid yw bysellau gludiog ar gael pan fydd ChromeVox ymlaen</translation>
 <translation id="3979395879372752341">Ychwanegwyd estyniad newydd (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326">Galluogi <ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">Cuddio'r tabiau hyn</translation>
 <translation id="3981058120448670012">Yn weladwy i ddyfeisiau gerllaw fel <ph name="DEVICE_NAME" /> am <ph name="REMAINING_TIME" />...</translation>
 <translation id="3981760180856053153">Rhoddwyd math cadw annilys.</translation>
 <translation id="3982375475032951137">Gosod eich porwr mewn ychydig o gamau syml</translation>
@@ -6314,6 +6318,7 @@
 <translation id="5642508497713047">Llofnodwr SRL</translation>
 <translation id="5643191124441701136">Mae eich cod diogelwch ar flaen eich cerdyn</translation>
 <translation id="5643321261065707929">Rhwydwaith ar fesurydd</translation>
+<translation id="5643717184207603910">Cadw'r perfformiad yn gyflym</translation>
 <translation id="5646376287012673985">Lleoliad</translation>
 <translation id="5646558797914161501">Dyn busnes</translation>
 <translation id="5648021990716966815">Cysylltydd meic</translation>
@@ -6418,6 +6423,7 @@
 <translation id="5733109311583381874">Ychwanegwch eich geiriau eich hun i'r geiriaduron defnyddwyr er mwyn addasu'r ymgeiswyr trosi.</translation>
 <translation id="5734362860645681824">Cyfathrebiadau</translation>
 <translation id="5734697361979786483">Ychwanegu cyfran ffeil</translation>
+<translation id="5735513236153491131">Rhoi Hwb Nawr</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{Nid yw'r data hyn neu eich dyfais yn bodloni rhai o bolisïau diogelwch eich sefydliad. Gwiriwch gyda'ch gweinyddwr beth sydd angen ei drwsio.}=1{Nid yw'r ffeil hon neu eich dyfais yn bodloni rhai o bolisïau diogelwch eich sefydliad. Gwiriwch gyda'ch gweinyddwr beth sydd angen ei drwsio.}two{Nid yw'r ffeiliau hyn yn bodloni rhai o bolisïau diogelwch eich sefydliad. Gwiriwch gyda'ch gweinyddwr beth sydd angen ei drwsio.}few{Nid yw'r ffeiliau hyn yn bodloni rhai o bolisïau diogelwch eich sefydliad. Gwiriwch gyda'ch gweinyddwr beth sydd angen ei drwsio.}many{Nid yw'r ffeiliau hyn yn bodloni rhai o bolisïau diogelwch eich sefydliad. Gwiriwch gyda'ch gweinyddwr beth sydd angen ei drwsio.}other{Nid yw'r ffeiliau hyn yn bodloni rhai o bolisïau diogelwch eich sefydliad. Gwiriwch gyda'ch gweinyddwr beth sydd angen ei drwsio.}}</translation>
 <translation id="5738093759615225354">Mae angen y cod pas hwn arnoch i fewngofnodi i'ch cyfrifiadur</translation>
 <translation id="5739017626473506901">Mewngofnodwch i helpu <ph name="USER_NAME" /> i ychwanegu cyfrif ysgol</translation>
@@ -8236,6 +8242,7 @@
 <translation id="7114054701490058191">Nid yw'r cyfrineiriau'n cyfateb</translation>
 <translation id="7114648273807173152">I ddefnyddio Smart Lock i fewngofnodi i'ch Cyfrif Google, ewch i Gosodiadau &gt; Dyfeisiau sydd wedi'u cysylltu &gt; Eich ffôn &gt; Smart Lock.</translation>
 <translation id="7115361495406486998">Dim cysylltiadau y gellir eu cyrraedd</translation>
+<translation id="7115731767122970828">Rhoi hwb nawr</translation>
 <translation id="7116554090938189816">Mae tystysgrif SSL yr argraffydd wedi darfod. Ailgychwynnwch yr argraffydd a rhowch gynnig arall arni.</translation>
 <translation id="7117228822971127758">Rhowch gynnig arall arni'n nes ymlaen</translation>
 <translation id="7118268675952955085">sgrinlun</translation>
@@ -8391,6 +8398,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Gorau)</translation>
 <translation id="7246230585855757313">Ailfewnosodwch eich allwedd ddiogelwch a rhowch gynnig arall arni</translation>
 <translation id="724835896049478274">Cyfrifon sydd ar gael ar gyfer apiau Android</translation>
+<translation id="7248802599439396696">Gwneud tabiau'n anweithredol</translation>
 <translation id="7249197363678284330">Gallwch newid y gosodiad hwn yn y bar cyfeiriad.</translation>
 <translation id="7249764475759804559">Cynnwys yr ap hwn fel opsiwn wrth agor ffeiliau</translation>
 <translation id="7250616558727237648">Ni wnaeth y ddyfais rydych yn ei rhannu â hi ymateb. Rhowch gynnig arall arni.</translation>
@@ -9985,6 +9993,7 @@
 <translation id="8390392581097975659">Wrthi'n gosod meddalwedd sganiwr</translation>
 <translation id="8390449457866780408">Nid yw'r gweinydd ar gael.</translation>
 <translation id="8391218455464584335">Vinyl</translation>
+<translation id="8391918125842702622">Rhybudd am broblem perfformiad</translation>
 <translation id="8392726714909453725">Gosodiadau dewis i siarad</translation>
 <translation id="8393511274964623038">Stopio'r ategyn</translation>
 <translation id="839363317075970734">Manylion dyfais Bluetooth</translation>
@@ -10085,6 +10094,7 @@
 <translation id="8466052016039127321">Methu â pharhau gyda'r sesiwn flaenorol</translation>
 <translation id="8467326454809944210">Dewis iaith arall</translation>
 <translation id="8468087214092422866">Ni chaniateir i chwilio am ddyfeisiau Bluetooth</translation>
+<translation id="8469863130477774813">Hwb perfformiad ar gael</translation>
 <translation id="8470513973197838199">Mae cyfrineiriau wedi'u cadw ar gyfer <ph name="ORIGIN" /></translation>
 <translation id="8471525937465764768">Mae gwefannau fel arfer yn cysylltu â dyfeisiau USB ar gyfer nodweddion megis argraffu dogfen neu gynilo i ddyfais storio</translation>
 <translation id="8471959340398751476">Mae gostyngiadau wedi'u ddiffodd. Gallwch eu troi ymlaen yn y ddewislen personoleiddio</translation>
diff --git a/chrome/app/resources/generated_resources_da.xtb b/chrome/app/resources/generated_resources_da.xtb
index 863dc43..0fec478cf 100644
--- a/chrome/app/resources/generated_resources_da.xtb
+++ b/chrome/app/resources/generated_resources_da.xtb
@@ -974,6 +974,7 @@
 <translation id="1697150536837697295">Art</translation>
 <translation id="1697686431566694143">Rediger fil</translation>
 <translation id="1698796500103229697">Betalingsmetoder</translation>
+<translation id="1698899521169711967">Tastenavigation</translation>
 <translation id="1699807488537653303">Ret adgangskodefejl</translation>
 <translation id="1700201317341192482">Fjern dit virtuelle kort</translation>
 <translation id="1700517974991662022">Besøgt</translation>
@@ -2484,6 +2485,7 @@
 <translation id="2771816809568414714">Ost</translation>
 <translation id="2772936498786524345">Ninja</translation>
 <translation id="2773288106548584039">Understøttelse af ældre browsere</translation>
+<translation id="2773621783913034737">Gør faner inaktive</translation>
 <translation id="2773802008104670137">Denne type fil kan skade din computer.</translation>
 <translation id="2775104091073479743">Rediger fingeraftryk</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{Udvidelsen "<ph name="EXTENSION" />" havde adgang til enhederne}=1{Udvidelsen "<ph name="EXTENSION" />" har adgang til {0} enhed}one{Udvidelsen "<ph name="EXTENSION" />" har adgang til {0} enhed}other{Udvidelsen "<ph name="EXTENSION" />" har adgang til {0} enheder}}</translation>
@@ -2564,6 +2566,7 @@
 <translation id="2830528677948328648">Administrer din &amp;Google-konto</translation>
 <translation id="2831430281393059038">Enheden understøttes</translation>
 <translation id="2832124733806557606">Dit barn kan bruge en pinkode til at logge ind på enheden eller låse den op.</translation>
+<translation id="2833144527504272627">Naviger med tekstmarkør</translation>
 <translation id="2835177225987815960">Din aktuelle konfiguration af scanning nulstilles, herunder præferencerne for tildelte kontakter og hastigheden ved automatisk scanning.</translation>
 <translation id="2835547721736623118">Tjeneste til talegenkendelse</translation>
 <translation id="2835761321523638096">Læs og rediger poster på læselisten</translation>
@@ -4120,6 +4123,7 @@
 <translation id="3978325380690188371">Træge taster er ikke tilgængelige, når ChromeVox er aktiveret</translation>
 <translation id="3979395879372752341">Ny udvidelse er tilføjet (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326">Aktivér <ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">Skjul disse faner</translation>
 <translation id="3981058120448670012">Andre enheder i nærheden får vist navnet <ph name="DEVICE_NAME" /> i <ph name="REMAINING_TIME" />...</translation>
 <translation id="3981760180856053153">Den indtastede filtype er ugyldig.</translation>
 <translation id="3982375475032951137">Konfigurer din browser ved et hjælp af et par enkle trin</translation>
@@ -6312,6 +6316,7 @@
 <translation id="5642508497713047">CRL-underskriver</translation>
 <translation id="5643191124441701136">Din sikkerhedskode står på forsiden af dit kort</translation>
 <translation id="5643321261065707929">Forbrugsafregnet netværk</translation>
+<translation id="5643717184207603910">Sørg for, at ydeevnen forbliver hurtig</translation>
 <translation id="5646376287012673985">Placering</translation>
 <translation id="5646558797914161501">Forretningsmand</translation>
 <translation id="5648021990716966815">Stik til mikrofon</translation>
@@ -6416,6 +6421,7 @@
 <translation id="5733109311583381874">Føj dine egne ord til brugerordbøger for at tilpasse konverteringskandidaterne.</translation>
 <translation id="5734362860645681824">Kommunikation</translation>
 <translation id="5734697361979786483">Tilføj fildeling</translation>
+<translation id="5735513236153491131">Boost nu</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{Disse data eller din enhed overholder ikke alle din organisations sikkerhedspolitikker. Spørg din administrator, hvad der skal rettes.}=1{Denne fil eller din enhed overholder ikke alle din organisations sikkerhedspolitikker. Spørg din administrator, hvad der skal rettes.}one{Denne fil overholder ikke alle din organisations sikkerhedspolitikker. Spørg din administrator, hvad der skal rettes.}other{Disse filer overholder ikke alle din organisations sikkerhedspolitikker. Spørg din administrator, hvad der skal rettes.}}</translation>
 <translation id="5738093759615225354">Du skal bruge denne adgangsnøgle for at logge ind på din computer</translation>
 <translation id="5739017626473506901">Log ind for at hjælpe <ph name="USER_NAME" /> med at tilføje en skolekonto</translation>
@@ -8229,6 +8235,7 @@
 <translation id="7114054701490058191">Adgangskoderne matcher ikke</translation>
 <translation id="7114648273807173152">Du kan bruge Smart Lock til at logge ind på din Google-konto ved at gå til Indstillinger &gt; Tilsluttede enheder &gt; Din telefon &gt; Smart Lock.</translation>
 <translation id="7115361495406486998">Der er ingen tilgængelige kontakter</translation>
+<translation id="7115731767122970828">Boost nu</translation>
 <translation id="7116554090938189816">Printerens SSL-certifikat er udløbet. Genstart printeren, og prøv igen.</translation>
 <translation id="7117228822971127758">Prøv igen senere</translation>
 <translation id="7118268675952955085">screenshot</translation>
@@ -8384,6 +8391,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Bedste)</translation>
 <translation id="7246230585855757313">Indsæt nøglen igen, og prøv igen.</translation>
 <translation id="724835896049478274">Tilgængelige konti for Android-apps</translation>
+<translation id="7248802599439396696">Gør faner inaktive</translation>
 <translation id="7249197363678284330">Skift denne indstilling i adresselinjen.</translation>
 <translation id="7249764475759804559">Inkluder denne app som en mulighed ved åbning af filer</translation>
 <translation id="7250616558727237648">Den enhed, du deler med, svarede ikke. Prøv igen.</translation>
@@ -9978,6 +9986,7 @@
 <translation id="8390392581097975659">Installerer scannersoftwaren</translation>
 <translation id="8390449457866780408">Serveren er utilgængelig.</translation>
 <translation id="8391218455464584335">Vinylplade</translation>
+<translation id="8391918125842702622">Underretning om problem med ydeevne</translation>
 <translation id="8392726714909453725">Indstillinger for Tekstoplæsning</translation>
 <translation id="8393511274964623038">Stop plugin</translation>
 <translation id="839363317075970734">Oplysninger om Bluetooth-enhed</translation>
@@ -10078,6 +10087,7 @@
 <translation id="8466052016039127321">Forrige session kan ikke genoptages</translation>
 <translation id="8467326454809944210">Vælg et andet sprog</translation>
 <translation id="8468087214092422866">Har ikke tilladelse til at søge efter Bluetooth-enheder</translation>
+<translation id="8469863130477774813">Ydeevnen kan boostes</translation>
 <translation id="8470513973197838199">Gemte adgangskoder til <ph name="ORIGIN" /></translation>
 <translation id="8471525937465764768">Websites opretter normalt forbindelse til USB-enheder for at kunne udskrive dokumenter eller gemme filer på en lagerenhed</translation>
 <translation id="8471959340398751476">Rabatter er slået fra. Du kan slå rabatter til i menuen for personlig tilpasning</translation>
diff --git a/chrome/app/resources/generated_resources_en-GB.xtb b/chrome/app/resources/generated_resources_en-GB.xtb
index c07c9f1..f4ff611f 100644
--- a/chrome/app/resources/generated_resources_en-GB.xtb
+++ b/chrome/app/resources/generated_resources_en-GB.xtb
@@ -973,6 +973,7 @@
 <translation id="1697150536837697295">Art</translation>
 <translation id="1697686431566694143">Edit file</translation>
 <translation id="1698796500103229697">Payment methods</translation>
+<translation id="1698899521169711967">Caret Browsing</translation>
 <translation id="1699807488537653303">Fix password error</translation>
 <translation id="1700201317341192482">Remove your virtual card</translation>
 <translation id="1700517974991662022">Visited</translation>
@@ -1215,7 +1216,7 @@
 <translation id="1868617395637139709">Use location for Android apps and services.</translation>
 <translation id="1869433484041798909">Bookmark button</translation>
 <translation id="1871098866036088250">Open in Chrome browser</translation>
-<translation id="1871131409931646355">Full Download History</translation>
+<translation id="1871131409931646355">Full download history</translation>
 <translation id="187145082678092583">Fewer apps</translation>
 <translation id="1871534214638631766">Show related info when you right-click or long press on content</translation>
 <translation id="1871615898038944731">Your <ph name="DEVICE_TYPE" /> is up to date</translation>
@@ -2483,6 +2484,7 @@
 <translation id="2771816809568414714">Cheese</translation>
 <translation id="2772936498786524345">Sneaky</translation>
 <translation id="2773288106548584039">Legacy Browser Support</translation>
+<translation id="2773621783913034737">Make tabs inactive</translation>
 <translation id="2773802008104670137">This type of file may harm your computer.</translation>
 <translation id="2775104091073479743">Edit Fingerprints</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{Extension ‘<ph name="EXTENSION" />’ was accessing devices}=1{Extension ‘<ph name="EXTENSION" />’ is accessing {0} device}other{Extension ‘<ph name="EXTENSION" />’ is accessing {0} devices}}</translation>
@@ -2563,6 +2565,7 @@
 <translation id="2830528677948328648">Manage your &amp;Google Account</translation>
 <translation id="2831430281393059038">Device is supported</translation>
 <translation id="2832124733806557606">Your child can use a PIN to sign in to or unlock the device.</translation>
+<translation id="2833144527504272627">Navigate with text cursor</translation>
 <translation id="2835177225987815960">Your current scanning setup will be reset, including any assigned switches and auto-scan speed preferences.</translation>
 <translation id="2835547721736623118">Speech recognition service</translation>
 <translation id="2835761321523638096">Read and change entries in the reading list</translation>
@@ -4119,6 +4122,7 @@
 <translation id="3978325380690188371">Sticky keys is not available when ChromeVox is on</translation>
 <translation id="3979395879372752341">New extension added (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326">Enable <ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">Hide these tabs</translation>
 <translation id="3981058120448670012">Visible to nearby devices as <ph name="DEVICE_NAME" /> for <ph name="REMAINING_TIME" />…</translation>
 <translation id="3981760180856053153">Invalid save type entered.</translation>
 <translation id="3982375475032951137">Set up your browser in a few simple steps</translation>
@@ -6311,6 +6315,7 @@
 <translation id="5642508497713047">CRL Signer</translation>
 <translation id="5643191124441701136">Your security code is on the front of your card</translation>
 <translation id="5643321261065707929">Metered network</translation>
+<translation id="5643717184207603910">Keep performance speedy</translation>
 <translation id="5646376287012673985">Location</translation>
 <translation id="5646558797914161501">Businessman</translation>
 <translation id="5648021990716966815">Mic jack</translation>
@@ -6415,6 +6420,7 @@
 <translation id="5733109311583381874">Add your own words to the user dictionaries in order to customise the conversion candidates.</translation>
 <translation id="5734362860645681824">Communications</translation>
 <translation id="5734697361979786483">Add file share</translation>
+<translation id="5735513236153491131">Boost now</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{This data or your device doesn’t meet some of your organisation’s security policies. Check with your admin on what needs to be fixed.}=1{This file or your device doesn’t meet some of your organisation’s security policies. Check with your admin on what needs to be fixed.}other{These files don't meet some of your organisation’s security policies. Check with your admin on what needs to be fixed.}}</translation>
 <translation id="5738093759615225354">You need this passkey to sign in to your computer</translation>
 <translation id="5739017626473506901">Sign in to help <ph name="USER_NAME" /> add a school account</translation>
@@ -8226,6 +8232,7 @@
 <translation id="7114054701490058191">Passwords don't match</translation>
 <translation id="7114648273807173152">To use Smart Lock to sign in to your Google Account, go to Settings &gt; Connected devices &gt; Your phone &gt; Smart Lock.</translation>
 <translation id="7115361495406486998">No reachable contacts</translation>
+<translation id="7115731767122970828">Boost now</translation>
 <translation id="7116554090938189816">Printer SSL certificate is expired. Restart printer and try again.</translation>
 <translation id="7117228822971127758">Please try again later</translation>
 <translation id="7118268675952955085">screenshot</translation>
@@ -8381,6 +8388,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Best)</translation>
 <translation id="7246230585855757313">Reinsert your security key and try again</translation>
 <translation id="724835896049478274">Accounts available for Android apps</translation>
+<translation id="7248802599439396696">Make tabs inactive</translation>
 <translation id="7249197363678284330">Change this setting in the address bar.</translation>
 <translation id="7249764475759804559">Include this app as an option when opening files</translation>
 <translation id="7250616558727237648">The device that you're sharing with didn't respond. Try again.</translation>
@@ -9477,7 +9485,7 @@
 <translation id="803771048473350947">File</translation>
 <translation id="8037801708772278989">Checked just now</translation>
 <translation id="8039151841428107077">{NUM_OF_FILES,plural, =1{Copying 1 file to <ph name="CLOUD_PROVIDER" />}other{Copying {NUM_OF_FILES} files to <ph name="CLOUD_PROVIDER" />}}</translation>
-<translation id="8041089156583427627">Send Feedback</translation>
+<translation id="8041089156583427627">Send feedback</translation>
 <translation id="8041267120753677077">Stream your phone's apps</translation>
 <translation id="8042142357103597104">Text opacity</translation>
 <translation id="8042331986490021244">Your passwords are encrypted on your device before they‘re saved to Google Password Manager</translation>
@@ -9795,7 +9803,7 @@
     <ph name="BEGIN_PARAGRAPH4" />If additional Web &amp; app activity setting is turned on for your child, this data may be saved to their Google Account. Learn more about these settings and how to adjust them at families.google.com.<ph name="END_PARAGRAPH4" /></translation>
 <translation id="826905130698769948">Invalid client certificate</translation>
 <translation id="8270320981823560179">Drive</translation>
-<translation id="82706708334564640">Recent Download History</translation>
+<translation id="82706708334564640">Recent download history</translation>
 <translation id="8270946420566049889">You can customise Chrome the way that you want:
       &lt;ul&gt;
         &lt;li&gt;&lt;em&gt;The best of Google&lt;/em&gt;, for those who want it. For example, you can choose Google Search as Chrome's default search engine and use Google Password Manager to get all your passwords on any device. &lt;/li&gt;
@@ -9976,6 +9984,7 @@
 <translation id="8390392581097975659">Installing scanner software</translation>
 <translation id="8390449457866780408">Server unavailable.</translation>
 <translation id="8391218455464584335">Vinyl</translation>
+<translation id="8391918125842702622">Performance issue alert</translation>
 <translation id="8392726714909453725">Select-to-speak settings</translation>
 <translation id="8393511274964623038">Stop plug-in</translation>
 <translation id="839363317075970734">Bluetooth device details</translation>
@@ -10076,6 +10085,7 @@
 <translation id="8466052016039127321">Can’t resume previous session</translation>
 <translation id="8467326454809944210">Choose another language</translation>
 <translation id="8468087214092422866">Not allowed to look for Bluetooth devices</translation>
+<translation id="8469863130477774813">Performance boost available</translation>
 <translation id="8470513973197838199">Saved passwords for <ph name="ORIGIN" /></translation>
 <translation id="8471525937465764768">Sites usually connect to USB devices for features like printing a document or saving to a storage device</translation>
 <translation id="8471959340398751476">Discounts are off. You can turn them on in the customise menu</translation>
diff --git a/chrome/app/resources/generated_resources_es.xtb b/chrome/app/resources/generated_resources_es.xtb
index 5882b50..9a46f60 100644
--- a/chrome/app/resources/generated_resources_es.xtb
+++ b/chrome/app/resources/generated_resources_es.xtb
@@ -972,6 +972,7 @@
 <translation id="1697150536837697295">Arte</translation>
 <translation id="1697686431566694143">Editar archivo</translation>
 <translation id="1698796500103229697">&amp;Métodos de pago</translation>
+<translation id="1698899521169711967">Navegación por cursor de texto</translation>
 <translation id="1699807488537653303">Corregir error de contraseña</translation>
 <translation id="1700201317341192482">Quitar tu tarjeta virtual</translation>
 <translation id="1700517974991662022">Visitado</translation>
@@ -2471,6 +2472,7 @@
 <translation id="2771816809568414714">Queso</translation>
 <translation id="2772936498786524345">Ninja</translation>
 <translation id="2773288106548584039">Compatibilidad con navegadores antiguos</translation>
+<translation id="2773621783913034737">Inactivar pestañas</translation>
 <translation id="2773802008104670137">Este tipo de archivo puede dañar tu ordenador.</translation>
 <translation id="2775104091073479743">Editar huellas digitales</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{La extensión <ph name="EXTENSION" /> estaba accediendo a dispositivos}=1{La extensión <ph name="EXTENSION" /> está accediendo a {0} dispositivo}other{La extensión <ph name="EXTENSION" /> está accediendo a {0} dispositivos}}</translation>
@@ -2551,6 +2553,7 @@
 <translation id="2830528677948328648">Gestionar tu cuenta de &amp;Google</translation>
 <translation id="2831430281393059038">Dispositivo admitido</translation>
 <translation id="2832124733806557606">Tu hijo/a puede usar el PIN para iniciar sesión en el dispositivo o para desbloquearlo.</translation>
+<translation id="2833144527504272627">Desplazarse con el cursor de texto</translation>
 <translation id="2835177225987815960">Se borrará la configuración de búsqueda actual, incluyendo todos los interruptores asignados y las preferencias de velocidad de la búsqueda automática.</translation>
 <translation id="2835547721736623118">Servicio de reconocimiento de voz</translation>
 <translation id="2835761321523638096">Leer y cambiar entradas en la lista de lectura</translation>
@@ -4105,6 +4108,7 @@
 <translation id="3978325380690188371">Las teclas persistentes no están disponibles cuando ChromeVox está activado</translation>
 <translation id="3979395879372752341">Nueva extensión añadida (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326">Habilitar <ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">Ocultar estas pestañas</translation>
 <translation id="3981058120448670012">Visible para los dispositivos cercanos con el nombre <ph name="DEVICE_NAME" /> durante <ph name="REMAINING_TIME" />...</translation>
 <translation id="3981760180856053153">Tipo de almacenamiento no válido</translation>
 <translation id="3982375475032951137">Configura tu navegador con unos sencillos pasos</translation>
@@ -6296,6 +6300,7 @@
 <translation id="5642508497713047">Firmante de la lista de revocación de certificados</translation>
 <translation id="5643191124441701136">Tu código de seguridad está en la parte delantera de tu tarjeta</translation>
 <translation id="5643321261065707929">Red de uso medido</translation>
+<translation id="5643717184207603910">Mantén un rendimiento rápido</translation>
 <translation id="5646376287012673985">Ubicación</translation>
 <translation id="5646558797914161501">Hombre de negocios</translation>
 <translation id="5648021990716966815">Conector jack para micrófono</translation>
@@ -6400,6 +6405,7 @@
 <translation id="5733109311583381874">Añade tus propias palabras a los diccionarios del usuario para personalizar los candidatos de conversión.</translation>
 <translation id="5734362860645681824">Comunicaciones</translation>
 <translation id="5734697361979786483">Añadir sistema de archivos compartidos</translation>
+<translation id="5735513236153491131">Mejorar ahora</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{Estos datos o tu dispositivo no cumplen algunas de las políticas de seguridad de tu organización. Consulta con tu administrador qué debes corregir.}=1{Este archivo o tu dispositivo no cumplen algunas de las políticas de seguridad de tu organización. Consulta con tu administrador qué debes corregir.}other{Estos archivos no cumplen algunas de las políticas de seguridad de tu organización. Consulta con tu administrador qué debes corregir.}}</translation>
 <translation id="5738093759615225354">Necesitas esta llave de acceso para iniciar sesión en tu ordenador</translation>
 <translation id="5739017626473506901">Inicia sesión para ayudar a <ph name="USER_NAME" /> a añadir una cuenta de centro educativo</translation>
@@ -8211,6 +8217,7 @@
 <translation id="7114054701490058191">Las contraseñas no coinciden</translation>
 <translation id="7114648273807173152">Si quieres usar Smart Lock para iniciar sesión en tu cuenta de Google, ve a Configuración &gt; Dispositivos conectados &gt; Tu teléfono &gt; Smart Lock.</translation>
 <translation id="7115361495406486998">No hay contactos disponibles</translation>
+<translation id="7115731767122970828">Mejorar ahora</translation>
 <translation id="7116554090938189816">El certificado SSL de la impresora ha caducado. Reinicia la impresora e inténtalo de nuevo.</translation>
 <translation id="7117228822971127758">Inténtalo de nuevo más tarde</translation>
 <translation id="7118268675952955085">captura de pantalla</translation>
@@ -8366,6 +8373,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (recomendado)</translation>
 <translation id="7246230585855757313">Vuelve a introducir la llave de seguridad e inténtalo de nuevo.</translation>
 <translation id="724835896049478274">Cuentas disponibles para aplicaciones Android</translation>
+<translation id="7248802599439396696">Inactivar pestañas</translation>
 <translation id="7249197363678284330">Cambia este ajuste en la barra de direcciones.</translation>
 <translation id="7249764475759804559">Incluir esta aplicación como opción al abrir archivos</translation>
 <translation id="7250616558727237648">El dispositivo con el que estás compartiendo contenido no responde. Inténtalo de nuevo.</translation>
@@ -9961,6 +9969,7 @@
 <translation id="8390392581097975659">Instalando software del escáner</translation>
 <translation id="8390449457866780408">Servidor no disponible</translation>
 <translation id="8391218455464584335">Vinilo</translation>
+<translation id="8391918125842702622">Alerta de problema de rendimiento</translation>
 <translation id="8392726714909453725">Configuración de Enunciar selección</translation>
 <translation id="8393511274964623038">Detener complemento</translation>
 <translation id="839363317075970734">Información del dispositivo Bluetooth</translation>
@@ -10061,6 +10070,7 @@
 <translation id="8466052016039127321">No se puede reanudar la sesión anterior</translation>
 <translation id="8467326454809944210">Elegir otro idioma</translation>
 <translation id="8468087214092422866">Sin permiso para buscar dispositivos Bluetooth</translation>
+<translation id="8469863130477774813">Mejora de rendimiento disponible</translation>
 <translation id="8470513973197838199">Contraseñas guardadas de <ph name="ORIGIN" /></translation>
 <translation id="8471525937465764768">Los sitios se suelen conectar a dispositivos USB para usarlos en funciones como la impresión de documentos o el guardado de contenido en dispositivos de almacenamiento.</translation>
 <translation id="8471959340398751476">Los descuentos están desactivados. Puedes activarlos en el menú Personalizar.</translation>
diff --git a/chrome/app/resources/generated_resources_eu.xtb b/chrome/app/resources/generated_resources_eu.xtb
index 122685c..eb47867d 100644
--- a/chrome/app/resources/generated_resources_eu.xtb
+++ b/chrome/app/resources/generated_resources_eu.xtb
@@ -972,6 +972,7 @@
 <translation id="1697150536837697295">Artea</translation>
 <translation id="1697686431566694143">Editatu fitxategia</translation>
 <translation id="1698796500103229697">Ordainketa-metodoak</translation>
+<translation id="1698899521169711967">Testu-kurtsorearen bidez arakatzea</translation>
 <translation id="1699807488537653303">Konpondu pasahitzaren errorea</translation>
 <translation id="1700201317341192482">Kendu txartel birtuala</translation>
 <translation id="1700517974991662022">Bisitatuta</translation>
@@ -2470,6 +2471,7 @@
 <translation id="2771816809568414714">Gazta</translation>
 <translation id="2772936498786524345">Ninja</translation>
 <translation id="2773288106548584039">Arakatzaile zaharrekiko bateragarritasuna</translation>
+<translation id="2773621783913034737">Ezarri fitxak inaktibo</translation>
 <translation id="2773802008104670137">Baliteke fitxategi mota honek ordenagailuari kalte egitea.</translation>
 <translation id="2775104091073479743">Editatu hatz-markak</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{<ph name="EXTENSION" /> luzapena gailuak erabiltzen ari zen}=1{<ph name="EXTENSION" /> luzapena {0} gailu erabiltzen ari da}other{<ph name="EXTENSION" /> luzapena {0} gailu erabiltzen ari da}}</translation>
@@ -2550,6 +2552,7 @@
 <translation id="2830528677948328648">Kudeatu Google-ko kontua</translation>
 <translation id="2831430281393059038">Gailua onartzen da</translation>
 <translation id="2832124733806557606">Haurrak PIN bat erabil dezake saioa hasteko edo gailua desblokeatzeko.</translation>
+<translation id="2833144527504272627">Nabigatu testu-kurtsorearekin</translation>
 <translation id="2835177225987815960">Oraingo mugitze-konfigurazioa berrezarri egingo da, esleitutako etengailuak eta pantailan automatikoki mugitzeko abiadura-hobespenak barne.</translation>
 <translation id="2835547721736623118">Hizketa hautemateko zerbitzua</translation>
 <translation id="2835761321523638096">Irakurri eta aldatu irakurketa-zerrendako sarrerak</translation>
@@ -4104,6 +4107,7 @@
 <translation id="3978325380690188371">Tekla itsaskorrak ez daude erabilgarri ChromeVox aktibatuta dagoenean</translation>
 <translation id="3979395879372752341">Luzapena gehitu da (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326">Gaitu <ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">Ezkutatu fitxa hauek</translation>
 <translation id="3981058120448670012">Inguruko gailuek <ph name="DEVICE_NAME" /> gisa ikusiko dute denbora hau agortu arte: <ph name="REMAINING_TIME" />…</translation>
 <translation id="3981760180856053153">Gordetze motak ez du balio.</translation>
 <translation id="3982375475032951137">Konfiguratu arakatzailea urrats gutxi batzuetan</translation>
@@ -6293,6 +6297,7 @@
 <translation id="5642508497713047">CRL sinatzailea</translation>
 <translation id="5643191124441701136">Segurtasun-kodea txartelaren aurrealdean dago</translation>
 <translation id="5643321261065707929">Sare neurtua</translation>
+<translation id="5643717184207603910">Bizkortu errendimendua</translation>
 <translation id="5646376287012673985">Kokapena</translation>
 <translation id="5646558797914161501">Enpresaria</translation>
 <translation id="5648021990716966815">Mikrofonoaren konektorea</translation>
@@ -6397,6 +6402,7 @@
 <translation id="5733109311583381874">Bihurketa-aukerak pertsonalizatzeko, gehitu zeure hitzak erabiltzailearen hiztegietan.</translation>
 <translation id="5734362860645681824">Komunikazioak</translation>
 <translation id="5734697361979786483">Gehitu fitxategiak partekatzeko biltegia</translation>
+<translation id="5735513236153491131">Hobetu</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{Datuek edo gailuak ez dituzte gordetzen erakundearen segurtasun-gidalerro batzuk. Galdetu administratzaileari ea zer konpondu behar den.}=1{Fitxategiak edo gailuak ez ditu gordetzen erakundearen segurtasun-gidalerro batzuk. Galdetu administratzaileari ea zer konpondu behar den.}other{Fitxategiek ez dituzte gordetzen erakundearen segurtasun-gidalerro batzuk. Galdetu administratzaileari ea zer konpondu behar den.}}</translation>
 <translation id="5738093759615225354">Sarbide-gako hau behar duzu ordenagailuan saioa hasteko</translation>
 <translation id="5739017626473506901">Hasi saioa <ph name="USER_NAME" /> erabiltzaileak ikastetxeko kontua gehi dezan</translation>
@@ -8206,6 +8212,7 @@
 <translation id="7114054701490058191">Pasahitzak ez datoz bat</translation>
 <translation id="7114648273807173152">Smart Lock erabili nahi baduzu Google-ko kontuan saioa hasteko, joan Ezarpenak &gt; Konektatutako gailuak &gt; Zure telefonoa &gt; Smart Lock atalera.</translation>
 <translation id="7115361495406486998">Ez dago kontaktu eskuragarririk</translation>
+<translation id="7115731767122970828">Hobetu</translation>
 <translation id="7116554090938189816">Inprimagailuaren SSL ziurtagiria iraungi egin da. Berrabiarazi inprimagailua eta saiatu berriro.</translation>
 <translation id="7117228822971127758">Saiatu berriro geroago</translation>
 <translation id="7118268675952955085">pantaila-argazkia</translation>
@@ -8361,6 +8368,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> × <ph name="HEIGHT" /> (onena)</translation>
 <translation id="7246230585855757313">Sartu segurtasun-giltza eta saiatu berriro</translation>
 <translation id="724835896049478274">Android-erako aplikazioetan erabil daitezkeen kontuak</translation>
+<translation id="7248802599439396696">Ezarri fitxak inaktibo</translation>
 <translation id="7249197363678284330">Aldatu ezarpena helbide-barran.</translation>
 <translation id="7249764475759804559">Gehitu aplikazio hau fitxategiak irekitzeko aukera gisa</translation>
 <translation id="7250616558727237648">Edukia partekatzeko erabiltzen ari zaren gailuak ez dio erantzun fitxategia onartu edo baztertzeko eskaerari. Saiatu berriro.</translation>
@@ -9954,6 +9962,7 @@
 <translation id="8390392581097975659">Eskanerraren softwarea instalatzen</translation>
 <translation id="8390449457866780408">Zerbitzaria ez dago erabilgarri.</translation>
 <translation id="8391218455464584335">Biniloa</translation>
+<translation id="8391918125842702622">Errendimendu-arazoaren alerta</translation>
 <translation id="8392726714909453725">"Hautatu ozen irakurtzeko" eginbidearen ezarpenak</translation>
 <translation id="8393511274964623038">Gelditu plugina</translation>
 <translation id="839363317075970734">Bluetooth bidezko gailuaren xehetasunak</translation>
@@ -10054,6 +10063,7 @@
 <translation id="8466052016039127321">Ezin zaio berrekin aurreko saioari</translation>
 <translation id="8467326454809944210">Aukeratu beste hizkuntza bat</translation>
 <translation id="8468087214092422866">Bluetooth bidezko gailuak bilatzeko baimenik ez dutenak</translation>
+<translation id="8469863130477774813">Errendimendua hobe daiteke</translation>
 <translation id="8470513973197838199"><ph name="ORIGIN" /> webgunean gordetako pasahitzak</translation>
 <translation id="8471525937465764768">Webguneak USB bidezko gailuetara konektatu ohi dira dokumentu bat inprimatzeko edo biltegiratze-gailu batean gordetzeko, eta antzeko eginbideak eskaintzeko</translation>
 <translation id="8471959340398751476">Deskontuak aurkitzeko eginbidea desaktibatuta dago. Aktiba ezazu Pertsonalizatu menuan.</translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb
index c637cf06..09ab04d 100644
--- a/chrome/app/resources/generated_resources_fa.xtb
+++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -973,6 +973,7 @@
 <translation id="1697150536837697295">هنری</translation>
 <translation id="1697686431566694143">ویرایش فایل</translation>
 <translation id="1698796500103229697">&amp;روش‌های پرداخت</translation>
+<translation id="1698899521169711967">مرور با هشتک</translation>
 <translation id="1699807488537653303">رفع خطای گذرواژه</translation>
 <translation id="1700201317341192482">حذف کارت مجازی</translation>
 <translation id="1700517974991662022">بازدیدشده</translation>
@@ -2485,6 +2486,7 @@
 <translation id="2771816809568414714">پنیر</translation>
 <translation id="2772936498786524345">مأمور مخفی</translation>
 <translation id="2773288106548584039">پشتیبانی از مرورگر قدیمی</translation>
+<translation id="2773621783913034737">غیرفعال کردن برگه‌ها</translation>
 <translation id="2773802008104670137">این نوع فایل ممکن است به رایانه شما صدمه بزند.</translation>
 <translation id="2775104091073479743">ویرایش اثر انگشت</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{افزونه «<ph name="EXTENSION" />» به دستگاه‌ها دسترسی داشت}=1{افزونه «<ph name="EXTENSION" />» به {0} دستگاه دسترسی دارد}one{افزونه «<ph name="EXTENSION" />» به {0} دستگاه دسترسی دارد}other{افزونه «<ph name="EXTENSION" />» به {0} دستگاه دسترسی دارد}}</translation>
@@ -2565,6 +2567,7 @@
 <translation id="2830528677948328648">‏مدیریت «حساب Google»</translation>
 <translation id="2831430281393059038">دستگاه پشتیبانی می‌شود</translation>
 <translation id="2832124733806557606">فرزندتان می‌تواند برای ورود به سیستم یا باز کردن قفل دستگاه از پین استفاده کند.</translation>
+<translation id="2833144527504272627">پیمایش با مکان‌نمای نوشتار</translation>
 <translation id="2835177225987815960">راه‌اندازی اسکن فعلی بازنشانی خواهد شد، ازجمله کلیدهای واگذارشده و اولویت‌های سرعت اسکن خودکار.</translation>
 <translation id="2835547721736623118">سرویس تشخیص گفتار</translation>
 <translation id="2835761321523638096">خواندن و تغییر ورودی‌ها در فهرست خواندن</translation>
@@ -4123,6 +4126,7 @@
 <translation id="3978325380690188371">‏هنگام روشن بودن ChromeVox، کلیدهای چسبان دردسترس نیست</translation>
 <translation id="3979395879372752341">افزودنه‌های جدید اضافه شد (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326">فعال کردن <ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">پنهان کردن این برگه‌ها</translation>
 <translation id="3981058120448670012">نمایان برای دستگاه‌های اطراف با نام <ph name="DEVICE_NAME" /> به‌مدت <ph name="REMAINING_TIME" />…</translation>
 <translation id="3981760180856053153">نوع ذخیره نامعتبری وارد شده است.</translation>
 <translation id="3982375475032951137">راه‌اندازی مرورگر طی چند مرحله ساده</translation>
@@ -6318,6 +6322,7 @@
 <translation id="5642508497713047">‏امضاکننده CRL</translation>
 <translation id="5643191124441701136">کد امنیتی شما روی کارت درج شده است</translation>
 <translation id="5643321261065707929">شبکه محدود</translation>
+<translation id="5643717184207603910">سرعت بالای عملکرد را حفظ کنید</translation>
 <translation id="5646376287012673985">مکان</translation>
 <translation id="5646558797914161501">فروشنده</translation>
 <translation id="5648021990716966815">فیش میکروفون</translation>
@@ -6422,6 +6427,7 @@
 <translation id="5733109311583381874">کلمات موردنظرتان را به فرهنگ‌های لغت کاربر اضافه کنید تا موارد برگزیده برای تبدیل را سفارشی کنید.</translation>
 <translation id="5734362860645681824">ارتباطات</translation>
 <translation id="5734697361979786483">افزودن دستگاه ذخیره‌سازی متصل به شبکه</translation>
+<translation id="5735513236153491131">اکنون تقویت شود</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{این داده یا دستگاه شما برخی‌از خط‌مشی‌های امنیتی سازمانتان را رعایت نمی‌کند. مواردی را که باید برطرف شود از سرپرست خود بپرسید.}=1{این فایل یا دستگاه شما برخی‌از خط‌مشی‌های امنیتی سازمانتان را رعایت نمی‌کند. مواردی را که باید برطرف شود از سرپرست خود بپرسید.}one{این فایل‌ها برخی‌از خط‌مشی‌های امنیتی سازمانتان را رعایت نمی‌کنند. مواردی را که باید برطرف شود از سرپرست خود بپرسید.}other{این فایل‌ها برخی‌از خط‌مشی‌های امنیتی سازمانتان را رعایت نمی‌کنند. مواردی را که باید برطرف شود از سرپرست خود بپرسید.}}</translation>
 <translation id="5738093759615225354">برای ورود به سیستم رایانه‌تان به این گذرکلید نیاز دارید</translation>
 <translation id="5739017626473506901">به سیستم وارد شوید تا بتوانید به <ph name="USER_NAME" /> در افزودن حساب محل تحصیل کمک کنید</translation>
@@ -8236,6 +8242,7 @@
 <translation id="7114054701490058191">گذرواژه‌ها مطابقت ندارند</translation>
 <translation id="7114648273807173152">‏برای استفاده از Smart Lock برای ورود به سیستم حساب Google، به «تنظیمات &gt; دستگاه‌های متصل &gt; Smart Lock» بروید.</translation>
 <translation id="7115361495406486998">مخاطبی دردسترس نیست</translation>
+<translation id="7115731767122970828">اکنون تقویت شود</translation>
 <translation id="7116554090938189816">‏گواهینامه SSL چاپگر منقضی شده است. چاپگر را بازراه‌اندازی کنید و دوباره امتحان کنید.</translation>
 <translation id="7117228822971127758">لطفاً بعداً دوباره امتحان کنید</translation>
 <translation id="7118268675952955085">نماگرفت</translation>
@@ -8391,6 +8398,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> × <ph name="HEIGHT" /> (بهترین)</translation>
 <translation id="7246230585855757313">کلید ایمنی را مجدداً وارد کنید و دوباره امتحان کنید</translation>
 <translation id="724835896049478274">‏حساب‌های دردسترس برای برنامه‌های Android</translation>
+<translation id="7248802599439396696">غیرفعال کردن برگه‌ها</translation>
 <translation id="7249197363678284330">این تنظیم را در نوار نشانی تغییر دهید.</translation>
 <translation id="7249764475759804559">هنگام باز کردن فایل‌ها این برنامه به‌عنوان یکی از گزینه‌ها ارائه شود</translation>
 <translation id="7250616558727237648">دستگاهی که درحال هم‌رسانی با آن هستید پاسخی نداد. لطفاً دوباره امتحان کنید.</translation>
@@ -9988,6 +9996,7 @@
 <translation id="8390392581097975659">درحال نصب نرم‌افزار اسکنر</translation>
 <translation id="8390449457866780408">سرور در دسترس نیست.</translation>
 <translation id="8391218455464584335">صفحه گرامافون</translation>
+<translation id="8391918125842702622">هشدار مشکل عملکرد</translation>
 <translation id="8392726714909453725">تنظیمات «انتخاب برای شنیدن»</translation>
 <translation id="8393511274964623038">توقف افزایه</translation>
 <translation id="839363317075970734">جزئیات دستگاه بلوتوث</translation>
@@ -10088,6 +10097,7 @@
 <translation id="8466052016039127321">جلسه قبلی ازسر گرفته نشد</translation>
 <translation id="8467326454809944210">انتخاب زبانی دیگر</translation>
 <translation id="8468087214092422866">اجازه ندارند دستگاه‌های بلوتوث را جستجو کند</translation>
+<translation id="8469863130477774813">تقویت عملکرد دردسترس است</translation>
 <translation id="8470513973197838199">گذرواژه‌های ذخیره‌شده برای <ph name="ORIGIN" /></translation>
 <translation id="8471525937465764768">‏سایت‌ها معمولاً برای ارائه ویژگی‌هایی مانند چاپ سند یا ذخیره در دستگاه ذخیره‌سازی به دستگاه‌های USB متصل می‌شوند</translation>
 <translation id="8471959340398751476">تخفیف‌ها خاموش هستند. می‌توانید در منوی سفارشی آن‌ها را روشن کنید</translation>
diff --git a/chrome/app/resources/generated_resources_fil.xtb b/chrome/app/resources/generated_resources_fil.xtb
index f4c91343..4d9fbff 100644
--- a/chrome/app/resources/generated_resources_fil.xtb
+++ b/chrome/app/resources/generated_resources_fil.xtb
@@ -974,6 +974,7 @@
 <translation id="1697150536837697295">Sining</translation>
 <translation id="1697686431566694143">I-edit ang file</translation>
 <translation id="1698796500103229697">&amp;Mga Paraan ng Pagbabayad</translation>
+<translation id="1698899521169711967">Caret browsing</translation>
 <translation id="1699807488537653303">Ayusin ang error sa password</translation>
 <translation id="1700201317341192482">Alisin ang iyong virtual card</translation>
 <translation id="1700517974991662022">Nabisita na</translation>
@@ -2484,6 +2485,7 @@
 <translation id="2771816809568414714">Keso</translation>
 <translation id="2772936498786524345">Ninja</translation>
 <translation id="2773288106548584039">Suporta sa Legacy Browser</translation>
+<translation id="2773621783913034737">Gawing Hindi Aktibo ang Mga Tab</translation>
 <translation id="2773802008104670137">Maaaring maapektuhan ng ganitong uri ng file ang iyong computer.</translation>
 <translation id="2775104091073479743">I-edit ang Mga Fingerprint</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{Nag-access ang extension na "<ph name="EXTENSION" />" ng mga device}=1{Nag-a-access ang extension na "<ph name="EXTENSION" />" ng {0} device}one{Nag-a-access ang extension na "<ph name="EXTENSION" />" ng {0} device}other{Nag-a-access ang extension na "<ph name="EXTENSION" />" ng {0} na device}}</translation>
@@ -2564,6 +2566,7 @@
 <translation id="2830528677948328648">Pamahalaan ang iyong &amp;Google account</translation>
 <translation id="2831430281393059038">Sinusuportahan ang device</translation>
 <translation id="2832124733806557606">Puwedeng gumamit ng PIN ang iyong anak para mag-sign in sa o i-unlock ang device.</translation>
+<translation id="2833144527504272627">Mag-navigate gamit ang cursor ng text</translation>
 <translation id="2835177225987815960">Mare-reset ang iyong kasalukuyang setup ng pag-scan, kasama ang anumang nakatalagang switch at kagustuhan sa bilis ng awtomatikong pag-scan.</translation>
 <translation id="2835547721736623118">Serbisyo ng pagkilala sa speech</translation>
 <translation id="2835761321523638096">Basahin at baguhin ang mga entry sa listahan ng babasahin.</translation>
@@ -4120,6 +4123,7 @@
 <translation id="3978325380690188371">Hindi available ang mga sticky key kapag naka-on ang ChromeVox</translation>
 <translation id="3979395879372752341">Nagdagdag ng bagong extension (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326">Paganahin ang <ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">I-hide ang mga tab na ito</translation>
 <translation id="3981058120448670012">Visible sa mga kalapit na device bilang <ph name="DEVICE_NAME" /> sa loob ng <ph name="REMAINING_TIME" />...</translation>
 <translation id="3981760180856053153">Di-wastong uri ng pag-save ang ipinasok.</translation>
 <translation id="3982375475032951137">I-set up ang iyong browser gamit ang ilang simpleng hakbang</translation>
@@ -6312,6 +6316,7 @@
 <translation id="5642508497713047">Tagapaglagda ng CRL</translation>
 <translation id="5643191124441701136">Nasa harap ng iyong card ang panseguridad na code mo</translation>
 <translation id="5643321261065707929">Nakametrong network</translation>
+<translation id="5643717184207603910">Panatilihing mabilis ang performance</translation>
 <translation id="5646376287012673985">Lokasyon</translation>
 <translation id="5646558797914161501">Negosyante</translation>
 <translation id="5648021990716966815">Jack ng mikropono</translation>
@@ -6416,6 +6421,7 @@
 <translation id="5733109311583381874">Magdagdag ng sarili mong mga salita sa diksyunaryo ng user para ma-customize ang mga kandidato ng conversion.</translation>
 <translation id="5734362860645681824">Komunikasyon</translation>
 <translation id="5734697361979786483">Magdagdag ng file share</translation>
+<translation id="5735513236153491131">Mag-boost Ngayon</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{Hindi natutugunan ng data na ito o ng iyong device ang ilan sa mga patakarang panseguridad ng organisasyon mo. Itanong sa iyong admin kung ano ang kailangang ayusin.}=1{Hindi natutugunan ng file na ito o ng iyong device ang ilan sa mga patakarang panseguridad ng organisasyon mo. Itanong sa iyong admin kung ano ang kailangang ayusin.}one{Hindi natutugunan ng mga file na ito ang ilan sa mga patakarang panseguridad ng organisasyon mo. Itanong sa iyong admin kung ano ang kailangang ayusin.}other{Hindi natutugunan ng mga file na ito ang ilan sa mga patakarang panseguridad ng organisasyon mo. Itanong sa iyong admin kung ano ang kailangang ayusin.}}</translation>
 <translation id="5738093759615225354">Kailangan mo ang passkey na ito para mag-sign in sa iyong computer</translation>
 <translation id="5739017626473506901">Mag-sign in para matulungan si <ph name="USER_NAME" /> na magdagdag ng pampaaralang account</translation>
@@ -8229,6 +8235,7 @@
 <translation id="7114054701490058191">Hindi magkatugma ang mga password</translation>
 <translation id="7114648273807173152">Para gamitin ang Smart Lock para mag-sign in sa iyong Google Account, pumunta sa Mga Setting &gt; Mga nakakonektang device &gt; Iyong telepono &gt; Smart Lock.</translation>
 <translation id="7115361495406486998">Walang maabot na contact</translation>
+<translation id="7115731767122970828">Mag-boost ngayon</translation>
 <translation id="7116554090938189816">Nag-expire na ang SSL certificate ng printer. I-restart ang printer at subukan ulit.</translation>
 <translation id="7117228822971127758">Pakisubukang muli sa ibang pagkakataon</translation>
 <translation id="7118268675952955085">screenshot</translation>
@@ -8384,6 +8391,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Pinakamainam)</translation>
 <translation id="7246230585855757313">Muling ipasok ang iyong security key at subukan ulit</translation>
 <translation id="724835896049478274">Mga account na available para sa mga Android app</translation>
+<translation id="7248802599439396696">Gawing hindi aktibo ang mga tab</translation>
 <translation id="7249197363678284330">Baguhin ang setting na ito sa address bar.</translation>
 <translation id="7249764475759804559">Isama ang app na ito bilang opsyon kapag nagbubukas ng mga file</translation>
 <translation id="7250616558727237648">Hindi tumugon ang device kung saan ka nagbabahagi. Pakisubukan ulit.</translation>
@@ -9979,6 +9987,7 @@
 <translation id="8390392581097975659">Ini-install ang software ng scanner</translation>
 <translation id="8390449457866780408">Hindi available ang server.</translation>
 <translation id="8391218455464584335">Vinyl</translation>
+<translation id="8391918125842702622">Alerto sa isyu sa performance</translation>
 <translation id="8392726714909453725">Mga setting ng select-to-speak</translation>
 <translation id="8393511274964623038">Ihinto ang plugin</translation>
 <translation id="839363317075970734">Mga detalye ng Bluetooth device</translation>
@@ -10080,6 +10089,7 @@
 <translation id="8466052016039127321">Hindi maipagpatuloy ang nakaraang session</translation>
 <translation id="8467326454809944210">Pumili ng iba pang wika</translation>
 <translation id="8468087214092422866">Hindi pinapayagang maghanap ng mga Bluetooth device</translation>
+<translation id="8469863130477774813">Available ang pang-boost ng performance</translation>
 <translation id="8470513973197838199">Mga naka-save na password para sa <ph name="ORIGIN" /></translation>
 <translation id="8471525937465764768">Karaniwang kumokonekta ang mga site sa mga USB device para sa mga feature gaya ng pag-print ng dokumento o pag-save sa storage device</translation>
 <translation id="8471959340398751476">Naka-off ang mga diskwento. Puwede mong i-on ang mga ito sa menu na i-customize</translation>
diff --git a/chrome/app/resources/generated_resources_fr-CA.xtb b/chrome/app/resources/generated_resources_fr-CA.xtb
index 2bcb3fc..8f4fcfd 100644
--- a/chrome/app/resources/generated_resources_fr-CA.xtb
+++ b/chrome/app/resources/generated_resources_fr-CA.xtb
@@ -973,6 +973,7 @@
 <translation id="1697150536837697295">Art</translation>
 <translation id="1697686431566694143">Modifier le fichier</translation>
 <translation id="1698796500103229697">Méthodes de paiement</translation>
+<translation id="1698899521169711967">Navigation au clavier</translation>
 <translation id="1699807488537653303">Corriger l'erreur de mot de passe</translation>
 <translation id="1700201317341192482">Retirer votre carte virtuelle</translation>
 <translation id="1700517974991662022">Visité</translation>
@@ -2472,6 +2473,7 @@
 <translation id="2771816809568414714">Fromage</translation>
 <translation id="2772936498786524345">Sournois</translation>
 <translation id="2773288106548584039">Prise en charge de navigateurs hérités</translation>
+<translation id="2773621783913034737">Rendre les onglets inactifs</translation>
 <translation id="2773802008104670137">Ce type de fichier peut endommager votre ordinateur.</translation>
 <translation id="2775104091073479743">Modifier les empreintes digitales</translation>
 <translation id="2775858145769350417">{NUM_APPS,plural, =1{Retirer 1 application non prise en charge}one{Retirer # application non prise en charge}other{Retirer # applications non prises en charge}}</translation>
@@ -2553,6 +2555,7 @@
 <translation id="2830528677948328648">&amp;Gérer votre compte Google</translation>
 <translation id="2831430281393059038">L'appareil est pris en charge</translation>
 <translation id="2832124733806557606">Votre enfant peut utiliser un NIP pour se connecter à l'appareil ou pour le déverrouiller.</translation>
+<translation id="2833144527504272627">Naviguer avec le curseur de texte</translation>
 <translation id="2835177225987815960">Votre configuration de recherche actuelle sera réinitialisée, y compris les commutateurs attribués et les préférences de vitesse de la recherche automatique.</translation>
 <translation id="2835547721736623118">Service de reconnaissance vocale</translation>
 <translation id="2835761321523638096">Lire et modifier des entrées dans la Liste de lecture</translation>
@@ -4109,6 +4112,7 @@
 <translation id="3978325380690188371">Les touches rémanentes ne sont pas disponibles lorsque ChromeVox est activé</translation>
 <translation id="3979395879372752341">Nouvelle extension installée (<ph name="EXTENSION_NAME" />).</translation>
 <translation id="3979748722126423326">Activer <ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">Masquer ces onglets</translation>
 <translation id="3981058120448670012">Visible aux appareils à proximité en tant que <ph name="DEVICE_NAME" /> pendant <ph name="REMAINING_TIME" />…</translation>
 <translation id="3981760180856053153">Format d'enregistrement incorrect.</translation>
 <translation id="3982375475032951137">Configurez votre navigateur en quelques étapes simples</translation>
@@ -6300,6 +6304,7 @@
 <translation id="5642508497713047">Signataire de la liste de révocation de certificats</translation>
 <translation id="5643191124441701136">Votre code de sécurité se trouve au recto de votre carte</translation>
 <translation id="5643321261065707929">Réseau à connexion mesurée</translation>
+<translation id="5643717184207603910">Maintenir des performances rapides</translation>
 <translation id="5646376287012673985">Lieu</translation>
 <translation id="5646558797914161501">Homme d'affaires</translation>
 <translation id="5648021990716966815">Prise du microphone</translation>
@@ -6404,6 +6409,7 @@
 <translation id="5733109311583381874">Ajoutez vos propres mots aux dictionnaires personnels afin de personnaliser les candidats de conversion.</translation>
 <translation id="5734362860645681824">Communications</translation>
 <translation id="5734697361979786483">Ajouter un partage de fichier</translation>
+<translation id="5735513236153491131">Améliorer maintenant</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{Cette donnée ou votre appareil ne respecte pas certaines des politiques de sécurité de votre organisation. Vérifiez auprès de votre administrateur ce qui doit être corrigé.}=1{Ce fichier ou votre appareil ne respecte pas certaines des politiques de sécurité de votre organisation. Vérifiez auprès de votre administrateur ce qui doit être corrigé.}one{Ce fichier ne respecte pas certaines des politiques de sécurité de votre organisation. Vérifiez auprès de votre administrateur ce qui doit être corrigé.}other{Ces fichiers ne respectent pas certaines des politiques de sécurité de votre organisation. Vérifiez auprès de votre administrateur ce qui doit être corrigé.}}</translation>
 <translation id="5738093759615225354">Vous avez besoin de cette clé d'accès pour vous connecter à votre ordinateur</translation>
 <translation id="5739017626473506901">Connectez-vous pour aider <ph name="USER_NAME" /> à ajouter un compte scolaire</translation>
@@ -8216,6 +8222,7 @@
 <translation id="7114054701490058191">Les mots de passe ne correspondent pas</translation>
 <translation id="7114648273807173152">Pour utiliser Smart Lock pour vous connecter à votre compte Google, accédez à Paramètres &gt; Appareils connectés &gt; Votre téléphone &gt; Smart Lock.</translation>
 <translation id="7115361495406486998">Aucun contact joignable</translation>
+<translation id="7115731767122970828">Améliorer maintenant</translation>
 <translation id="7116554090938189816">Le certificat SSL de l'imprimante a expiré. Redémarrez l'imprimante et réessayez.</translation>
 <translation id="7117228822971127758">Veuillez réessayer plus tard</translation>
 <translation id="7118268675952955085">Capture d'écran</translation>
@@ -8371,6 +8378,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Meilleure résolution)</translation>
 <translation id="7246230585855757313">Réinsérez votre clé de sécurité, puis réessayez</translation>
 <translation id="724835896049478274">Comptes accessibles aux applications Android</translation>
+<translation id="7248802599439396696">Rendre les onglets inactifs</translation>
 <translation id="7249197363678284330">Modifiez ce paramètre dans la barre d'adresse.</translation>
 <translation id="7249764475759804559">Inclure cette application comme option lors de l'ouverture de fichiers</translation>
 <translation id="7250616558727237648">L'appareil avec lequel vous tentez de partager le fichier ne répond pas. Veuillez réessayer.</translation>
@@ -9965,6 +9973,7 @@
 <translation id="8390392581097975659">Installation du logiciel du numériseur en cours…</translation>
 <translation id="8390449457866780408">Serveur inaccessible.</translation>
 <translation id="8391218455464584335">Disque de vinyle</translation>
+<translation id="8391918125842702622">Alerte de problème de performances</translation>
 <translation id="8392726714909453725">Paramètres de Sélectionner pour énoncer</translation>
 <translation id="8393511274964623038">Arrêter le plugiciel</translation>
 <translation id="839363317075970734">Détails relatifs à l'appareil Bluetooth</translation>
@@ -10065,6 +10074,7 @@
 <translation id="8466052016039127321">Impossible de reprendre la session précédente</translation>
 <translation id="8467326454809944210">Choisir une autre langue</translation>
 <translation id="8468087214092422866">Non autorisé à rechercher les appareils Bluetooth</translation>
+<translation id="8469863130477774813">Amélioration des performances disponible</translation>
 <translation id="8470513973197838199">Mots de passe enregistrés pour <ph name="ORIGIN" /></translation>
 <translation id="8471525937465764768">Les sites se connectent généralement aux appareils USB pour proposer des fonctionnalités comme l'impression de document ou l'enregistrement sur un périphérique de stockage</translation>
 <translation id="8471959340398751476">Les rabais sont désactivés. Vous pouvez les activer dans le menu de personnalisation</translation>
diff --git a/chrome/app/resources/generated_resources_hi.xtb b/chrome/app/resources/generated_resources_hi.xtb
index 43605dcf..2322da7 100644
--- a/chrome/app/resources/generated_resources_hi.xtb
+++ b/chrome/app/resources/generated_resources_hi.xtb
@@ -974,6 +974,7 @@
 <translation id="1697150536837697295">कला</translation>
 <translation id="1697686431566694143">फ़ाइल में बदलाव करें</translation>
 <translation id="1698796500103229697">पैसे चुकाने के तरीके</translation>
+<translation id="1698899521169711967">कैरेट ब्राउज़िंग</translation>
 <translation id="1699807488537653303">पासवर्ड की गड़बड़ी ठीक करें</translation>
 <translation id="1700201317341192482">अपना वर्चुअल कार्ड हटाएं</translation>
 <translation id="1700517974991662022">देखा गया</translation>
@@ -2484,6 +2485,7 @@
 <translation id="2771816809568414714">पनीर</translation>
 <translation id="2772936498786524345">स्नीकी</translation>
 <translation id="2773288106548584039">पुराने ब्राउज़र के लिए मदद</translation>
+<translation id="2773621783913034737">टैब बंद करें</translation>
 <translation id="2773802008104670137">इस प्रकार की फ़ाइल आपके कंप्यूटर को हानि पहुंचा सकती है.</translation>
 <translation id="2775104091073479743">फ़िंगरप्रिंट में बदलाव करें</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{"<ph name="EXTENSION" />" एक्सटेंशन, डिवाइसों को ऐक्सेस कर रहा था}=1{"<ph name="EXTENSION" />" एक्सटेंशन, {0} डिवाइस को ऐक्सेस कर रहा है}one{"<ph name="EXTENSION" />" एक्सटेंशन, {0} डिवाइस को ऐक्सेस कर रहा है}other{"<ph name="EXTENSION" />" एक्सटेंशन, {0} डिवाइसों को ऐक्सेस कर रहा है}}</translation>
@@ -2564,6 +2566,7 @@
 <translation id="2830528677948328648">अपना Google खाता मैनेज करें</translation>
 <translation id="2831430281393059038">इस डिवाइस पर वीएम सॉफ़्टवेयर इस्तेमाल किया जा सकता है</translation>
 <translation id="2832124733806557606">इस डिवाइस में साइन इन करने या इसे अनलॉक करने के लिए, आपका बच्चा पिन का इस्तेमाल कर सकता है.</translation>
+<translation id="2833144527504272627">टेक्स्ट कर्सर की मदद से नेविगेट करें</translation>
 <translation id="2835177225987815960">स्कैन करने वाला आपका मौजूदा सेट अप रीसेट हो जाएगा. इसमें, असाइन किए गए स्विच और अपने-आप तेज़ी से स्कैन होने की सेटिंग शामिल हैं.</translation>
 <translation id="2835547721736623118">बोली पहचानने की सुविधा</translation>
 <translation id="2835761321523638096">रीडिंग लिस्ट में एंट्री पढ़ें और उन्हें बदलें</translation>
@@ -4119,6 +4122,7 @@
 <translation id="3978325380690188371">ChromeVox के चालू होने पर, स्टिकी बटन की सुविधा उपलब्ध नहीं होती</translation>
 <translation id="3979395879372752341">नया एक्सटेंशन जोड़ा गया (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326"><ph name="NETWORKDEVICE" /> चालू करें</translation>
+<translation id="398095528354975981">इन टैब को छिपाएं</translation>
 <translation id="3981058120448670012"><ph name="REMAINING_TIME" /> तक आस-पास के डिवाइस को <ph name="DEVICE_NAME" /> के तौर पर दिखेगा...</translation>
 <translation id="3981760180856053153">सेव करने का गलत तरीका दर्ज किया गया.</translation>
 <translation id="3982375475032951137">कुछ आसान चरणों में अपना ब्राउज़र सेट करें</translation>
@@ -6310,6 +6314,7 @@
 <translation id="5642508497713047">CRL हस्ताक्षरकर्ता</translation>
 <translation id="5643191124441701136">आपके कार्ड के अगले हिस्से पर आपका सुरक्षा कोड मौजूद होता है</translation>
 <translation id="5643321261065707929">सीमित डेटा वाला नेटवर्क</translation>
+<translation id="5643717184207603910">परफ़ॉर्मेंस को बेहतर बनाए रखें</translation>
 <translation id="5646376287012673985">जगह की जानकारी</translation>
 <translation id="5646558797914161501">व्यवसायी</translation>
 <translation id="5648021990716966815">माइक जैक</translation>
@@ -6414,6 +6419,7 @@
 <translation id="5733109311583381874">उपयोगकर्ता डिक्शनरी में अपने शब्द जोड़ें, ताकि उम्मीदवारों को आसानी से ग्राहकों में बदला जा सके.</translation>
 <translation id="5734362860645681824">संचार</translation>
 <translation id="5734697361979786483">फ़ाइल शेयर जोड़ें</translation>
+<translation id="5735513236153491131">अभी बूस्ट करें</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{यह डेटा या आपका डिवाइस, आपके संगठन की कुछ सुरक्षा नीतियों का पालन नहीं करता. किन समस्याओं को ठीक करना है, इसके बारे में अपने एडमिन से संपर्क करें.}=1{यह फ़ाइल या आपका डिवाइस, आपके संगठन की सुरक्षा नीतियों का पालन नहीं करता. किन समस्याओं को ठीक करना है, इसके बारे में अपने एडमिन से संपर्क करें.}one{यह फ़ाइल आपके संगठन की सुरक्षा नीतियों का पालन नहीं करती. किन समस्याओं को ठीक करना है, इसके बारे में अपने एडमिन से संपर्क करें.}other{ये फ़ाइलें आपके संगठन की सुरक्षा नीतियों का पालन नहीं करतीं. किन समस्याओं को ठीक करना है, इसके बारे में अपने एडमिन से संपर्क करें.}}</translation>
 <translation id="5738093759615225354">आपको अपने कंप्यूटर में साइन इन करने के लिए, इस पासवर्ड की ज़रूरत है</translation>
 <translation id="5739017626473506901">साइन इन करके, स्कूल वाला खाता जोड़ने में <ph name="USER_NAME" /> की मदद करें</translation>
@@ -8227,6 +8233,7 @@
 <translation id="7114054701490058191">पासवर्ड मेल नहीं खाते</translation>
 <translation id="7114648273807173152">Smart Lock का इस्तेमाल करके अपने Google खाते में साइन इन करने के लिए, सेटिंग &gt; कनेक्ट किए हुए डिवाइस &gt; आपका फ़ोन &gt; Smart Lock पर जाएं.</translation>
 <translation id="7115361495406486998">Google खाते वाला कोई भी संपर्क नहीं है</translation>
+<translation id="7115731767122970828">अभी बूस्ट करें</translation>
 <translation id="7116554090938189816">प्रिंटर के एसएसएल सर्टिफ़िकेट की समयसीमा खत्म हो गई है. प्रिंटर को रीस्टार्ट करें और फिर से कोशिश करें.</translation>
 <translation id="7117228822971127758">कृपया बाद में फिर से कोशिश करें</translation>
 <translation id="7118268675952955085">स्क्रीनशॉट</translation>
@@ -8382,6 +8389,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (श्रेष्ठ)</translation>
 <translation id="7246230585855757313">अपनी सुरक्षा कुंजी फिर से लगाएं और दोबारा कोशिश करें</translation>
 <translation id="724835896049478274">Android ऐप्लिकेशन के साथ इस्तेमाल करने के लिए उपलब्ध खाते</translation>
+<translation id="7248802599439396696">टैब बंद करें</translation>
 <translation id="7249197363678284330">इस सेटिंग को पता बार में जाकर बदलें.</translation>
 <translation id="7249764475759804559">फ़ाइलें खोलते समय, इस ऐप्लिकेशन को भी विकल्प के तौर पर दिखाएं</translation>
 <translation id="7250616558727237648">आप जिस डिवाइस के साथ फ़ाइल को शेयर करना चाहते हैं उसने कोई रिस्पॉन्स नहीं दिया. कृपया फिर से कोशिश करें.</translation>
@@ -9975,6 +9983,7 @@
 <translation id="8390392581097975659">स्कैनर सॉफ़्टवेयर इंस्टॉल किया जा रहा है</translation>
 <translation id="8390449457866780408">सर्वर अनुपलब्‍ध है.</translation>
 <translation id="8391218455464584335">विनाइल</translation>
+<translation id="8391918125842702622">परफ़ॉर्मेंस से जुड़ी समस्या की सूचना</translation>
 <translation id="8392726714909453725">'चुनें और सुनें' सेटिंग</translation>
 <translation id="8393511274964623038">प्लग-इन रोकें</translation>
 <translation id="839363317075970734">ब्लूटूथ डिवाइस की जानकारी</translation>
@@ -10075,6 +10084,7 @@
 <translation id="8466052016039127321">पिछले सेशन को फिर से शुरू नहीं किया जा सकता</translation>
 <translation id="8467326454809944210">कोई दूसरी भाषा चुनें</translation>
 <translation id="8468087214092422866">ब्लूटूथ डिवाइसों को खोजने की अनुमति नहीं है</translation>
+<translation id="8469863130477774813">परफ़ॉर्मेंस में सुधार करने के विकल्प उपलब्ध हैं</translation>
 <translation id="8470513973197838199"><ph name="ORIGIN" /> के लिए सेव किए गए पासवर्ड</translation>
 <translation id="8471525937465764768">आम तौर पर, साइटें, दस्तावेज़ को प्रिंट करने या स्टोरेज डिवाइस में चीज़ें सेव करने जैसी सुविधाओं के लिए, यूएसबी डिवाइस से कनेक्ट करती हैं</translation>
 <translation id="8471959340398751476">छूट की जानकारी पाने की सुविधा बंद है. आप 'पसंद के मुताबिक बनाएं' मेन्यू में जाकर, इस सुविधा को चालू कर सकते हैं</translation>
diff --git a/chrome/app/resources/generated_resources_hr.xtb b/chrome/app/resources/generated_resources_hr.xtb
index 25662db..6011225 100644
--- a/chrome/app/resources/generated_resources_hr.xtb
+++ b/chrome/app/resources/generated_resources_hr.xtb
@@ -67,6 +67,7 @@
 <translation id="1043505821207197890">Nešto nije u redu. Linux je možda samo djelomično nadograđen. Pregledajte zapisnike za više informacija. Zapisnici su spremljeni u mapu Datoteke &gt; Moje datoteke &gt; <ph name="LOG_FILE" /></translation>
 <translation id="104419033123549300">Stil karte tipkovnice</translation>
 <translation id="1046521327593783388">{NUM_PASSWORDS,plural, =1{Jedna zaporka uvezena je na uslugu <ph name="BRAND" /> na ovom uređaju}one{{NUM_PASSWORDS} zaporka uvezena je na uslugu <ph name="BRAND" /> na ovom uređaju}few{{NUM_PASSWORDS} zaporke uvezene su na uslugu <ph name="BRAND" /> na ovom uređaju}other{{NUM_PASSWORDS} zaporki uvezeno je na uslugu <ph name="BRAND" /> na ovom uređaju}}</translation>
+<translation id="1046572983040892965">Prozor je premješten prema gore i ulijevo</translation>
 <translation id="104710386808485638">Ponovno pokrenuti Linux?</translation>
 <translation id="1047431265488717055">Kopiraj te&amp;kst veze</translation>
 <translation id="1048286738600630630">Zasloni</translation>
@@ -187,6 +188,7 @@
 <translation id="1130589222747246278"><ph name="WINDOW_TITLE" /> – dio grupe <ph name="GROUP_NAME" /></translation>
 <translation id="1130676589211693127">Razina baterije desne slušalice: <ph name="PERCENTAGE" />%.</translation>
 <translation id="1133418583142946603">Dodaj trenutačnu karticu</translation>
+<translation id="1134363466745332968">Povijest pregledavanja možete pretraživati na temelju općeg sadržaja stranice, a ne samo naslova i URL-a stranice. Time ćete dobiti poboljšane rezultate, bez obzira na to pretražujete li povijest pregledavanja u adresnoj traci pomoću oznake @history ili putem stranice Povijest.</translation>
 <translation id="1136179794690960030"><ph name="EMOJI_NAME" />. <ph name="EMOJI_INDEX" /> od <ph name="EMOJI_COUNT" />.</translation>
 <translation id="1136712381129578788">Sigurnosni je ključ zaključan jer je previše puta unesen pogrešan PIN. Da biste ga otključali, uklonite ga i ponovo ga umetnite.</translation>
 <translation id="1137589305610962734">privremeni podaci</translation>
@@ -218,6 +220,7 @@
 <translation id="1158080958325422608">Promijeni u velika slova</translation>
 <translation id="1158238185437008462">Gledajte uspomene</translation>
 <translation id="1159879754517035595">Upravljanje postavkama proširenja</translation>
+<translation id="1160800016654917722">Prozor je premješten prema dolje i ulijevo</translation>
 <translation id="1161575384898972166">Prijavite se u uređaj <ph name="TOKEN_NAME" /> kako biste izvezli potvrdu klijenta.</translation>
 <translation id="116173250649946226">Vaš je administrator postavio zadanu temu koja se ne može promijeniti.</translation>
 <translation id="1162213688509394031">Sakrijte traku naslova</translation>
@@ -326,6 +329,7 @@
 <translation id="1227993798763400520">Emitiranje nije uspjelo. Pokušajte ponovo.</translation>
 <translation id="1230417814058465809">Uključena je standardna zaštita. Za veću sigurnost koristite poboljšanu zaštitu.</translation>
 <translation id="1231426483209637778">Zapamtit ćemo vašu mrežu sljedeći put kad budete upotrebljavali <ph name="DEVICE_TYPE" /></translation>
+<translation id="1231572247662419826">Web-lokacije mogu tražiti dopuštenje za bilježenje i upotrebu unosa mišem</translation>
 <translation id="1232569758102978740">Neimenovano</translation>
 <translation id="1233497634904001272">Ponovo dodirnite svoj sigurnosni ključ da biste dovršili zahtjev.</translation>
 <translation id="1233721473400465416">Oznaka zemlje/jezika</translation>
@@ -546,6 +550,7 @@
 <translation id="1407069428457324124">Tamna tema</translation>
 <translation id="1407135791313364759">Otvori sve</translation>
 <translation id="140723521119632973">Mobilna aktivacija</translation>
+<translation id="1407970155431887387">Kliknite da biste otvorili dijaloški okvir za uređivanje za tražilicu <ph name="SEARCH_ENGINE_NAME" /></translation>
 <translation id="1408504635543854729">Istražite sadržaj ovog uređaja u aplikaciji Datoteke. Administrator nameće ograničenja za sadržaj, pa se sadržaj ne može mijenjati.</translation>
 <translation id="1408980562518920698">Upravljanje osobnim podacima</translation>
 <translation id="1410197035576869800">Ikona aplikacije</translation>
@@ -1109,6 +1114,7 @@
 <translation id="1803531841600994172">Jezik na koji se prevodi</translation>
 <translation id="1803545009660609783">Ponovo uvježbaj</translation>
 <translation id="1804195280859010019">U značajkama kao što je bočna ploča Google pretraživanja prikazivat će se korisnije informacije ili prijedlozi</translation>
+<translation id="180441032496361123">Kliknite da biste aktivirali tražilicu <ph name="SEARCH_ENGINE_NAME" /></translation>
 <translation id="1805738995123446102">Pozadinska kartica upotrebljava mikrofon</translation>
 <translation id="1805822111539868586">Provjerite prikaze</translation>
 <translation id="1805888043020974594">Poslužitelj za ispis</translation>
@@ -1182,6 +1188,7 @@
 <translation id="1848219224579402567">Odjavi se kada se zatvori poklopac</translation>
 <translation id="184862733444771842">Zahtjev za značajku</translation>
 <translation id="1849016657376805933">Bilo koji HID uređaj</translation>
+<translation id="1849022541429818637">Dopušteno je bilježiti i upotrebljavati unose mišem</translation>
 <translation id="1850145825777333687">Vjerodajnice uređaja</translation>
 <translation id="1850508293116537636">Zakreni u &amp;smjeru kretanja kazaljke na satu</translation>
 <translation id="185111092974636561"><ph name="BEGIN_PARAGRAPH1" />Prije prijave trebate izbrisati TPM kako bi <ph name="DEVICE_OS" /> mogao preuzeti uređaj.<ph name="END_PARAGRAPH1" />
@@ -1728,6 +1735,7 @@
 <translation id="2251809247798634662">Novi anoniman prozor</translation>
 <translation id="2252017960592955005">Zaštita prilikom pregleda (beta)</translation>
 <translation id="2253318212986772520">Nije moguće dohvatiti PPD za <ph name="PRINTER_NAME" />.</translation>
+<translation id="2253797136365098595">Saznajte više o pretraživanjima povijesti</translation>
 <translation id="2253927598983295051">Odaberite što će se dijeliti s aplikacijom <ph name="APP_NAME" /></translation>
 <translation id="2255077166240162850">Uređaj je zaključan za neku drugu domenu ili način rada.</translation>
 <translation id="2255317897038918278">Microsoftovo vremensko označavanje</translation>
@@ -2123,6 +2131,7 @@
 <translation id="2515586267016047495">Alt</translation>
 <translation id="251722524540674480">Potvrdite svoje korisničko ime</translation>
 <translation id="2517472476991765520">Traži</translation>
+<translation id="2517851527960406492">Web-lokacije mogu tražiti dopuštenje za bilježenje i upotrebu unosa pomoću tipkovnice</translation>
 <translation id="2518024842978892609">Upotreba vaših korisničkih certifikata</translation>
 <translation id="2518620532958109495">Dopušten je automatski prikaz na cijelom zaslonu</translation>
 <translation id="2519250377986324805">Pokaži kako</translation>
@@ -2301,6 +2310,7 @@
 <translation id="265748523151262387">Ostanite povezani s telefonom</translation>
 <translation id="2657612187216250073">Postavke pristupačnosti pokazivača</translation>
 <translation id="2658941648214598230">Prikazati izvorni sadržaj?</translation>
+<translation id="2659694935349347275">Prozor je premješten prema dolje i udesno</translation>
 <translation id="2659971421398561408">Promjena veličine diska za Crostini</translation>
 <translation id="2660115748527982021">Savjet: mnoge Android aplikacije dostupne su na webu. Dostupnost provjerite u aplikaciji ili na web-lokaciji razvojnog programera.</translation>
 <translation id="2660779039299703961">Događaj</translation>
@@ -2346,6 +2356,7 @@
 <translation id="2690024944919328218">Prikaži opcije jezika</translation>
 <translation id="2691385045260836588">Model</translation>
 <translation id="2691440343905273290">Promjena postavki unosa</translation>
+<translation id="2691811116976138467">Web-lokacije upotrebljavaju tu značajku kako bi bilježile i upotrebljavale unose izvršene pomoću vaše tipkovnice, primjerice za igre ili aplikacije udaljene radne površine</translation>
 <translation id="2692503699962701720">Promijeni visinu glasa prilikom izgovaranja vrsta elemenata i formatiranog teksta.</translation>
 <translation id="2692901429679246677">Akvamarin</translation>
 <translation id="2693134906590795721">Zvukovi punjenja</translation>
@@ -3114,6 +3125,7 @@
 <translation id="3261090393424563833">Povećaj brzinu</translation>
 <translation id="3261268979727295785">Za stariju djecu možete dodati roditeljski nadzor kad dovršite postavljanje. Informacije o roditeljskom nadzoru možete pronaći u aplikaciji Istražite.</translation>
 <translation id="3261832505033014216">Pristupni ključ za <ph name="USER_EMAIL" /></translation>
+<translation id="3262261769033093854">Ne dopuštaj web-lokacijama bilježenje i upotrebu unosa mišem</translation>
 <translation id="3262336253311870293">Budući da ovim računom upravlja <ph name="DOMAIN" />, nećete se odjaviti s Google računa. Vaše se oznake, povijest, zaporke i ostale postavke više neće sinkronizirati. Međutim, vaši prethodno sinkronizirani podaci ostat će pohranjeni na vašem Google računu i možete upravljati njima na <ph name="BEGIN_LINK" />Google nadzornoj ploči<ph name="END_LINK" />.</translation>
 <translation id="3262986719682892278">Datoteka prevelika</translation>
 <translation id="3264544094376351444">Font Sans-serif</translation>
@@ -3427,6 +3439,7 @@
 <translation id="3497501929010263034">USB uređaj davatelja usluge <ph name="VENDOR_NAME" /> (proizvod <ph name="PRODUCT_ID" />)</translation>
 <translation id="3497560059572256875">Dijeljenje doodle logotipa</translation>
 <translation id="3497915391670770295">Pošalji na svoje uređaje</translation>
+<translation id="3499091376302796297">Dok pregledavate web-lokacije, sadržaj njihovih stranica sprema se u šifriranom obliku na vašem uređaju.</translation>
 <translation id="3500417806337761827">Pogreška prilikom učitavanja dijeljenja. Već je učitano previše SMB dijeljenja.</translation>
 <translation id="3500764001796099683">Omogući izolirane web-aplikacije</translation>
 <translation id="350397915809787283">Ako nemate račun, odaberite prvu opciju da biste ga izradili.</translation>
@@ -4234,6 +4247,7 @@
 <translation id="4062561150282203854">Sinkronizirajte aplikacije, postavke i druge podatke s uređaja <ph name="DEVICE_TYPE" /></translation>
 <translation id="4065876735068446555">Mreža koju upotrebljavate (<ph name="NETWORK_ID" />) može zahtijevati posjet stranici za prijavu.</translation>
 <translation id="4066207411788646768">Provjerite svoju vezu da biste vidjeli dostupne pisače u mreži</translation>
+<translation id="4066458014195202324">Dopušteno je bilježiti i upotrebljavati unose pomoću tipkovnice</translation>
 <translation id="4067839975993712852">Označi trenutačnu karticu kao pročitano</translation>
 <translation id="4068776064906523561">Spremljeni otisci prstiju</translation>
 <translation id="4070132839822635162">Ne prijavljuj se</translation>
@@ -4373,6 +4387,7 @@
 <translation id="4184803915913850597">HID uređaj (<ph name="VENDOR_ID" />:<ph name="PRODUCT_ID" />)</translation>
 <translation id="4186749321808907788"><ph name="QUERY_NAME" /> - <ph name="DEFAULT_SEARCH_ENGINE_NAME" /> Pretraživanje</translation>
 <translation id="4187424053537113647">Postavljanje aplikacije <ph name="APP_NAME" />...</translation>
+<translation id="4190446002599583608">Pretraživanje povijesti pomoću AI-ja</translation>
 <translation id="4190492351494485814">Za početno postavljanje morate se povezati s internetom kako bi se datoteke mogle sinkronizirati s Chromebookom</translation>
 <translation id="4190828427319282529">Fokus na tipkovnici za isticanje</translation>
 <translation id="4191892134568599822">Želite li primati putem značajke <ph name="FEATURE_NAME" />?</translation>
@@ -4868,6 +4883,7 @@
 <translation id="4562155214028662640">Dodajte otisak prsta</translation>
 <translation id="4562155266774382038">Odbaci prijedlog</translation>
 <translation id="4562364000855074606">Blokiraj aplikacije instalirane na uređaju <ph name="DEVICE_TYPE" />. Da biste ograničili preuzimanje aplikacija ili sadržaja, otvorite postavke Google Playa. <ph name="BEGIN_LINK_LEARN_MORE" />Saznajte više<ph name="END_LINK_LEARN_MORE" /></translation>
+<translation id="4562925006886238518">Koristite svakodnevni jezik da biste pretraživali svoju povijest pregledavanja i pronašli web-lokacije koje ste posjetili.</translation>
 <translation id="4563210852471260509">Početni jezik unosa je kineski</translation>
 <translation id="4563382028841851106">Ukloni s računa</translation>
 <translation id="4563880231729913339">Treći prst</translation>
@@ -4919,6 +4935,7 @@
 <translation id="4598549027014564149">Dok ste u anonimnom načinu, web-lokacije ne mogu upotrebljavati vaše kolačiće za uvid u vašu aktivnost pregledavanja na web-lokacijama, čak ni na povezanim web-lokacijama. Vaša aktivnost pregledavanja ne koristi se za stvari kao što je personaliziranje oglasa. Značajke na nekim web-lokacijama možda neće funkcionirati.</translation>
 <translation id="4598556348158889687">Upravljanje pohranom</translation>
 <translation id="4598776695426288251">Wi-Fi je dostupan putem više uređaja</translation>
+<translation id="4599323532350839656">Nije dopušteno bilježiti i upotrebljavati unose pomoću tipkovnice</translation>
 <translation id="4600071396330666617">Broj prijedloga</translation>
 <translation id="4601095002996233687">Dubinska pretraživanja mogućih sumnjivih preuzimanja.</translation>
 <translation id="4601426376352205922">Označi kao nepročitano</translation>
@@ -5232,6 +5249,7 @@
 <translation id="484462545196658690">Automatski</translation>
 <translation id="4846628405149428620">Odaberite gdje ova web-lokacija može spremati promjene</translation>
 <translation id="4846680374085650406">Vi pratite preporuku administratora za ovu postavku.</translation>
+<translation id="4846897209694249040">Nije dopušteno bilježiti i upotrebljavati unose mišem</translation>
 <translation id="4847242508757499006">Odaberite "Pokušajte ponovo" ili odaberite "Otvori u osnovnom uređivaču" da biste koristili ograničene opcije pregleda i uređivanja.</translation>
 <translation id="4847742514726489375">Smanjeno kretanje</translation>
 <translation id="4848191975108266266">"Ok Google" za Google asistenta</translation>
@@ -5352,6 +5370,7 @@
 <translation id="4927753642311223124">Nema nikakvih obavijesti.</translation>
 <translation id="4928629450964837566">Upotrijebite sigurniju zaporku</translation>
 <translation id="4929386379796360314">Odredišta ispisa</translation>
+<translation id="4930406318748549391">Položaj bočne ploče</translation>
 <translation id="4930447554870711875">Razvojni programeri</translation>
 <translation id="4930714375720679147">Uključi</translation>
 <translation id="4931347390544064118">Sigurne veze možda neće uvijek biti dostupne kad upotrebljavate zadanu postavku mreže. Savjetujemo vam da odaberete nekog drugog davatelja usluga kako biste uvijek upotrebljavali sigurnu vezu.</translation>
@@ -5700,6 +5719,7 @@
 <translation id="5195074424945754995">URL-ovi koji se podudaraju s tim pravilima neće pokretati promjenu preglednika i mogu se otvarati u pregledniku <ph name="BROWSER_NAME" /> ili u pregledniku <ph name="ALTERNATIVE_BROWSER_NAME" />.</translation>
 <translation id="5195863934285556588"><ph name="BEGIN_PARAGRAPH1" />Za procjenu lokacije ovog uređaja Googleova usluga lokacije upotrebljava izvore kao što su Wi-Fi, mobilne mreže i senzori.<ph name="END_PARAGRAPH1" />
     <ph name="BEGIN_PARAGRAPH2" />Lokaciju Androida na ovom uređaju možete isključiti kad god želite u odjeljku Postavke &gt; Aplikacije &gt; Trgovina Google Play &gt; Upravljanje postavkama Androida &gt; Sigurnost i lokacija &gt; Lokacija. Možete isključiti i upotrebu Wi-Fija, mobilnih mreža i senzora za lokaciju Androida tako što ćete na istom izborniku isključiti opciju Googleovo točno lociranje.<ph name="END_PARAGRAPH2" /></translation>
+<translation id="5197150086680615104">Prijedloge grupa kartica uvijek možete provjeriti</translation>
 <translation id="5197255632782567636">Internet</translation>
 <translation id="5198430103906431024">Slanje podataka o upotrebi i dijagnostici. Ovaj uređaj trenutačno Googleu automatski šalje dijagnostičke podatke te podatke o upotrebi uređaja i aplikacija. Ti podaci pomoći će poboljšati stabilnost sustava, aplikacija i drugo. Neki skupni podaci pomoći će i Googleovim aplikacijama i partnerima, na primjer razvojnim programerima za Android. Ako je uključena dodatna aktivnost na webu i u aplikacijama, ti se podaci mogu spremati na vaš Google račun.</translation>
 <translation id="5199729219167945352">Eksperimenti</translation>
@@ -7212,6 +7232,7 @@
 <translation id="6341850831632289108">otkriti vašu fizičku lokaciju</translation>
 <translation id="6342069812937806050">Upravo sada</translation>
 <translation id="6343003829431264373">Samo parne stranice</translation>
+<translation id="6343981313228733146">Prozor je premješten prema gore i udesno</translation>
 <translation id="6344170822609224263">pristupiti popisu mrežnih veza</translation>
 <translation id="6344576354370880196">Spremljeni pisači</translation>
 <translation id="6344608411615208519"><ph name="BEGIN_LINK" />Preglednikom upravlja<ph name="END_LINK" /> tvoj roditelj</translation>
@@ -7796,6 +7817,7 @@
 <translation id="6798780071646309401">Caps Lock uključen</translation>
 <translation id="6798954102094737107">Dodatak: <ph name="PLUGIN_NAME" /></translation>
 <translation id="679905836499387150">Skriveni gumbi alatne trake</translation>
+<translation id="6800623240347398745">Nema grupe za tu karticu, ali pogledajte ove grupe</translation>
 <translation id="6800893479155997609">Najbolje aplikacije za vaš uređaj <ph name="DEVICE_TYPE" /></translation>
 <translation id="6801308659697002152">{NUM_EXTENSIONS,plural, =1{Odaberite može li ovo proširenje čitati ili mijenjati navedenu web-lokaciju}one{Odaberite mogu li ova proširenja čitati ili mijenjati navedenu web-lokaciju}few{Odaberite mogu li ova proširenja čitati ili mijenjati navedenu web-lokaciju}other{Odaberite mogu li ova proširenja čitati ili mijenjati navedenu web-lokaciju}}</translation>
 <translation id="6801435275744557998">Kalibrirajte dodirni zaslon</translation>
@@ -7837,6 +7859,7 @@
 <translation id="6818920801736417483">Spremiti zaporke?</translation>
 <translation id="6820079682647046800">Kerberos autentifikacija nije uspjela</translation>
 <translation id="6821439254917412979">Otkvači proširenje <ph name="EXTENSION_NAME" /></translation>
+<translation id="6823097506504975234">Kada pretražujete povijest pregledavanja, vaši pojmovi za pretraživanje povijesti, sadržaj stranica s najboljim podudaranjima i generirani rezultati obrade šalju se Googleu i pregledavatelji ih mogu vidjeti kako bi poboljšali tu značajku.</translation>
 <translation id="6823174134746916417">Dodir za klik na dodirnoj podlozi</translation>
 <translation id="6823561724060793716">U adresnoj traci možete otvoriti informacije o stranici da biste vidjeli dodatne informacije o stranici koju posjećujete</translation>
 <translation id="6824564591481349393">Kopiraj &amp;adresu e-pošte</translation>
@@ -8868,6 +8891,7 @@
 <translation id="761530003705945209">Sigurnosno kopiranje na Google disku. Jednostavno vratite svoje podatke ili promijenite uređaj u bilo kojem trenutku. Sigurnosna kopija uključuje podatke aplikacija. Sigurnosna kopija prenosi se na Google i kriptira pomoću zaporke vašeg Google računa.</translation>
 <translation id="7615365294369022248">Došlo je do pogreške prilikom dodavanja računa</translation>
 <translation id="7616214729753637086">Registriranje uređaja...</translation>
+<translation id="7616964248951412133">Web-lokacije upotrebljavaju tu značajku kako bi bilježile i upotrebljavale unose izvršene pomoću vašeg miša, primjerice za igre ili aplikacije udaljene radne površine</translation>
 <translation id="7617263010641145920">Uključivanje Trgovine Play</translation>
 <translation id="7617648809369507487">Koristi tiše slanje poruka</translation>
 <translation id="7619937211696316184">Održavanje je dovršeno</translation>
@@ -9371,6 +9395,7 @@
 <translation id="7959665254555683862">Nova anonimna &amp;kartica</translation>
 <translation id="7961015016161918242">Nikad</translation>
 <translation id="7963001036288347286">Ubrzanje dodirne podloge</translation>
+<translation id="7963513503134856713">Prozor je premješten udesno</translation>
 <translation id="7963608432878156675">Ovaj je naziv vidljiv drugim uređajima za povezivanje s Bluetoothom i mrežnom vezom</translation>
 <translation id="7963826112438303517">Te snimke i zahtjeve koje izgovorite Asistent upotrebljava za izradu i ažuriranje vašeg glasovnog modela koji se sprema samo na uređajima na kojima ste uključili Voice Match. Glasovnu aktivnost možete pregledati ili ponovo uvježbati u postavkama Asistenta.</translation>
 <translation id="7964458523224581615">Plavo-zelena</translation>
@@ -10024,6 +10049,7 @@
 <translation id="8428271547607112339">Dodavanje školskog računa</translation>
 <translation id="8428634594422941299">Shvaćam</translation>
 <translation id="84297032718407999">Odjavit ćete se za <ph name="LOGOUT_TIME_LEFT" /></translation>
+<translation id="8429928917752180743">Više opcija za proširenje <ph name="EXTENSION_NAME" /></translation>
 <translation id="8431190899827883166">Prikaži dodire</translation>
 <translation id="843173223122814223">Izrada pozadina pomoću AI-ja</translation>
 <translation id="8433186206711564395">Postavke mreže</translation>
@@ -10114,6 +10140,7 @@
 <translation id="8498214519255567734">Olakšaj gledanje zaslona ili čitanje pri slabom svjetlu</translation>
 <translation id="8499083585497694743">Uključi mikrofon</translation>
 <translation id="8500044868721690197">Toj je web-lokaciji blokirano kontroliranje i reprogramiranje MIDI uređaja</translation>
+<translation id="8500123638242682652">Prozor je premješten prema gore</translation>
 <translation id="8502536196501630039">Da biste upotrebljavali aplikacije s Google Playa, prvo morate vratiti aplikacije. Neki su podaci možda izgubljeni.</translation>
 <translation id="8503813439785031346">Korisničko ime</translation>
 <translation id="850382998924680137">Pogledano danas</translation>
@@ -10213,6 +10240,7 @@
 <translation id="8577052309681449949">Automatski klikovi, veličina pokazivača, boja pokazivača i više</translation>
 <translation id="8578639784464423491">Dopušteno je najviše 99 slova</translation>
 <translation id="8581809080475256101">Pritisnite da biste išli unaprijed, kontekstni izbornik za prikaz povijesti</translation>
+<translation id="8583122761178401199">Ne dopuštaj web-lokacijama bilježenje i upotrebu unosa pomoću tipkovnice</translation>
 <translation id="8584280235376696778">&amp;Otvori video na novoj kartici</translation>
 <translation id="858451212965845553">Pošalji na svoje uređaje</translation>
 <translation id="8584843865238667486">HID uređaji s upotrebom <ph name="USAGE" /> od stranice upotrebe <ph name="USAGE_PAGE" /></translation>
@@ -10228,6 +10256,7 @@
 <translation id="859246725979739260">Ovoj web-lokaciji blokiran je pristup vašoj lokaciji.</translation>
 <translation id="8593450223647418235">Nećete moći otvarati datoteke u sustavu Microsoft 365 dok se postavljanje ne dovrši.</translation>
 <translation id="8593686980889923154">Aplikacija <ph name="APP_NAME" /> blokirana je na vašem uređaju <ph name="DEVICE_TYPE" /></translation>
+<translation id="8596400097994526901">Više radnji za <ph name="SEARCH_ENGINE_NAME" /></translation>
 <translation id="8596540852772265699">Prilagođene datoteke</translation>
 <translation id="8597845839771543242">Oblik svojstva:</translation>
 <translation id="8598249292448297523">ispis</translation>
@@ -10313,6 +10342,7 @@
 <translation id="8657393004602556571">Želite li odbaciti povratne informacije?</translation>
 <translation id="8657542881463614516">Koristite pokret prelaska prstom da biste prelazili s jedne stranice na drugu</translation>
 <translation id="8659608856364348875">Kontakti značajke <ph name="FEATURE_NAME" /></translation>
+<translation id="8659609431223166673">Prozor je premješten prema dolje</translation>
 <translation id="8661290697478713397">Otvori vezu u anoni&amp;mnom prozoru</translation>
 <translation id="8662474268934425487">Prijavite se na <ph name="SITE_ETLD_PLUS_ONE" /></translation>
 <translation id="8662671328352114214">Pridruži se mreži <ph name="TYPE" /></translation>
@@ -10359,6 +10389,7 @@
 <translation id="8682730193597992579"><ph name="PRINTER_NAME" /> je povezan i spreman</translation>
 <translation id="8684471948980641888">Dopusti sinkronizaciju na mrežama s ograničenim prometom</translation>
 <translation id="8685540043423825702">Vaš profil u Chromeu</translation>
+<translation id="8685882652128627032">Kliknite da biste otvorili dijaloški okvir za dodavanje pretraživanja web-lokacija</translation>
 <translation id="8686142379631285985">Prijavljeni ste kao <ph name="BEGIN_BOLD" /><ph name="DRIVE_ACCOUNT_EMAIL" /><ph name="END_BOLD" /></translation>
 <translation id="8687103160920393343">Poništavanje <ph name="FILE_NAME" /></translation>
 <translation id="8687527282898211955">Postavljanje PIN-a</translation>
@@ -10549,6 +10580,7 @@
 <translation id="881799181680267069">Sakrij ostale</translation>
 <translation id="8818152010000655963">Pozadina</translation>
 <translation id="8818958672113348984">Potvrda putem telefona</translation>
+<translation id="8818988764764862764">Prozor je premješten ulijevo</translation>
 <translation id="8819510664278523111">EID vašeg uređaja je <ph name="EID_NUMBER" />, IMEI je <ph name="IMEI_NUMBER" />, a serijski broj uređaja je <ph name="SERIAL_NUMBER" />. Pomoću tih brojeva možete aktivirati uslugu.</translation>
 <translation id="8820817407110198400">Oznake</translation>
 <translation id="8821045908425223359">Konfiguriraj IP adresu automatski</translation>
@@ -10627,6 +10659,7 @@
 <translation id="8872506776304248286">Otvori u aplikaciji</translation>
 <translation id="8872774989979382243">Zvuk je isključen. Uključite zvuk.</translation>
 <translation id="887292602123626481">Saznajte više o zadanim tražilicama</translation>
+<translation id="8873075098103007382">Ostanite organizirani pomoću grupa kartica</translation>
 <translation id="8874341931345877644">Emitirajte na uređaju:</translation>
 <translation id="8874790741333031443">Pokušajte privremeno dopustiti kolačiće trećih strana, što znači da će biti manje zaštite pregledavanja, ali će značajke web-lokacije vjerojatnije funkcionirati prema očekivanjima.</translation>
 <translation id="8875520811099717934">Nadogradnja Linuxa</translation>
@@ -10759,6 +10792,7 @@
 <translation id="8973557916016709913">Ukloni razinu zuma</translation>
 <translation id="8973596347849323817">Ovaj uređaj možete prilagoditi svojim potrebama. Značajke pristupačnosti možete promijeniti kasnije u postavkama.</translation>
 <translation id="897414447285476047">Odredišna datoteka bila je nepotpuna zbog problema s vezom.</translation>
+<translation id="8974261761101622391">Pronađite alternativu za proširenje <ph name="EXTENSION_NAME" /></translation>
 <translation id="897525204902889653">Usluga karantene</translation>
 <translation id="8975396729541388937">Pretplatu uvijek možete otkazati klikom na vezu u primljenim e-porukama.</translation>
 <translation id="8975562453115131273">{NUM_OTHER_TABS,plural, =0{„<ph name="TAB_TITLE" />"}=1{„<ph name="TAB_TITLE" />" i još jedna kartica}one{„<ph name="TAB_TITLE" />" i još # kartica}few{„<ph name="TAB_TITLE" />" i još # kartice}other{„<ph name="TAB_TITLE" />" i još # kartica}}</translation>
diff --git a/chrome/app/resources/generated_resources_hy.xtb b/chrome/app/resources/generated_resources_hy.xtb
index 3f38ae76..1f1c815 100644
--- a/chrome/app/resources/generated_resources_hy.xtb
+++ b/chrome/app/resources/generated_resources_hy.xtb
@@ -411,6 +411,7 @@
 <translation id="1293556467332435079">Ֆայլեր</translation>
 <translation id="1294807885394205587">Սա կարող է մի քանի րոպե տևել։ Կոնտեյներների կառավարիչը գործարկվում է։</translation>
 <translation id="12951065153783848">Ձեր հաշիվը կառավարվում է կազմակերպության կողմից</translation>
+<translation id="1296410481664942178">Ցույց չտալ Google Օրացույցը</translation>
 <translation id="1296911687402551044">Ամրացնել այս ներդիրը</translation>
 <translation id="1297175357211070620">Նպատակակետ</translation>
 <translation id="129770436432446029">Կարծիք հայտնել «<ph name="EXPERIMENT_NAME" />» գործառույթի մասին</translation>
@@ -449,6 +450,7 @@
 <translation id="1327495825214193325">ADB վրիպազերծումը միացնելու համար վերագործարկեք <ph name="DEVICE_TYPE" /> սարքը։ Դրա համար անհրաժեշտ է վերականգնել սարքի գործարանային կարգավորումները։</translation>
 <translation id="1327527584824210101">Օգտագործեք ձեր մուտքի բանալին</translation>
 <translation id="1327794256477341646">Գործառույթները, որոնց համար պահանջվում է տեղորոշում, չեն աշխատի</translation>
+<translation id="1328364753167940710"><ph name="NUM_HR" /> ժամից</translation>
 <translation id="1329466763986822896">Բարձրացնել այս թեժ կետի գաղտնիության մակարդակը</translation>
 <translation id="1331977651797684645">Սա ես եմ։</translation>
 <translation id="1333489022424033687"><ph name="ORIGIN" /> կայքում որոշ գործառույթներ կարող են չաշխատել, մինչև չհեռացնեք ձեր սարքում այլ կայքերի պահած տվյալները։</translation>
@@ -997,6 +999,7 @@
 <translation id="1709762881904163296">Ցանցի կարգավորումներ</translation>
 <translation id="1709916727352927457">Մուտքի բանալու ջնջում</translation>
 <translation id="1709972045049031556">Սխալ առաջացավ</translation>
+<translation id="1712143791363119140">Ընթացքում է</translation>
 <translation id="1714644264617423774">Միացնել հատուկ գործառույթները՝ սարքն ավելի հեշտ օգտագործելու համար։ <ph name="LINK_BEGIN" />Իմանալ ավելին<ph name="LINK_END" /></translation>
 <translation id="1716034099915639464">Հեռացնե՞լ <ph name="SITE_NAME" /> կայքի և դրա համար տեղադրված հավելվածի կայքի տվյալներն ու թույլտվությունները</translation>
 <translation id="171826447717908393">Մեկուսացված վեբ հավելվածներ (բետա)</translation>
@@ -1400,6 +1403,7 @@
 <translation id="200928901437634269">Օգտագործեք ձեր երեխայի Google հաշիվը կամ ուսումնական հաշիվը: Կարող եք նաև սահմանել ծնողական վերահսկողություն։</translation>
 <translation id="2009590708342941694">«Էմոջիներ» գործիք</translation>
 <translation id="2010501376126504057">Համատեղելի սարքեր</translation>
+<translation id="2010636492623189611">Ընտրված է։</translation>
 <translation id="201217432804812273">Միացրեք «Պահել խումբը» պարամետրը</translation>
 <translation id="2012935757369720523">Ջնջել ֆայլը</translation>
 <translation id="2013550551806600826">Փորձեք։ Միացրեք կամ անջատեք կարգավորումը, այնուհետև երկու մատով ոլորեք ձեր հպահարթակի վրա փորձարկման համար հատկացված տարածքում։ Այս պարամետրը հետագայում նաև կարող եք գտնել՝ անցնելով Կարգավորումներ &gt; Սարք &gt; Մկնիկ և հպահարթակ։</translation>
@@ -1992,6 +1996,7 @@
 <translation id="2435248616906486374">Ցանցն անջատված է</translation>
 <translation id="2435457462613246316">Ցույց տալ գաղտնաբառը</translation>
 <translation id="2436385001956947090">Պատճենել &amp;հղումը</translation>
+<translation id="2437561292559037753">Տվյալների փոխանցում</translation>
 <translation id="2438853563451647815">Տպիչի հետ կապ չի հաստատվել</translation>
 <translation id="2439152382014731627">Փոխել <ph name="DEVICE_TYPE" /> սարքի գաղտնաբառը</translation>
 <translation id="2439626940657133600"><ph name="WINDOW_TITLE" />-ի բեռնում</translation>
@@ -2566,6 +2571,7 @@
 <translation id="2843698124892775282">Ազատվել է <ph name="MEMORY_SAVINGS" /> տարածք</translation>
 <translation id="2844169650293029770">USB-C սարք (առջևի ձախակողմյան միացք)</translation>
 <translation id="2844809857160214557">Դիտեք և կառավարեք տպելու առաջադրանքները</translation>
+<translation id="2845276301195220700">Google Օրացույցի այլ գործողություններ</translation>
 <translation id="2845382757467349449">Always Show Bookmarks Bar</translation>
 <translation id="2845751331501453107">Գովազդի անհատականացումը կախված է այս կարգավորումից, <ph name="BEGIN_LINK1" />կայքերի կողմից առաջարկվող գովազդներից<ph name="LINK_END1" />, <ph name="BEGIN_LINK2" />քուքիների կարգավորումներից<ph name="LINK_END2" /> և այն կայքի կարգավորումներից, որը դուք դիտում եք</translation>
 <translation id="284581348330507117">Ստեղծեք չկրկնվող գաղտնաբառեր</translation>
@@ -3678,6 +3684,7 @@
 <translation id="3694590407685276748">Ընդգծել տեքստի նշորդը</translation>
 <translation id="369489984217678710">Գաղտնաբառեր և մուտքի այլ տվյալներ</translation>
 <translation id="369522892592566391">{NUM_FILES,plural, =0{Անվտանգության ստուգումներն ավարտվել են։ Ձեր տվյալները կվերբեռնվեն։}=1{Անվտանգության ստուգումներն ավարտվել են։ Ձեր ֆայլը կվերբեռնվի։}one{Անվտանգության ստուգումներն ավարտվել են։ Ձեր ֆայլերը կվերբեռնվեն։}other{Անվտանգության ստուգումներն ավարտվել են։ Ձեր ֆայլերը կվերբեռնվեն։}}</translation>
+<translation id="3695339288331169103">Աղբյուրը՝ <ph name="BEGIN_LINK" /><ph name="DISPLAY_REFERRER_URL" /><ph name="END_LINK" /></translation>
 <translation id="369736917241079046">գործարկիչ + ձախ սլաք</translation>
 <translation id="3697716475445175867">վերջին բացվածը</translation>
 <translation id="3697732362672163692">{NUM_SITES,plural, =1{Դուք կարող եք կանգնեցնել այս կայքից ուղարկվող ծանուցումները։}one{Դուք կարող եք կանգնեցնել այս կայքից ուղարկվող ծանուցումները։}other{Դուք կարող եք կանգնեցնել այս կայքերից ուղարկվող ծանուցումները։}}</translation>
@@ -4978,6 +4985,7 @@
 <translation id="4650591383426000695">Անջատեք ձեր հեռախոսը <ph name="DEVICE_TYPE" /> սարքից</translation>
 <translation id="4651484272688821107">Չհաջողվեց առցանց բաղադրիչը բեռնել դեմո ռեժիմի ռեսուրսներով։</translation>
 <translation id="4651921906638302153">Չհաջողվեց մտնել այս հաշիվ</translation>
+<translation id="4652921642122345344">Խոսքի արագությունը <ph name="RATE" />x</translation>
 <translation id="4652935475563630866">Վերագործարկեք Parallels Desktop-ը, որպեսզի տեսախցիկի կարգավորումը փոխվի, և դուք կարողանաք շարունակել աշխատանքը։</translation>
 <translation id="4653116291358041820">Փոքր շողք</translation>
 <translation id="4653405415038586100">Չհաջողվեց կարգավորել Լինուքսը</translation>
@@ -5176,6 +5184,7 @@
 <translation id="4809927044794281115">Բաց թեմա</translation>
 <translation id="4811212958317149293">Ստեղնաշարի ավտոմատ սկանավորում Switch Access-ի միջոցով</translation>
 <translation id="4811503964269049987">Ավելացնել ընտրված ներդիրը խմբում</translation>
+<translation id="4812073856515324252">Ընտրեք, թե որտեղ պահել <ph name="APP_NAME" /> հավելվածի մուտքի բանալին</translation>
 <translation id="4813512666221746211">Ցանցի սխալ</translation>
 <translation id="4814114628197290459">IBAN-ի ջնջում</translation>
 <translation id="4814327014588285482">Բաց թողնել և հիշեցնել ավելի ուշ</translation>
@@ -5644,6 +5653,7 @@
 <translation id="5160634252433617617">Ֆիզիկական ստեղնաշար</translation>
 <translation id="5160857336552977725">Մուտք գործեք ձեր <ph name="DEVICE_TYPE" /></translation>
 <translation id="5161251470972801814">USB սարքեր <ph name="VENDOR_NAME" />-ից</translation>
+<translation id="5161442190864186925">Միանալ հանդիպմանը</translation>
 <translation id="5161827038979306924">Ո՞րն է Chrome-ում այցելությունների պատմության և որոնումների պատմության տարբերությունը</translation>
 <translation id="5162905305237671850"><ph name="DEVICE_TYPE" />-ն արգելափակվել է</translation>
 <translation id="5163910114647549394">Ներդիրը տեղափոխվեց վահանակի վերջ</translation>
@@ -7947,6 +7957,7 @@
 <translation id="6912007319859991306">SIM քարտի PIN կոդ</translation>
 <translation id="6912380255120084882">Այլ սարք փորձեք</translation>
 <translation id="691289340230098384">Ենթագրերի կարգավորումներ</translation>
+<translation id="6913051485529944333">Դուք այլևս չեք տեսնի Google Օրացույցը այս էջում</translation>
 <translation id="6914812290245989348">Չտեսնել նախազգուշացումներ նախքան ոչ ապահով կայքեր մտնելը</translation>
 <translation id="6916590542764765824">Կառավարել ընդլայնումները</translation>
 <translation id="6918677045355889289">Թարմացրեք ChromeOS-ը</translation>
@@ -9148,6 +9159,7 @@
 <translation id="7810202088502699111">Ելնող պատուհաններն արգելափակված են այս էջում:</translation>
 <translation id="7810367892333449285">Մուտքագրումը պետք է լինի <ph name="LPA_0" />$<ph name="LPA_1" />SM-DP+ address<ph name="LPA_2" />$<ph name="LPA_3" />optional matching id<ph name="LPA_4" /> ձևաչափով</translation>
 <translation id="7811263553491007091">Նորից փորձեք կամ ընտրեք նախկինում ստեղծված հետևյալ թեմաներից որևէ մեկը։</translation>
+<translation id="7812170317334653156">Google Օրացույցը թաքցվեց</translation>
 <translation id="7814090115158024843">Երբեք չառաջարկել օգտագործել տեքստագրիչն այս կայքերում</translation>
 <translation id="7814458197256864873">&amp;Պատճենել</translation>
 <translation id="7814857791038398352">Microsoft OneDrive</translation>
@@ -9206,6 +9218,7 @@
 <translation id="7853747251428735">Լրացուցիչ գործիքներ</translation>
 <translation id="7853999103056713222">Օգտագործեք ավելի ապահով գաղտնաբառ</translation>
 <translation id="7855678561139483478">Բացել ներդիրը նոր պատուհանում</translation>
+<translation id="7856117067008941054">Թաքցնել Google Օրացույցը</translation>
 <translation id="7857004848504343806">Ձեր համակարգիչը պարունակում է անվտանգության մոդուլ, որն օգտագործվում է ChromeOS Flex-ում անվտանգության բազմաթիվ կարևոր գործառույթների համար։ Լրացուցիչ տեղեկությունների համար այցելեք Chromebook-ի օգնության կենտրոն՝ https://support.google.com/chromebook/?p=sm</translation>
 <translation id="7857093393627376423">Տեքստային հուշումներ</translation>
 <translation id="7858120906780498731">ChromeOS-ին միացված ներածման սարքեր</translation>
@@ -9214,6 +9227,7 @@
 <translation id="786073089922909430">Ծառայություն՝ <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;Ներբեռնումներ</translation>
 <translation id="7861846108263890455">Google հաշվի լեզուն</translation>
+<translation id="7864114920800968141"><ph name="NUM_MIN" /> րոպեից</translation>
 <translation id="7864539943188674973">Անջատել Bluetooth-ը</translation>
 <translation id="7864825798076155402">Պահե՞լ ձեր Google հաշվում</translation>
 <translation id="7865127013871431856">Թարգմանության կարգավորումներ</translation>
diff --git a/chrome/app/resources/generated_resources_id.xtb b/chrome/app/resources/generated_resources_id.xtb
index 004ed80..4055ca9 100644
--- a/chrome/app/resources/generated_resources_id.xtb
+++ b/chrome/app/resources/generated_resources_id.xtb
@@ -973,6 +973,7 @@
 <translation id="1697150536837697295">Seni</translation>
 <translation id="1697686431566694143">Edit file</translation>
 <translation id="1698796500103229697">&amp;Metode Pembayaran</translation>
+<translation id="1698899521169711967">Penjelajahan dengan keyboard</translation>
 <translation id="1699807488537653303">Perbaiki error sandi</translation>
 <translation id="1700201317341192482">Hapus kartu virtual Anda</translation>
 <translation id="1700517974991662022">Dikunjungi</translation>
@@ -2483,6 +2484,7 @@
 <translation id="2771816809568414714">Keju</translation>
 <translation id="2772936498786524345">Ninja</translation>
 <translation id="2773288106548584039">Dukungan Browser Lama</translation>
+<translation id="2773621783913034737">Nonaktifkan Tab</translation>
 <translation id="2773802008104670137">Jenis file ini dapat membahayakan komputer.</translation>
 <translation id="2775104091073479743">Edit Sidik Jari</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{Ekstensi "<ph name="EXTENSION" />" telah mengakses perangkat}=1{Ekstensi "<ph name="EXTENSION" />" sedang mengakses {0} perangkat}other{Ekstensi "<ph name="EXTENSION" />" sedang mengakses {0} perangkat}}</translation>
@@ -2563,6 +2565,7 @@
 <translation id="2830528677948328648">Kelola akun &amp;Google Anda</translation>
 <translation id="2831430281393059038">Perangkat didukung</translation>
 <translation id="2832124733806557606">Anak Anda dapat menggunakan PIN untuk login atau membuka kunci perangkat.</translation>
+<translation id="2833144527504272627">Navigasi dengan kursor teks</translation>
 <translation id="2835177225987815960">Penyiapan pemindaian saat ini akan direset, termasuk semua preferensi tombol akses yang ditetapkan dan kecepatan pemindaian otomatis.</translation>
 <translation id="2835547721736623118">Layanan pengenalan ucapan</translation>
 <translation id="2835761321523638096">Membaca dan mengubah entri dalam daftar bacaan</translation>
@@ -4119,6 +4122,7 @@
 <translation id="3978325380690188371">Tombol lekat tidak tersedia saat ChromeVox diaktifkan</translation>
 <translation id="3979395879372752341">Ekstensi baru ditambahkan (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326">Aktifkan <ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">Sembunyikan tab ini</translation>
 <translation id="3981058120448670012">Dapat dilihat oleh perangkat di sekitar sebagai <ph name="DEVICE_NAME" /> selama <ph name="REMAINING_TIME" />...</translation>
 <translation id="3981760180856053153">Jenis penyimpanan yang dimasukkan tidak valid.</translation>
 <translation id="3982375475032951137">Siapkan browser Anda dalam beberapa langkah mudah</translation>
@@ -6311,6 +6315,7 @@
 <translation id="5642508497713047">Penandatangan CRL</translation>
 <translation id="5643191124441701136">Kode keamanan ada di bagian depan kartu</translation>
 <translation id="5643321261065707929">Jaringan berbayar</translation>
+<translation id="5643717184207603910">Jaga performa agar tetap cepat</translation>
 <translation id="5646376287012673985">Lokasi</translation>
 <translation id="5646558797914161501">Pengusaha</translation>
 <translation id="5648021990716966815">Colokan mikrofon</translation>
@@ -6415,6 +6420,7 @@
 <translation id="5733109311583381874">Tambahkan kata-kata Anda sendiri ke kamus pengguna untuk menyesuaikan kandidat konversi.</translation>
 <translation id="5734362860645681824">Komunikasi</translation>
 <translation id="5734697361979786483">Tambahkan berbagi file</translation>
+<translation id="5735513236153491131">Tingkatkan Sekarang</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{Data ini atau perangkat Anda tidak memenuhi beberapa kebijakan keamanan organisasi Anda. Hubungi admin Anda untuk mengetahui hal yang perlu diperbaiki.}=1{File ini atau perangkat Anda tidak memenuhi beberapa kebijakan keamanan organisasi Anda. Hubungi admin Anda untuk mengetahui hal yang perlu diperbaiki.}other{File ini tidak memenuhi beberapa kebijakan keamanan organisasi Anda. Hubungi admin Anda untuk mengetahui hal yang perlu diperbaiki.}}</translation>
 <translation id="5738093759615225354">Anda memerlukan kunci sandi ini untuk login ke komputer Anda</translation>
 <translation id="5739017626473506901">Login untuk membantu <ph name="USER_NAME" /> menambahkan akun sekolah</translation>
@@ -8226,6 +8232,7 @@
 <translation id="7114054701490058191">Sandi tidak cocok</translation>
 <translation id="7114648273807173152">Agar dapat menggunakan Smart Lock untuk login ke akun Google Anda, buka Setelan &gt; Perangkat terhubung &gt; Ponsel Anda &gt; Smart Lock.</translation>
 <translation id="7115361495406486998">Tidak ada kontak yang dapat dihubungi</translation>
+<translation id="7115731767122970828">Tingkatkan sekarang</translation>
 <translation id="7116554090938189816">Masa berlaku sertifikat SSL printer telah berakhir. Mulai ulang printer, lalu coba lagi.</translation>
 <translation id="7117228822971127758">Coba lagi nanti</translation>
 <translation id="7118268675952955085">screenshot</translation>
@@ -8381,6 +8388,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Terbaik)</translation>
 <translation id="7246230585855757313">Masukkan kembali kunci keamanan, lalu coba lagi</translation>
 <translation id="724835896049478274">Akun yang tersedia untuk aplikasi Android</translation>
+<translation id="7248802599439396696">Nonaktifkan tab</translation>
 <translation id="7249197363678284330">Ubah setelan ini di kolom URL.</translation>
 <translation id="7249764475759804559">Sertakan aplikasi ini sebagai opsi saat membuka file</translation>
 <translation id="7250616558727237648">Perangkat yang diajak berbagi tidak merespons. Coba lagi.</translation>
@@ -9975,6 +9983,7 @@
 <translation id="8390392581097975659">Menginstal software pemindai</translation>
 <translation id="8390449457866780408">Server tidak tersedia.</translation>
 <translation id="8391218455464584335">Piringan hitam</translation>
+<translation id="8391918125842702622">Peringatan masalah performa</translation>
 <translation id="8392726714909453725">Setelan Klik untuk Diucapkan</translation>
 <translation id="8393511274964623038">Hentikan plugin</translation>
 <translation id="839363317075970734">Detail perangkat Bluetooth</translation>
@@ -10075,6 +10084,7 @@
 <translation id="8466052016039127321">Tidak dapat melanjutkan sesi sebelumnya</translation>
 <translation id="8467326454809944210">Pilih bahasa lain</translation>
 <translation id="8468087214092422866">Tidak diizinkan mencari perangkat Bluetooth</translation>
+<translation id="8469863130477774813">Peningkatan performa tersedia</translation>
 <translation id="8470513973197838199">Sandi yang tersimpan untuk <ph name="ORIGIN" /></translation>
 <translation id="8471525937465764768">Situs biasanya terhubung ke perangkat USB untuk fitur seperti pencetakan dokumen atau penyimpanan ke perangkat penyimpanan</translation>
 <translation id="8471959340398751476">Diskon nonaktif. Anda dapat mengaktifkannya di menu sesuaikan</translation>
diff --git a/chrome/app/resources/generated_resources_is.xtb b/chrome/app/resources/generated_resources_is.xtb
index 316954d7..573b076 100644
--- a/chrome/app/resources/generated_resources_is.xtb
+++ b/chrome/app/resources/generated_resources_is.xtb
@@ -974,6 +974,7 @@
 <translation id="1697150536837697295">List</translation>
 <translation id="1697686431566694143">Breyta skrá</translation>
 <translation id="1698796500103229697">Greiðslumátar</translation>
+<translation id="1698899521169711967">Skoðun með textabendli</translation>
 <translation id="1699807488537653303">Laga villu í aðgangsorði</translation>
 <translation id="1700201317341192482">Fjarlægja sýndarkortið</translation>
 <translation id="1700517974991662022">Opnað</translation>
@@ -2484,6 +2485,7 @@
 <translation id="2771816809568414714">Ostur</translation>
 <translation id="2772936498786524345">Ninja</translation>
 <translation id="2773288106548584039">Stuðningur við eldri vafra</translation>
+<translation id="2773621783913034737">Óvirkja flipa</translation>
 <translation id="2773802008104670137">Þessi tegund af skrá gæti skaðað tölvuna þína.</translation>
 <translation id="2775104091073479743">Breyta fingraförum</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{Viðbótin „<ph name="EXTENSION" />“ var með aðgang að tækjum}=1{Viðbótin „<ph name="EXTENSION" />“ er með aðgang að {0} tæki}one{Viðbótin „<ph name="EXTENSION" />“ er með aðgang að {0} tæki}other{Viðbótin „<ph name="EXTENSION" />“ er með aðgang að {0} tækjum}}</translation>
@@ -2564,6 +2566,7 @@
 <translation id="2830528677948328648">Stjórnaðu &amp;Google-reikningnum þínum</translation>
 <translation id="2831430281393059038">Tæki er stutt</translation>
 <translation id="2832124733806557606">Barnið getur notað PIN-númer til að skrá sig inn í tækið eða taka það úr lás.</translation>
+<translation id="2833144527504272627">Fletta með textabendli</translation>
 <translation id="2835177225987815960">Núverandi uppsetning skönnunar verður endurstillt, þ.m.t. úthlutaðir rofar og hraðastillingar sjálfvirkrar skönnunar.</translation>
 <translation id="2835547721736623118">Raddgreiningarþjónusta</translation>
 <translation id="2835761321523638096">Lesa og breyta færslum á leslistanum</translation>
@@ -4120,6 +4123,7 @@
 <translation id="3978325380690188371">Festilyklar eru ekki í boði þegar kveikt er á ChromeVox</translation>
 <translation id="3979395879372752341">Nýrri viðbót bætt við (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326">Gera <ph name="NETWORKDEVICE" /> virkt</translation>
+<translation id="398095528354975981">Fela þessa flipa</translation>
 <translation id="3981058120448670012">Sýnilegt nálægum tækjum sem <ph name="DEVICE_NAME" /> í <ph name="REMAINING_TIME" />...</translation>
 <translation id="3981760180856053153">Ógild tegund vistunar færð inn.</translation>
 <translation id="3982375475032951137">Settu upp vafrann í nokkrum einföldum skrefum</translation>
@@ -6312,6 +6316,7 @@
 <translation id="5642508497713047">CRL-undirritun</translation>
 <translation id="5643191124441701136">Öryggiskóðinn þinn er á framhlið kortsins.</translation>
 <translation id="5643321261065707929">Net með mældri notkun</translation>
+<translation id="5643717184207603910">Hafa afköst hröð</translation>
 <translation id="5646376287012673985">Staðsetning</translation>
 <translation id="5646558797914161501">Viðskiptamaður</translation>
 <translation id="5648021990716966815">Hljóðnematengi</translation>
@@ -6416,6 +6421,7 @@
 <translation id="5733109311583381874">Bættu eigin orðum við orðabækur notanda til að sérsníða tillögur í samtölum.</translation>
 <translation id="5734362860645681824">Samskipti</translation>
 <translation id="5734697361979786483">Bæta samnýttri skráageymslu við</translation>
+<translation id="5735513236153491131">Bæta núna</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{Þessi gögn eða tækið þitt stenst ekki tilteknar öryggisreglur fyrirtækisins. Hafðu samband við stjórnandann til að fá upplýsingar um hvað þarf að lagfæra.}=1{Þetta skrá eða tækið þitt stenst ekki tilteknar öryggisreglur fyrirtækisins. Hafðu samband við stjórnandann til að fá upplýsingar um hvað þarf að lagfæra.}one{Þessar skrár standast ekki tilteknar öryggisreglur fyrirtækisins. Hafðu samband við stjórnandann til að fá upplýsingar um hvað þarf að lagfæra.}other{Þessar skrár standast ekki tilteknar öryggisreglur fyrirtækisins. Hafðu samband við stjórnandann til að fá upplýsingar um hvað þarf að lagfæra.}}</translation>
 <translation id="5738093759615225354">Þú þarft þennan aðgangslykil til að skrá þig inn í tölvuna þína</translation>
 <translation id="5739017626473506901">Skráðu þig inn til að hjálpa <ph name="USER_NAME" /> að bæta við skólareikningi</translation>
@@ -8228,6 +8234,7 @@
 <translation id="7114054701490058191">Aðgangsorðin stemma ekki</translation>
 <translation id="7114648273807173152">Þú getur notað Smart Lock til að skrá þig inn á Google reikninginn þinn með því að fara í Stillingar &gt; Tengd tæki &gt; Síminn þinn &gt; Smart Lock.</translation>
 <translation id="7115361495406486998">Ekki næst í neina tengiliði</translation>
+<translation id="7115731767122970828">Bæta núna</translation>
 <translation id="7116554090938189816">SSL-vottorð prentara er útrunnið. Endurræstu prentarann og reyndu aftur.</translation>
 <translation id="7117228822971127758">Reyndu aftur síðar</translation>
 <translation id="7118268675952955085">skjámynd</translation>
@@ -8383,6 +8390,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (best)</translation>
 <translation id="7246230585855757313">Settu öryggislykilinn aftur inn og reyndu aftur</translation>
 <translation id="724835896049478274">Reikningar sem eru í boði fyrir Android forrit</translation>
+<translation id="7248802599439396696">Óvirkja flipa</translation>
 <translation id="7249197363678284330">Breyttu þessari stillingu á veffangastikunni.</translation>
 <translation id="7249764475759804559">Hafa þetta forrit með sem valkost við opnun skráa</translation>
 <translation id="7250616558727237648">Tækið sem þú ert að deila með svaraði ekki. Reyndu aftur.</translation>
@@ -9977,6 +9985,7 @@
 <translation id="8390392581097975659">Setur upp skönnunarhugbúnað</translation>
 <translation id="8390449457866780408">Ekki næst í netþjóninn.</translation>
 <translation id="8391218455464584335">Vínyll</translation>
+<translation id="8391918125842702622">Viðvörun vegna afkastavandamála</translation>
 <translation id="8392726714909453725">Stillingar fyrir textaupplestur</translation>
 <translation id="8393511274964623038">Stöðva viðbót</translation>
 <translation id="839363317075970734">Nánar um Bluetooth-tæki</translation>
@@ -10077,6 +10086,7 @@
 <translation id="8466052016039127321">Ekki er hægt að halda áfram með fyrri lotu</translation>
 <translation id="8467326454809944210">Velja annað tungumál</translation>
 <translation id="8468087214092422866">Ekki leyfilegt að leita að Bluetooth-tækjum</translation>
+<translation id="8469863130477774813">Afkastabæting í boði</translation>
 <translation id="8470513973197838199">Vistuð aðgangsorð fyrir <ph name="ORIGIN" /></translation>
 <translation id="8471525937465764768">Vefsvæði tengjast yfirleitt USB-tækjum til að nota eiginleika eins og að prenta skjal eða vista í geymslutæki</translation>
 <translation id="8471959340398751476">Afslættir eru ekki virkir. Þú getur virkjað þá í sérsniðsvalmynd</translation>
diff --git a/chrome/app/resources/generated_resources_iw.xtb b/chrome/app/resources/generated_resources_iw.xtb
index 220ee01..a2f5cd6 100644
--- a/chrome/app/resources/generated_resources_iw.xtb
+++ b/chrome/app/resources/generated_resources_iw.xtb
@@ -632,6 +632,7 @@
 <translation id="1467432559032391204">שמאלה</translation>
 <translation id="1468368115497843240">‏הפעולה הזו תמחק מהמכשיר הזה באופן סופי את נתוני הגלישה ושולחנות העבודה הווירטואליים השמורים שמשויכים לפרופיל הזה. יכול להיות שיש אפליקציות אחרות ב-<ph name="DEVICE_TYPE" /> שלך שמחוברות לחשבונות Google שבפרופיל הזה. כדי להסיר את החשבונות האלה, צריך להיכנס אל <ph name="BEGIN_LINK" /><ph name="SETTING_SECTION" /> &gt; <ph name="ACCOUNTS_SECTION" /><ph name="END_LINK" />.</translation>
 <translation id="1468571364034902819">לא ניתן להשתמש בפרופיל הזה</translation>
+<translation id="1469702495092129863">בדיקת המיקרופון</translation>
 <translation id="1470084204649225129">{NUM_TABS,plural, =1{הוספת הכרטיסייה לקבוצה חדשה}one{הוספת כרטיסיות לקבוצה חדשה}two{הוספת כרטיסיות לקבוצה חדשה}other{הוספת כרטיסיות לקבוצה חדשה}}</translation>
 <translation id="1470350905258700113">שימוש במכשיר הזה</translation>
 <translation id="1470946456740188591">‏כדי להפעיל או להשבית או הגלישה באמצעות סמן הטקסט, אפשר להשתמש במקשי הקיצור Ctrl+Search+7</translation>
@@ -2470,6 +2471,7 @@
 <translation id="276582196519778359">עליך להזין קוד אימות לאמצעי בקרת ההורים</translation>
 <translation id="2766006623206032690">הדבקה והמשך</translation>
 <translation id="2766161002040448006">בקשת רשות מההורים</translation>
+<translation id="2766629385177215776">הצמדה אוטומטית של קבוצות כרטיסיות חדשות שנוצרו לסרגל הסימניות בלי קשר לאיזה מכשיר הן נוצרו בו</translation>
 <translation id="2767077837043621282">‏לא ניתן לעדכן את ה-Chromebook. יש לנסות שוב מאוחר יותר.</translation>
 <translation id="2767127727915954024">לאתר <ph name="ORIGIN" /> תהיה הרשאה לערוך את <ph name="FILENAME" /> עד שכל הכרטיסיות של האתר הזה ייסגרו</translation>
 <translation id="2769174155451290427">התמונה שהועלתה</translation>
@@ -2512,6 +2514,7 @@
 <translation id="2794977172822818797">הוספת האתרים שפתוחים כרגע</translation>
 <translation id="2795716239552913152">אתרים משתמשים בדרך כלל במיקום המכשיר כדי לתמוך בתכונות או פרטים רלוונטיים, כמו חדשות מקומיות או חנויות בקרבת מקום</translation>
 <translation id="2798347533012571708">המשך קבלת עדכונים</translation>
+<translation id="2799162042226656283">‏ה-Chrome שלך</translation>
 <translation id="2799223571221894425">הפעלה מחדש</translation>
 <translation id="2800309299477632167">מיפוי מקשים בהתאמה אישית</translation>
 <translation id="2800760947029405028">העלאת תמונה</translation>
@@ -2747,6 +2750,7 @@
 <translation id="2972581237482394796">&amp;ביצוע חוזר</translation>
 <translation id="2973324205039581528">השתקת האודיו באתר</translation>
 <translation id="2975761176769946178">‏נדרשת כתובת URL</translation>
+<translation id="2976547701881428815">כלים ופעולות</translation>
 <translation id="2976557544729462544">יש מכשירים שיפעלו בצורה נכונה או מיטבית רק אם הגנת הגישה לנתונים תושבת.</translation>
 <translation id="2976639738101799892">‏נהנים מחיפוש Google ומהיכולות המתקדמות של Google בכל פעם שגולשים</translation>
 <translation id="2977480621796371840">הסרה מהקבוצה</translation>
@@ -3002,6 +3006,7 @@
 <translation id="316542773973815724">ניווט</translation>
 <translation id="3165734944977250074">לא ניתן להעביר את הקובץ כי הוא כבר לא קיים</translation>
 <translation id="3166443275568926403">ביצועים ומצב הסוללה</translation>
+<translation id="3167562202484086668">מחיקת כל הנתונים מ<ph name="BRAND" /></translation>
 <translation id="3169930038976362151">כאן אפשר לבחור את העיצוב שמתאים לך. כדי לשנות את העיצוב, הטפט, שומר המסך ופריטים נוספים, פשוט לוחצים לחיצה ארוכה על שולחן העבודה.</translation>
 <translation id="3170072451822350649">ניתן גם לדלג על הכניסה ו<ph name="LINK_START" />לגלוש כאורח<ph name="LINK_END" />.</translation>
 <translation id="3175067642577044620">גוף ההודעה</translation>
@@ -3971,6 +3976,7 @@
 <translation id="3873423927483480833">הצגת קודי אימות</translation>
 <translation id="3873915545594852654">‏התרחשה בעיה הקשורה ל-ARC++‎.</translation>
 <translation id="3874164307099183178">‏הפעלת Google Assistant</translation>
+<translation id="3875511946736639169">הפעלת התמונות</translation>
 <translation id="3875815154304214043">האפליקציה <ph name="APP_NAME" /> הוגדרה כך שתיפתח בכרטיסייה חדשה בדפדפן. גם הקישורים הנתמכים ייפתחו בדפדפן. <ph name="BEGIN_LINK_LEARN_MORE" />למידע נוסף<ph name="END_LINK_LEARN_MORE" /></translation>
 <translation id="3876219572815410515">שינוי גודל החלונות למעלה</translation>
 <translation id="3877075909000773256">הגדרות שיתוף בקרבת מקום למכשיר של <ph name="USER_NAME" />. השיתוף יתבצע בשם <ph name="USER_EMAIL" />.</translation>
@@ -5238,6 +5244,7 @@
 <translation id="4846628405149428620">בחירת המיקום לשמירת שינויים על ידי האתר הזה</translation>
 <translation id="4846680374085650406">הפעילות שלך נעשית בהתאם להמלצה של מנהל המערכת לגבי הגדרה זו.</translation>
 <translation id="4847242508757499006">צריך לבחור באפשרות 'ניסיון חוזר', או לבחור באפשרות 'פתיחה בכלי לעריכה בסיסית' כדי להשתמש באפשרויות מוגבלות לתצוגה ולעריכה.</translation>
+<translation id="4847742514726489375">תנועה מופחתת</translation>
 <translation id="4848191975108266266">‏קריאה ל-Google Assistant במילים "Hey Google"</translation>
 <translation id="4849286518551984791">‏זמן אוניברסלי מתואם (UTC/‏GMT)</translation>
 <translation id="4849517651082200438">לא להתקין</translation>
@@ -5426,6 +5433,7 @@
 <translation id="4988526792673242964">דפים</translation>
 <translation id="49896407730300355">סיבוב נ&amp;גד כיוון השעון</translation>
 <translation id="4989966318180235467">בדיקת דף ה&amp;רקע</translation>
+<translation id="4990673372047946816">אין מצלמה זמינה</translation>
 <translation id="4991420928586866460">התייחסות למקשים בשורה העליונה כאל מקשי פונקציה</translation>
 <translation id="4992443049233195791">‏ההגדרות לקובצי Microsoft 365</translation>
 <translation id="4992458225095111526">‏אישור פעולת Powerwash</translation>
@@ -6368,6 +6376,7 @@
 <translation id="5696143504434933566">דיווח על ניצול לרעה על-ידי "<ph name="EXTENSION_NAME" />"</translation>
 <translation id="5696679855467848181">‏קובץ PPD נוכחי בשימוש: <ph name="PPD_NAME" /></translation>
 <translation id="5697832193891326782">בוחר אמוג'י</translation>
+<translation id="5698136107297470317">בחרת למחוק את הנתונים שלך מ<ph name="BRAND" /></translation>
 <translation id="5698878456427040674">עליך לבדוק אם יש תמיכה בחשבון שנבחר.</translation>
 <translation id="5699227710146832453">מתוך</translation>
 <translation id="570043786759263127">‏אפליקציות ושירותים של Google Play</translation>
@@ -7040,6 +7049,7 @@
 <translation id="6209908325007204267">‏המכשיר כולל אפשרות שדרוג ל-Chrome Enterprise, אבל שם המשתמש שלך לא משויך לחשבון ארגוני. כדי ליצור חשבון ארגוני, יש להיכנס לכתובת g.co/ChromeEnterpriseAccount במכשיר אחר.</translation>
 <translation id="6210282067670792090">בסרגל הכתובות, צריך להשתמש במקש הקיצור הזה בשילוב עם קיצורי דרך למנועי חיפוש ולחיפוש באתרים.</translation>
 <translation id="6211067089253408231">הפעלת שיתוף אינטרנט מיידי בין מכשירים</translation>
+<translation id="6211659910592825123">בדיקת המצלמה</translation>
 <translation id="621172521139737651">{COUNT,plural, =0{פתיחת כל הכתובות ב&amp;קבוצת כרטיסיות חדשה}=1{פתיחת הכתובת ב&amp;קבוצת כרטיסיות חדשה}one{פתיחת כל הכתובות ({COUNT}) ב&amp;קבוצת כרטיסיות חדשה}two{פתיחת כל הכתובות ({COUNT}) ב&amp;קבוצת כרטיסיות חדשה}other{פתיחת כל הכתובות ({COUNT}) ב&amp;קבוצת כרטיסיות חדשה}}</translation>
 <translation id="6212039847102026977">הצגת מאפייני רשת מתקדמים</translation>
 <translation id="6212168817037875041">כיבוי המסך</translation>
@@ -7311,7 +7321,7 @@
 <translation id="6418481728190846787">הסרה לצמיתות של גישה עבור כל היישומים</translation>
 <translation id="6418511932144861495">התקנה של עדכון קריטי</translation>
 <translation id="641867537956679916">האדמין שלך התחבר כדי לבדוק בעיה. ניתן יהיה להמשיך להשתמש במכשיר לאחר שהאדמין יחזיר לך את השליטה.</translation>
-<translation id="641899100123938294">סריקה לחיפוש מכשירים חדשים</translation>
+<translation id="641899100123938294">סריקה לאיתור מכשירים חדשים</translation>
 <translation id="6419524191360800346">‏יש עדכון ל-Debian 11 (‏Bullseye)</translation>
 <translation id="6419546358665792306">‏טעינת פריט Unpacked</translation>
 <translation id="642469772702851743">מכשיר זה (מספר סידורי: <ph name="SERIAL_NUMBER" />) ננעל על-ידי הבעלים.</translation>
@@ -7576,6 +7586,7 @@
 <translation id="6624036901798307345">במצב טאבלט, מקישים על הלחצן בסרגל הכלים של מונה הכרטיסיות כדי לפתוח שורת כרטיסיות חדשה עם תצוגה המכילה תמונות ממוזערות של כל כרטיסייה.</translation>
 <translation id="6624687053722465643">מתוקי</translation>
 <translation id="6628328486509726751">הועלה בתאריך <ph name="WEBRTC_LOG_UPLOAD_TIME" /></translation>
+<translation id="662861173589771882">בחירת הסמלים של סרגל הכלים</translation>
 <translation id="6630117778953264026">רמת אבטחה גבוהה יותר</translation>
 <translation id="6630752851777525409"><ph name="EXTENSION_NAME" /> מעוניין בגישה קבועה לאישור כדי לאמת את עצמו בשמך.</translation>
 <translation id="6635362468090274700">אף אחד לא יכול לשתף איתך אם המכשיר לא יוגדר כגלוי.<ph name="BR" /><ph name="BR" />כדי שהמכשיר יהיה גלוי באופן זמני, יש לפתוח את אזור הסטטוס ואז להפעיל את הרשאות הגישה בקרבת מקום.</translation>
@@ -8277,6 +8288,7 @@
 <translation id="7155161204362351654">‏שיפור איכות הווידאו וחיסכון בחיי הסוללה. תוכן וידאו יופעל רק במסך שתומך ב-Cast.</translation>
 <translation id="7159953856712257647">מותקן כברירת מחדל</translation>
 <translation id="7160182524506337403">עכשיו יש לך אפשרות לראות את ההתראות שבטלפון</translation>
+<translation id="7160911207516219534">חלוניות צדדיות</translation>
 <translation id="7165263843655074092">במכשיר הזה יש אבטחה ברמה רגילה</translation>
 <translation id="716640248772308851">"<ph name="EXTENSION" />" יכול לקרוא קובצי תמונות, וידאו ואודיו במיקומים המסומנים.</translation>
 <translation id="7166815366658507447">נקודת האינטרנט מופעלת</translation>
@@ -8303,6 +8315,7 @@
 <translation id="7182063559013288142">נקודת אינטרנט מיידית</translation>
 <translation id="7182791023900310535">העברת הסיסמה שלך</translation>
 <translation id="718427252411067142">כדי למנוע מאנשים אחרים להשתמש בסיסמה שלך, עליך לפתוח את האפליקציה ולשנות את הסיסמה</translation>
+<translation id="718512729823942418">אין מיקרופון זמין</translation>
 <translation id="7186088072322679094">השארה בסרגל הכלים</translation>
 <translation id="7186303001964993981">ל-<ph name="ORIGIN" /> אין הרשאה לפתוח את התיקייה הזו כי היא מכילה קובצי מערכת</translation>
 <translation id="7186568385131859684">‏יש לך אפשרות לשלוט בדרכים שבהן נשתמש בהיסטוריית הגלישה ביחד עם שאר הנתונים שלך בשירותי Google</translation>
@@ -9168,7 +9181,7 @@
 <translation id="7814458197256864873">&amp;העתקה</translation>
 <translation id="7814857791038398352">Microsoft OneDrive</translation>
 <translation id="7815583197273433531">עריכת קיצור הדרך <ph name="SHORTCUT" /> עבור <ph name="EXTENSION_NAME" /></translation>
-<translation id="7815680994978050279">נחסמה הורדה מסוכנת</translation>
+<translation id="7815680994978050279">הורדה מסוכנת נחסמה</translation>
 <translation id="7817361223956157679">‏המקלדת שמופיעה במסך לא עובדת עדיין באפליקציות Linux</translation>
 <translation id="7818135753970109980">עיצוב חדש נוסף (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="7819087895293765164">אחרי ההפעלה מחדש, אפשר להמשיך מהמקום שבו הפסקת באפליקציות, באתרים ובחלונות פתוחים</translation>
@@ -9641,6 +9654,7 @@
 <translation id="8149564499626272569">‏אימות באמצעות הטלפון עם כבל USB</translation>
 <translation id="8149870652370242480">‏כדי להשתמש בטלפון בסיסמאות השמורות, סורקים את קוד ה-QR, מורידים את Chrome ל-iOS ונכנסים לחשבון Google.</translation>
 <translation id="8150396590017071059">שינוי קוד האימות של מנהל הסיסמאות</translation>
+<translation id="8150841750108340884">בחירת הסמלים של סרגל הכלים</translation>
 <translation id="8151057139207656239">‏פרטי ה-build הועתקו</translation>
 <translation id="815114315010033526">‏שימוש בקוד QR במקום זאת</translation>
 <translation id="8151638057146502721">הגדרה</translation>
@@ -9883,6 +9897,7 @@
 <translation id="8327386430364625757">גופן מתמטי</translation>
 <translation id="8327538105740918488">תמיד אפשר לשנות את הסיסמה הזו. היא תישמר ב<ph name="GOOGLE_PASSWORD_MANAGER" /> בחשבון <ph name="EMAIL" />.</translation>
 <translation id="8327676037044516220">הגדרות תוכן והרשאות</translation>
+<translation id="8328228852664998535">לאחר המשך הפעולה, הסיסמאות, מפתחות הגישה ונתונים אחרים יימחקו באופן סופי מ<ph name="BRAND" />. חשבונות שיצרת לאתרים או לאפליקציות לא יימחקו.</translation>
 <translation id="8328777765163860529">סגירת הכול</translation>
 <translation id="8330617762701840933">רשימת האתרים שמפנים לדפדפן חלופי.</translation>
 <translation id="8330689128072902965">אנשי קשר בקרבת מקום יכולים לשתף איתך. אפשר ללחוץ כדי לשנות.</translation>
@@ -9982,6 +9997,7 @@
 <translation id="8394212467245680403">אלפאנומרי</translation>
 <translation id="8394908167088220973">הפעלה/השהיה של המדיה</translation>
 <translation id="8396098434728053815">שיתוף גם של האודיו מהכרטיסייה</translation>
+<translation id="8396657283886698158">כלים ופעולות</translation>
 <translation id="8397825320644530257">ניתוק הטלפון המחובר</translation>
 <translation id="8398877366907290961">להמשיך בכל זאת</translation>
 <translation id="8399282673057829204">הצגת הסיסמה</translation>
@@ -10169,6 +10185,7 @@
 <translation id="8541838361296720865">צריך להקיש על מתג או מקש במקלדת כדי להקצות אותם לפעולה "<ph name="ACTION" />"</translation>
 <translation id="8546186510985480118">חסר שטח אחסון במכשיר</translation>
 <translation id="8546306075665861288">מטמון תמונות</translation>
+<translation id="8546817377311213339">השבתת התמונות</translation>
 <translation id="8546930481464505581">התאמה אישית של סרגל המגע</translation>
 <translation id="8547821378890700958"><ph name="BEGIN_PARAGRAPH1" />החשבון <ph name="USER_EMAIL" /> מנוהל על ידי <ph name="MANAGER" />. אין לך אפשרות להוסיף את כתובת האימייל הזו כחשבון נוסף.<ph name="END_PARAGRAPH1" />
     <ph name="BEGIN_PARAGRAPH2" />כדי להשתמש בחשבון <ph name="USER_EMAIL" />, קודם צריך לצאת מ-<ph name="DEVICE_TYPE" />. לאחר מכן, יש לבחור באפשרות 'הוספת משתמש' בתחתית מסך ההתחברות.<ph name="END_PARAGRAPH2" /></translation>
@@ -10800,6 +10817,7 @@
 <translation id="8998078711690114234">סוג הקובץ הזה עלול להיות מסוכן. יש לשמור את הקובץ רק אם האתר <ph name="ORIGIN" /> מהימן</translation>
 <translation id="8999027165951679951">הנפח שהתפנה בגלל כרטיסייה לא פעילה: <ph name="MEMORY_SAVINGS" /></translation>
 <translation id="8999560016882908256">שגיאה בתחביר של קטע: <ph name="ERROR_LINE" /></translation>
+<translation id="8999651235576960439">הפחתת התנועה במסך</translation>
 <translation id="9000185763019430629">יש לגעת בחיישן טביעות האצבע שבצד ימין של <ph name="DEVICE_TYPE" />. נתוני טביעות האצבע נשמרים באופן מאובטח ואף פעם לא נשלחים ממכשיר <ph name="DEVICE_TYPE" />.</translation>
 <translation id="9003185744423389627">החיבור לשרת ניהול המכשירים נכשל עם הסטטוס '<ph name="STATUS_TEXT" />', בשעה <ph name="FAILURE_TIME" /></translation>
 <translation id="90033698482696970">‏לבצע סריקה אוטומטית של פרופילי eSIM זמינים?</translation>
@@ -11042,7 +11060,7 @@
 <translation id="9167813284871066981"><ph name="NUM_ACCOUNTS" /> חשבונות</translation>
 <translation id="9168436347345867845">מאוחר יותר</translation>
 <translation id="9169093579080634183">מידע נוסף על כרטיסיות</translation>
-<translation id="9169496697824289689">הצגת מקשי קיצור</translation>
+<translation id="9169496697824289689">צפייה במקשי הקיצור</translation>
 <translation id="916964310188958970">למה ההצעה הזאת הופיעה?</translation>
 <translation id="9170048603158555829">Thunderbolt</translation>
 <translation id="9170061643796692986">הגדרת הרשאות הגישה הנוכחית היא 'כל אנשי הקשר'</translation>
@@ -11196,6 +11214,7 @@
 <translation id="992653586748191655">יש <ph name="NUM" /> הצעות לקבוצות של כרטיסיות</translation>
 <translation id="992778845837390402">‏מתבצע כעת גיבוי של Linux</translation>
 <translation id="993540765962421562">ההתקנה עוד לא הסתיימה</translation>
+<translation id="994087375490600917">חלוניות צדדיות</translation>
 <translation id="994289308992179865">הפעלה ב&amp;רצף</translation>
 <translation id="995755448277384931">‏הוספת IBAN</translation>
 <translation id="995782501881226248">YouTube</translation>
diff --git a/chrome/app/resources/generated_resources_ja.xtb b/chrome/app/resources/generated_resources_ja.xtb
index ec93e34..7c0177a 100644
--- a/chrome/app/resources/generated_resources_ja.xtb
+++ b/chrome/app/resources/generated_resources_ja.xtb
@@ -971,6 +971,7 @@
 <translation id="1697150536837697295">アート</translation>
 <translation id="1697686431566694143">ファイルを編集</translation>
 <translation id="1698796500103229697">お支払い方法(&amp;P)</translation>
+<translation id="1698899521169711967">カーソル ブラウジング</translation>
 <translation id="1699807488537653303">パスワード エラーを修正する</translation>
 <translation id="1700201317341192482">仮想カードを削除</translation>
 <translation id="1700517974991662022">アクセス済み</translation>
@@ -2464,6 +2465,7 @@
 <translation id="2771816809568414714">チーズ</translation>
 <translation id="2772936498786524345">スニーキー</translation>
 <translation id="2773288106548584039">従来のブラウザのサポート</translation>
+<translation id="2773621783913034737">タブを非アクティブにする</translation>
 <translation id="2773802008104670137">この種類のファイルはパソコンに危害を及ぼす可能性があります。</translation>
 <translation id="2775104091073479743">指紋を編集</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{拡張機能「<ph name="EXTENSION" />」がデバイスにアクセスしていました}=1{拡張機能「<ph name="EXTENSION" />」が {0} 個のデバイスにアクセスしています}other{拡張機能「<ph name="EXTENSION" />」が {0} 個のデバイスにアクセスしています}}</translation>
@@ -2544,6 +2546,7 @@
 <translation id="2830528677948328648">Google アカウントを管理(&amp;G)</translation>
 <translation id="2831430281393059038">デバイスはサポートされています</translation>
 <translation id="2832124733806557606">お子様はデバイスのログインやロック解除に PIN を使用できます。</translation>
+<translation id="2833144527504272627">テキスト カーソルで移動する</translation>
 <translation id="2835177225987815960">現在のスキャン設定(割り当てたスイッチや自動スキャンの速度設定など)はリセットされます。</translation>
 <translation id="2835547721736623118">音声認識サービス</translation>
 <translation id="2835761321523638096">リーディング リストのエントリの読み取りと変更</translation>
@@ -4097,6 +4100,7 @@
 <translation id="3978325380690188371">ChromeVox が有効になっている場合、固定キーは利用できません</translation>
 <translation id="3979395879372752341">新しい拡張機能が追加されました(<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326"><ph name="NETWORKDEVICE" /> を有効にする</translation>
+<translation id="398095528354975981">これらのタブを非表示にする</translation>
 <translation id="3981058120448670012"><ph name="REMAINING_TIME" />間、付近のデバイスに「<ph name="DEVICE_NAME" />」として表示されます...</translation>
 <translation id="3981760180856053153">入力された保存形式が無効です。</translation>
 <translation id="3982375475032951137">簡単な手順でブラウザを設定できます</translation>
@@ -6284,6 +6288,7 @@
 <translation id="5642508497713047">CRL の署名者</translation>
 <translation id="5643191124441701136">セキュリティ コードはカードの表面に記載されています</translation>
 <translation id="5643321261065707929">従量制ネットワーク</translation>
+<translation id="5643717184207603910">パフォーマンスを高速に保つ</translation>
 <translation id="5646376287012673985">保存先</translation>
 <translation id="5646558797914161501">ビジネスマン</translation>
 <translation id="5648021990716966815">マイク差込口</translation>
@@ -6388,6 +6393,7 @@
 <translation id="5733109311583381874">よく使う単語を単語リストに登録して、変換候補をカスタマイズします</translation>
 <translation id="5734362860645681824">通信</translation>
 <translation id="5734697361979786483">ファイル共有を追加</translation>
+<translation id="5735513236153491131">今すぐ向上</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{このデータまたはお使いのデバイスは、組織のセキュリティ ポリシーの一部に違反しています。修正が必要な箇所を管理者にご確認ください。}=1{このファイルまたはお使いのデバイスは、組織のセキュリティ ポリシーの一部に違反しています。修正が必要な箇所を管理者にご確認ください。}other{これらのファイルは、組織のセキュリティ ポリシーの一部に違反しています。修正が必要な箇所を管理者にご確認ください。}}</translation>
 <translation id="5738093759615225354">パソコンにログインするには、このパスキーが必要です</translation>
 <translation id="5739017626473506901">ログインして、<ph name="USER_NAME" /> さんの学校アカウントの追加を許可してください</translation>
@@ -8197,6 +8203,7 @@
 <translation id="7114054701490058191">パスワードが一致しません</translation>
 <translation id="7114648273807173152">Smart Lock を使用して Google アカウントにログインするには、[設定] &gt; [接続済みのデバイス] &gt; [スマートフォン] &gt; [Smart Lock] に移動します。</translation>
 <translation id="7115361495406486998">連絡先が見つかりませんでした</translation>
+<translation id="7115731767122970828">今すぐ向上</translation>
 <translation id="7116554090938189816">プリンタの SSL 証明書の有効期限が切れています。プリンタを再起動してもう一度お試しください。</translation>
 <translation id="7117228822971127758">しばらくしてからもう一度お試しください</translation>
 <translation id="7118268675952955085">スクリーンショット</translation>
@@ -8352,6 +8359,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" />x<ph name="HEIGHT" />(最適)</translation>
 <translation id="7246230585855757313">セキュリティ キーを挿入し直して、もう一度お試しください</translation>
 <translation id="724835896049478274">Android アプリで使用できるアカウント</translation>
+<translation id="7248802599439396696">タブを非アクティブにする</translation>
 <translation id="7249197363678284330">アドレスバーでこの設定を変更できます。</translation>
 <translation id="7249764475759804559">ファイルを開く際にオプションとしてこのアプリを含める</translation>
 <translation id="7250616558727237648">共有先のデバイスから応答がありませんでした。もう一度お試しください。</translation>
@@ -9945,6 +9953,7 @@
 <translation id="8390392581097975659">スキャナ ソフトウェアをインストールしています</translation>
 <translation id="8390449457866780408">サーバーを使用できません。</translation>
 <translation id="8391218455464584335">レコード</translation>
+<translation id="8391918125842702622">パフォーマンスの問題に関するアラート</translation>
 <translation id="8392726714909453725">「選択して読み上げ」の設定</translation>
 <translation id="8393511274964623038">プラグインを停止</translation>
 <translation id="839363317075970734">Bluetooth デバイスの詳細</translation>
@@ -10045,6 +10054,7 @@
 <translation id="8466052016039127321">前のセッションを再開できません</translation>
 <translation id="8467326454809944210">別の言語を選択</translation>
 <translation id="8468087214092422866">Bluetooth デバイスの検出が許可されていないサイト</translation>
+<translation id="8469863130477774813">パフォーマンスを向上できます</translation>
 <translation id="8470513973197838199"><ph name="ORIGIN" /> 用に保存されているパスワード</translation>
 <translation id="8471525937465764768">多くのサイトは、ドキュメントを印刷したりストレージ デバイスに保存するために USB デバイスに接続します。</translation>
 <translation id="8471959340398751476">割引情報の取得はオフになっています。カスタマイズ メニューでオンにすることができます</translation>
diff --git a/chrome/app/resources/generated_resources_ko.xtb b/chrome/app/resources/generated_resources_ko.xtb
index 024bae07..2a53376 100644
--- a/chrome/app/resources/generated_resources_ko.xtb
+++ b/chrome/app/resources/generated_resources_ko.xtb
@@ -973,6 +973,7 @@
 <translation id="1697150536837697295">예술</translation>
 <translation id="1697686431566694143">파일 수정</translation>
 <translation id="1698796500103229697">결제 수단</translation>
+<translation id="1698899521169711967">캐럿 브라우징</translation>
 <translation id="1699807488537653303">비밀번호 오류 해결</translation>
 <translation id="1700201317341192482">가상 카드 삭제</translation>
 <translation id="1700517974991662022">방문함</translation>
@@ -2485,6 +2486,7 @@
 <translation id="2771816809568414714">치즈</translation>
 <translation id="2772936498786524345">닌자</translation>
 <translation id="2773288106548584039">이전 브라우저 지원</translation>
+<translation id="2773621783913034737">탭 비활성화</translation>
 <translation id="2773802008104670137">컴퓨터에 유해할 수 있는 파일 유형입니다.</translation>
 <translation id="2775104091073479743">지문 수정</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{확장 프로그램 ‘<ph name="EXTENSION" />’에서 기기에 액세스했습니다.}=1{확장 프로그램 ‘<ph name="EXTENSION" />’에서 기기 {0}대에 액세스하는 중입니다.}other{확장 프로그램 ‘<ph name="EXTENSION" />’에서 기기 {0}대에 액세스하는 중입니다.}}</translation>
@@ -2565,6 +2567,7 @@
 <translation id="2830528677948328648">Google 계정 관리(&amp;G)</translation>
 <translation id="2831430281393059038">지원되는 기기입니다.</translation>
 <translation id="2832124733806557606">자녀가 PIN을 사용해 로그인하거나 기기를 잠금 해제할 수 있습니다</translation>
+<translation id="2833144527504272627">텍스트 커서로 탐색</translation>
 <translation id="2835177225987815960">할당된 스위치 및 자동 스캔 속도 환경설정을 포함하여 현재의 스캔 설정이 재설정됩니다.</translation>
 <translation id="2835547721736623118">음성 인식 서비스</translation>
 <translation id="2835761321523638096">읽기 목록의 항목 읽기 및 변경</translation>
@@ -4121,6 +4124,7 @@
 <translation id="3978325380690188371">ChromeVox가 사용 설정된 경우 고정키를 사용할 수 없음</translation>
 <translation id="3979395879372752341">새 확장 프로그램이 추가됨(<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326"><ph name="NETWORKDEVICE" /> 사용</translation>
+<translation id="398095528354975981">탭 숨기기</translation>
 <translation id="3981058120448670012"><ph name="REMAINING_TIME" /> 동안 주변 기기에 <ph name="DEVICE_NAME" />(으)로 표시됩니다.</translation>
 <translation id="3981760180856053153">잘못된 저장 유형을 입력했습니다.</translation>
 <translation id="3982375475032951137">몇 단계 만에 간단하게 브라우저를 설정하세요.</translation>
@@ -6312,6 +6316,7 @@
 <translation id="5642508497713047">CRL 서명자</translation>
 <translation id="5643191124441701136">보안 코드는 카드 앞면에 있습니다</translation>
 <translation id="5643321261065707929">종량제 네트워크</translation>
+<translation id="5643717184207603910">성능을 빠르게 유지</translation>
 <translation id="5646376287012673985">위치</translation>
 <translation id="5646558797914161501">사업가</translation>
 <translation id="5648021990716966815">마이크 잭</translation>
@@ -6416,6 +6421,7 @@
 <translation id="5733109311583381874">변환 후보를 맞춤설정하려면 나만의 단어를 사용자 사전에 추가하세요</translation>
 <translation id="5734362860645681824">커뮤니케이션</translation>
 <translation id="5734697361979786483">파일 공유 추가</translation>
+<translation id="5735513236153491131">지금 향상</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{데이터 또는 기기가 조직의 보안 정책 중 일부를 준수하지 않습니다. 관리자와 함께 문제 해결을 상의하세요.}=1{파일 또는 기기가 조직의 보안 정책 중 일부를 준수하지 않습니다. 관리자와 함께 문제 해결을 상의하세요.}other{파일이 조직의 보안 정책 중 일부를 준수하지 않습니다. 관리자와 함께 문제 해결을 상의하세요.}}</translation>
 <translation id="5738093759615225354">컴퓨터에 로그인하려면 이 패스키가 필요합니다.</translation>
 <translation id="5739017626473506901"><ph name="USER_NAME" />님이 학교 계정을 추가할 수 있도록 로그인하세요.</translation>
@@ -8227,6 +8233,7 @@
 <translation id="7114054701490058191">비밀번호가 일치하지 않습니다.</translation>
 <translation id="7114648273807173152">Smart Lock을 사용해 Google 계정에 로그인하려면 설정 &gt; 연결된 기기 &gt; 휴대전화 &gt; Smart Lock으로 이동하세요.</translation>
 <translation id="7115361495406486998">연락 가능한 연락처 없음</translation>
+<translation id="7115731767122970828">지금 향상</translation>
 <translation id="7116554090938189816">프린터 SSL 인증서가 만료되었습니다. 프린터를 다시 시작한 후 다시 시도해 보세요</translation>
 <translation id="7117228822971127758">나중에 다시 시도해 주세요</translation>
 <translation id="7118268675952955085">스크린샷</translation>
@@ -8382,6 +8389,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" />x<ph name="HEIGHT" />(최고)</translation>
 <translation id="7246230585855757313">보안 키를 다시 삽입하고 한번 더 시도해 보세요.</translation>
 <translation id="724835896049478274">Android 앱에서 사용할 수 있는 계정</translation>
+<translation id="7248802599439396696">탭 비활성화</translation>
 <translation id="7249197363678284330">주소 표시줄에서 이 설정을 변경하세요.</translation>
 <translation id="7249764475759804559">파일을 열 때 이 앱을 연결 프로그램 옵션으로 포함합니다.</translation>
 <translation id="7250616558727237648">공유하려는 기기가 응답하지 않습니다. 다시 시도해 주세요.</translation>
@@ -9977,6 +9985,7 @@
 <translation id="8390392581097975659">스캐너 소프트웨어 설치 중</translation>
 <translation id="8390449457866780408">서버를 사용할 수 없습니다.</translation>
 <translation id="8391218455464584335">레코드판</translation>
+<translation id="8391918125842702622">성능 문제 알림</translation>
 <translation id="8392726714909453725">텍스트 읽어주기 설정</translation>
 <translation id="8393511274964623038">플러그인 중지</translation>
 <translation id="839363317075970734">블루투스 기기 세부정보</translation>
@@ -10077,6 +10086,7 @@
 <translation id="8466052016039127321">이전 세션을 재개할 수 없음</translation>
 <translation id="8467326454809944210">다른 언어 선택</translation>
 <translation id="8468087214092422866">블루투스 기기 검색 허용 안됨</translation>
+<translation id="8469863130477774813">성능 향상 가능</translation>
 <translation id="8470513973197838199"><ph name="ORIGIN" />의 저장된 비밀번호</translation>
 <translation id="8471525937465764768">사이트에서는 일반적으로 문서 인쇄 또는 스토리지 기기에 저장과 같은 기능을 사용하기 위해 USB 기기에 연결합니다.</translation>
 <translation id="8471959340398751476">할인 기능이 사용 중지되었습니다. 맞춤설정 메뉴에서 사용 설정할 수 있습니다.</translation>
diff --git a/chrome/app/resources/generated_resources_lo.xtb b/chrome/app/resources/generated_resources_lo.xtb
index dbe1e52..604cc7a 100644
--- a/chrome/app/resources/generated_resources_lo.xtb
+++ b/chrome/app/resources/generated_resources_lo.xtb
@@ -971,6 +971,7 @@
 <translation id="1697150536837697295">ສິນລະປະ</translation>
 <translation id="1697686431566694143">ແກ້ໄຂໄຟລ໌</translation>
 <translation id="1698796500103229697">&amp;ວິທີການຈ່າຍເງິນ</translation>
+<translation id="1698899521169711967">ການຮຽກເບິ່ງດ້ວຍແປ້ນພິມ</translation>
 <translation id="1699807488537653303">ແກ້ໄຂຂໍ້ຜິດພາດລະຫັດຜ່ານ</translation>
 <translation id="1700201317341192482">ລຶບບັດສະເໝືອນຂອງທ່ານອອກ</translation>
 <translation id="1700517974991662022">ເຂົ້າເບິ່ງແລ້ວ</translation>
@@ -2482,6 +2483,7 @@
 <translation id="2771816809568414714">ເນີຍແຂງ</translation>
 <translation id="2772936498786524345">ລັບໆລີ້ໆ</translation>
 <translation id="2773288106548584039">ການຮອງຮັບໂປຣແກຣມທ່ອງເວັບເກົ່າ</translation>
+<translation id="2773621783913034737">ເຮັດໃຫ້ແຖບບໍ່ເຮັດວຽກ</translation>
 <translation id="2773802008104670137">ໄຟລ໌ປະເພດນີ້ອາດຈະເປັນອັນຕະລາຍຕໍ່ກັບຄອມພິວເຕີຂອງທ່ານ.</translation>
 <translation id="2775104091073479743">ແກ້ໄຂລາຍນິ້ວມື</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{ສ່ວນຂະຫຍາຍ "<ph name="EXTENSION" />" ໄດ້ກຳລັງເຂົ້າເຖິງອຸປະກອນ}=1{ສ່ວນຂະຫຍາຍ "<ph name="EXTENSION" />" ກຳລັງເຂົ້າເຖິງ {0} ອຸປະກອນ}other{ສ່ວນຂະຫຍາຍ "<ph name="EXTENSION" />" ກຳລັງເຂົ້າເຖິງ {0} ອຸປະກອນ}}</translation>
@@ -2562,6 +2564,7 @@
 <translation id="2830528677948328648">ຈັດການ&amp;ບັນຊີ Google ຂອງທ່ານ</translation>
 <translation id="2831430281393059038">ບໍ່ຮອງຮັບອຸປະກອນ</translation>
 <translation id="2832124733806557606">ລູກຂອງທ່ານສາມາດໃຊ້ PIN ເພື່ອເຂົ້າສູ່ລະບົບ ຫຼື ປົດລັອກອຸປະກອນນີ້ໄດ້.</translation>
+<translation id="2833144527504272627">ນຳທາງໄປຫາສ່ວນຕ່າງໆດ້ວຍເຄີເຊີຂໍ້ຄວາມ</translation>
 <translation id="2835177225987815960">ລະບົບຈະຣີເຊັດການຕັ້ງຄ່າການສະແກນປັດຈຸບັນຂອງທ່ານ, ຮວມທັງສະວິດໃດກໍຕາມທີ່ໄດ້ຮັບມອບໝາຍ ແລະ ການຕັ້ງຄ່າຄວາມໄວການສະແກນອັດຕະໂນມັດ.</translation>
 <translation id="2835547721736623118">ການບໍລິການຈຳແນກສຽງເວົ້າ</translation>
 <translation id="2835761321523638096">ອ່ານ ແລະ ປ່ຽນແປງລາຍການນີ້ໃນລາຍຊື່ການອ່ານ</translation>
@@ -4118,6 +4121,7 @@
 <translation id="3978325380690188371">ປຸ່ມກົດຄ້າງບໍ່ມີໃຫ້ໃຊ້ເມື່ອ ChromeVox ເປີດຢູ່</translation>
 <translation id="3979395879372752341">ເພີ່ມສ່ວນຂະຫຍາຍໃໝ່ແລ້ວ ( <ph name="EXTENSION_NAME" /> )</translation>
 <translation id="3979748722126423326">ເປີດໃຊ້ງານ <ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">ເຊື່ອງແຖບເຫຼົ່ານີ້</translation>
 <translation id="3981058120448670012">ເບິ່ງເຫັນຕໍ່ກັບອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງເປັນ <ph name="DEVICE_NAME" /> ສຳລັບ <ph name="REMAINING_TIME" />...</translation>
 <translation id="3981760180856053153">ປະເພດບັນທຶກທີ່ໃຊ້ບໍ່ໄດ້ປ້ອນ​ເຂົ້າ​ແລ້ວ.</translation>
 <translation id="3982375475032951137">ຕັ້ງຄ່າໂປຣແກຣມທ່ອງເວັບຂອງທ່ານໃນສອງສາມຂັ້ນຕອນ</translation>
@@ -6309,6 +6313,7 @@
 <translation id="5642508497713047">ຜູ້ເຊັນ CRL</translation>
 <translation id="5643191124441701136">ລະຫັດຄວາມປອດໄພຂອງທ່ານຢູ່ໜ້າບັດຂອງທ່ານ</translation>
 <translation id="5643321261065707929">ເຄືອຂ່າຍມີການວັດແທກປະລິມານອິນເຕີເນັດ</translation>
+<translation id="5643717184207603910">ຮັກສາປະສິດທິພາບໃຫ້ວ່ອງໄວຢູ່ສະເໝີ</translation>
 <translation id="5646376287012673985">ສະ​ຖານ​ທີ່</translation>
 <translation id="5646558797914161501">ນັກທຸລະກິດ</translation>
 <translation id="5648021990716966815">ແຈັກໄມໂຄຣໂຟນ</translation>
@@ -6413,6 +6418,7 @@
 <translation id="5733109311583381874">ເພີ່ມຄຳສັບຂອງທ່ານໄປໃສ່ວັດຈະນານຸກົມຜູ້ໃຊ້ເພື່ອປັບແຕ່ງຕົວເລືອກການປ່ຽນຄ່າ.</translation>
 <translation id="5734362860645681824">ການ​ສື່​ສານ</translation>
 <translation id="5734697361979786483">ເພີ່ມການແບ່ງປັນໄຟລ໌</translation>
+<translation id="5735513236153491131">ເພີ່ມຕອນນີ້ເລີຍ</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{ຂໍ້ມູນນີ້ ຫຼື ອຸປະກອນຂອງທ່ານບໍ່ເປັນໄປຕາມນະໂຍບາຍຄວາມປອດໄພບາງຢ່າງຂອງອົງການທ່ານ. ກະລຸນາກວດສອບກັບຜູ້ເບິ່ງແຍງຂອງທ່ານວ່າຕ້ອງແກ້ໄຂຫຍັງ.}=1{ໄຟລ໌ນີ້ ຫຼື ອຸປະກອນຂອງທ່ານບໍ່ເປັນໄປຕາມນະໂຍບາຍຄວາມປອດໄພບາງຢ່າງຂອງອົງການທ່ານ. ກະລຸນາກວດສອບກັບຜູ້ເບິ່ງແຍງຂອງທ່ານວ່າຕ້ອງແກ້ໄຂຫຍັງ.}other{ໄຟລ໌ເຫຼົ່ານີ້ບໍ່ເປັນໄປຕາມນະໂຍບາຍຄວາມປອດໄພບາງຢ່າງຂອງອົງການທ່ານ. ກະລຸນາກວດສອບກັບຜູ້ເບິ່ງແຍງຂອງທ່ານວ່າຕ້ອງແກ້ໄຂຫຍັງ.}}</translation>
 <translation id="5738093759615225354">ທ່ານຕ້ອງການກະແຈຜ່ານນີ້ເພື່ອເຂົ້າສູ່ລະບົບຄອມພິວເຕີຂອງທ່ານ</translation>
 <translation id="5739017626473506901">ເຂົ້າສູ່ລະບົບເພື່ອຊ່ວຍ <ph name="USER_NAME" /> ເພີ່ມບັນຊີໂຮງຮຽນ</translation>
@@ -8223,6 +8229,7 @@
 <translation id="7114054701490058191">ລະຫັດຜ່ານບໍ່ກົງກັນ</translation>
 <translation id="7114648273807173152">ເພື່ອໃຊ້ Smart Lock ເພື່ອເຂົ້າສູ່ລະບົບບັນຊີ Google ຂອງທ່ານ, ກະລຸນາໄປທີ່ການຕັ້ງຄ່າ &gt; ອຸປະກອນທີ່ເຊື່ອມຕໍ່ &gt; ໂທລະສັບຂອງທ່ານ &gt; Smart Lock.</translation>
 <translation id="7115361495406486998">ບໍ່ມີລາຍຊື່ຜູ້ຕິດຕໍ່ທີ່ຕິດຕໍ່ຫາໄດ້</translation>
+<translation id="7115731767122970828">ເພີ່ມຕອນນີ້ເລີຍ</translation>
 <translation id="7116554090938189816">ໃບຮັບຮອງ SSL ຂອງເຄື່ອງພິມໝົດອາຍຸແລ້ວ. ຣີສະຕາດເຄື່ອງພິມແລ້ວລອງໃໝ່.</translation>
 <translation id="7117228822971127758">ກະລຸນາລອງໃໝ່ໃນພາຍຫຼັງ</translation>
 <translation id="7118268675952955085">ຮູບໜ້າຈໍ</translation>
@@ -8378,6 +8385,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (ດີທີ່ສຸດ)</translation>
 <translation id="7246230585855757313">ສຽບກະແຈຄວາມປອດໄພຂອງທ່ານຄືນໃໝ່ ແລ້ວລອງອີກຄັ້ງ</translation>
 <translation id="724835896049478274">ມີບັນຊີສຳລັບແອັບ Android</translation>
+<translation id="7248802599439396696">ເຮັດໃຫ້ແຖບບໍ່ເຮັດວຽກ</translation>
 <translation id="7249197363678284330">ປ່ຽນການຕັ້ງຄ່ານີ້ໄດ້ໃນ​ແຖບທີ່​ຢູ່.</translation>
 <translation id="7249764475759804559">ຮວມແອັບນີ້ເປັນຕົວເລືອກໃນເວລາເປີດໄຟລ໌</translation>
 <translation id="7250616558727237648">ອຸປະກອນທີ່ທ່ານກຳລັງແບ່ງປັນບໍ່ຕອບສະໜອງ. ກະລຸນາລອງໃໝ່.</translation>
@@ -9970,6 +9978,7 @@
 <translation id="8390392581097975659">ກຳລັງຕິດຕັ້ງຊອບແວເຄື່ອງສະແກນ</translation>
 <translation id="8390449457866780408">ບໍ່ມີເຊີບເວີຢູ່</translation>
 <translation id="8391218455464584335">ໄວນິລ</translation>
+<translation id="8391918125842702622">ການແຈ້ງເຕືອນບັນຫາດ້ານປະສິດທິພາບ</translation>
 <translation id="8392726714909453725">ການຕັ້ງຄ່າເລືອກເພື່ອເວົ້າ</translation>
 <translation id="8393511274964623038">ຢຸດປລັກອິນ</translation>
 <translation id="839363317075970734">ລາຍລະອຽດອຸປະກອນ Bluetooth</translation>
@@ -10070,6 +10079,7 @@
 <translation id="8466052016039127321">ບໍ່ສາມາດສືບຕໍ່ເຊດຊັນກ່ອນໜ້ານີ້ໄດ້</translation>
 <translation id="8467326454809944210">ເລືອກພາສາອື່ນ</translation>
 <translation id="8468087214092422866">ບໍ່ອະນຸຍາດໃຫ້ຊອກຫາອຸປະກອນ Bluetooth</translation>
+<translation id="8469863130477774813">ການເພີ່ມປະສິດທິພາບພ້ອມນຳໃຊ້ແລ້ວ</translation>
 <translation id="8470513973197838199">ລະຫັດຜ່ານທີ່ບັນທຶກໄວ້ສຳລັບ <ph name="ORIGIN" /></translation>
 <translation id="8471525937465764768">ໂດຍປົກກະຕິ ເວັບໄຊຈະເຊື່ອມຕໍ່ກັບອຸປະກອນ USB ສຳລັບຄຸນສົມບັດ ເຊັ່ນ: ການພິມເອກະສານ ຫຼື ການບັນທຶກໄວ້ໃນອຸປະກອນຈັດເກັບຂໍ້ມູນ</translation>
 <translation id="8471959340398751476">ສ່ວນຫຼຸດຖືກປິດການນຳໃຊ້ຢູ່. ທ່ານສາມາດເປີດໃຊ້ພວກມັນໄດ້ໃນເມນູປັບແຕ່ງ</translation>
diff --git a/chrome/app/resources/generated_resources_mn.xtb b/chrome/app/resources/generated_resources_mn.xtb
index c279461d..f43b8e4 100644
--- a/chrome/app/resources/generated_resources_mn.xtb
+++ b/chrome/app/resources/generated_resources_mn.xtb
@@ -969,6 +969,7 @@
 <translation id="1697150536837697295">Урлаг</translation>
 <translation id="1697686431566694143">Файлыг засах</translation>
 <translation id="1698796500103229697">&amp;Төлбөрийн хэрэгслүүд</translation>
+<translation id="1698899521169711967">Caret Browsing</translation>
 <translation id="1699807488537653303">Нууц үгний алдааг засах</translation>
 <translation id="1700201317341192482">Виртуал картаа хасах</translation>
 <translation id="1700517974991662022">Зочилсон</translation>
@@ -2479,6 +2480,7 @@
 <translation id="2771816809568414714">Бяслаг</translation>
 <translation id="2772936498786524345">Sneaky</translation>
 <translation id="2773288106548584039">Одоогийн хөтчийн дэмжлэг</translation>
+<translation id="2773621783913034737">Табуудыг идэвхгүй болгох</translation>
 <translation id="2773802008104670137">Ийм төрлийн файл таны компьютерт аюул учруулж болзошгүй.</translation>
 <translation id="2775104091073479743">Хурууны хээг солих</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{"<ph name="EXTENSION" />" өргөтгөл төхөөрөмжүүдэд хандаж байсан}=1{"<ph name="EXTENSION" />" өргөтгөл {0} төхөөрөмжид хандаж байна}other{"<ph name="EXTENSION" />" өргөтгөл {0} төхөөрөмжид хандаж байна}}</translation>
@@ -2559,6 +2561,7 @@
 <translation id="2830528677948328648">&amp;Google бүртгэлээ удирдах</translation>
 <translation id="2831430281393059038">Төхөөрөмжийг дэмждэг</translation>
 <translation id="2832124733806557606">Таны хүүхэд төхөөрөмжид нэвтрэх эсвэл түгжээг тайлахын тулд ПИН ашиглах боломжтой.</translation>
+<translation id="2833144527504272627">Текстийн курсороор шилжих</translation>
 <translation id="2835177225987815960">Таны оноосон аливаа сэлгүүр болон автоматаар скан хийх хурдны тохиргоог оруулаад одоогийн скан хийх тохируулгыг шинэчилнэ.</translation>
 <translation id="2835547721736623118">Яриа таних үйлчилгээ</translation>
 <translation id="2835761321523638096">Унших жагсаалтын оруулгуудыг оруулах болон өөрчлөх</translation>
@@ -4114,6 +4117,7 @@
 <translation id="3978325380690188371">ChromeVox асаалттай үед бэхэлсэн түлхүүр боломжгүй</translation>
 <translation id="3979395879372752341">Шинэ өргөтгөл нэмсэн ( <ph name="EXTENSION_NAME" /> )</translation>
 <translation id="3979748722126423326"><ph name="NETWORKDEVICE" />-ыг идэвхжүүл</translation>
+<translation id="398095528354975981">Эдгээр табыг нуух</translation>
 <translation id="3981058120448670012">Ойролцоох төхөөрөмжүүдэд <ph name="REMAINING_TIME" />-н турш <ph name="DEVICE_NAME" />-р харагдана...</translation>
 <translation id="3981760180856053153">Хадгалах хүчингүй төрөл орсон байна.</translation>
 <translation id="3982375475032951137">Хөтчөө энгийн хэдэн алхмаар тохируулна уу</translation>
@@ -6307,6 +6311,7 @@
 <translation id="5642508497713047">CRL гарын үсэг зурагч</translation>
 <translation id="5643191124441701136">Таны аюулгүй байдлын код картын тань урд талд байна</translation>
 <translation id="5643321261065707929">Хязгаартай сүлжээ</translation>
+<translation id="5643717184207603910">Гүйцэтгэлийг хурдтай байлгаарай</translation>
 <translation id="5646376287012673985">Байршил</translation>
 <translation id="5646558797914161501">Ажил хэрэгч хүн</translation>
 <translation id="5648021990716966815">Микрофоны чихэвчний оролт</translation>
@@ -6411,6 +6416,7 @@
 <translation id="5733109311583381874">Хөрвүүлэлтийн хувилбаруудыг өөрчлөхийн тулд та өөрийн үгийг хэрэглэгчийн тольд нэмнэ үү.</translation>
 <translation id="5734362860645681824">Харилцаа холбоо</translation>
 <translation id="5734697361979786483">Файл хуваалцахыг нэмэх</translation>
+<translation id="5735513236153491131">Одоо идэвхжүүлэх</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{Энэ өгөгдөл эсвэл таны төхөөрөмж байгууллагын тань аюулгүй байдлын зарим бодлогод нийцэхгүй байна. Юуг засах шаардлагатай талаар админаасаа тодруулна уу.}=1{Энэ файл эсвэл таны төхөөрөмж байгууллагын тань аюулгүй байдлын зарим бодлогод нийцэхгүй байна. Юуг засах шаардлагатай талаар админаасаа тодруулна уу.}other{Эдгээр файл танай байгууллагын аюулгүй байдлын зарим бодлогод нийцэхгүй байна. Юуг засах шаардлагатай талаар админаасаа тодруулна уу.}}</translation>
 <translation id="5738093759615225354">Энэ нууц үг компьютертоо нэвтрэхэд тань хэрэгтэй</translation>
 <translation id="5739017626473506901"><ph name="USER_NAME" />-д сургуулийн бүртгэл нэмэхэд нь туслахын тулд нэвтэрнэ үү</translation>
@@ -8220,6 +8226,7 @@
 <translation id="7114054701490058191">Нууц үг таарахгүй байна</translation>
 <translation id="7114648273807173152">Google бүртгэлдээ нэвтрэх ухаалаг түгжээ ашиглахын тулд Тохиргоо &gt; Холбогдсон төхөөрөмжүүд &gt; Таны утас &gt; Ухаалаг түгжээ хэсэгт очно уу.</translation>
 <translation id="7115361495406486998">Холбогдох боломжгүй харилцагчид</translation>
+<translation id="7115731767122970828">Одоо идэвхжүүлэх</translation>
 <translation id="7116554090938189816">Хэвлэгчийн SSL сертификатын хугацаа дууссан. Хэвлэгчийг дахин эхлүүлж, дахин оролдоно уу.</translation>
 <translation id="7117228822971127758">Дараа дахин оролдоно уу</translation>
 <translation id="7118268675952955085">дэлгэцийн агшин</translation>
@@ -8375,6 +8382,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Шилдэг)</translation>
 <translation id="7246230585855757313">Аюулгүй байдлын түлхүүрээ дахин залгаад дахин оролдоно уу</translation>
 <translation id="724835896049478274">Android аппуудад боломжтой бүртгэлүүд</translation>
+<translation id="7248802599439396696">Табуудыг идэвхгүй болгох</translation>
 <translation id="7249197363678284330">Энэ тохиргоог хаяг оруулах хэсэгт өөрчилнө үү.</translation>
 <translation id="7249764475759804559">Файлуудыг нээх үед энэ аппыг сонголтоор оруулах</translation>
 <translation id="7250616558727237648">Таны хуваалцаж буй төхөөрөмж хариу өгсөнгүй. Дахин оролдоно уу.</translation>
@@ -9967,6 +9975,7 @@
 <translation id="8390392581097975659">Сканнерын программ хангамжийг суулгаж байна</translation>
 <translation id="8390449457866780408">Серверүүд ажиллах боломжгүй байна.</translation>
 <translation id="8391218455464584335">Пянз</translation>
+<translation id="8391918125842702622">Гүйцэтгэлийн асуудлын сэрэмжлүүлэг</translation>
 <translation id="8392726714909453725">Ярихаар сонгох онцлогийн тохиргоо</translation>
 <translation id="8393511274964623038">Нэмэлт өргөтгөлийг зогсоох</translation>
 <translation id="839363317075970734">Bluetooth төхөөрөмжийн дэлгэрэнгүй</translation>
@@ -10067,6 +10076,7 @@
 <translation id="8466052016039127321">Өмнөх харилцан үйлдлийг үргэлжлүүлэх боломжгүй</translation>
 <translation id="8467326454809944210">Өөр хэл сонгох</translation>
 <translation id="8468087214092422866">Bluetooth төхөөрөмж хайхыг зөвшөөрөөгүй</translation>
+<translation id="8469863130477774813">Гүйцэтгэлийг идэвхжүүлэх боломжтой</translation>
 <translation id="8470513973197838199"><ph name="ORIGIN" />-н хадгалсан нууц үг</translation>
 <translation id="8471525937465764768">Сайтууд ихэвчлэн документ хэвлэх эсвэл хадгалах сангийн төхөөрөмжид хадгалах зэрэг онцлогуудад зориулж USB төхөөрөмжид холбогддог</translation>
 <translation id="8471959340398751476">Хөнгөлөлт унтраалттай байна. Та үүнийг өөрчлөх цэсэд асаах боломжтой</translation>
diff --git a/chrome/app/resources/generated_resources_mr.xtb b/chrome/app/resources/generated_resources_mr.xtb
index 8e1313d..e0035fe 100644
--- a/chrome/app/resources/generated_resources_mr.xtb
+++ b/chrome/app/resources/generated_resources_mr.xtb
@@ -409,6 +409,7 @@
 <translation id="1293556467332435079">Files</translation>
 <translation id="1294807885394205587">या प्रक्रियेला काही मिनिटे लागू शकतात. कंटेनर व्यवस्थापक सुरू करत आहे.</translation>
 <translation id="12951065153783848">तुमची संस्था तुमचे खाते व्यवस्थापित करते</translation>
+<translation id="1296410481664942178">Google Calendar दाखवू नका</translation>
 <translation id="1296911687402551044">निवडलेला टॅब पिन करा</translation>
 <translation id="1297175357211070620">गंतव्य</translation>
 <translation id="129770436432446029"><ph name="EXPERIMENT_NAME" /> विषयी फीडबॅक पाठवा</translation>
@@ -447,6 +448,7 @@
 <translation id="1327495825214193325">ADB डीबगिंग सुरू करण्यासाठी, हे <ph name="DEVICE_TYPE" /> रीस्टार्ट करणे आवश्यक आहे. ते बंद करण्यासाठी फॅक्टरी सेटिंग्जवर रीसेट करणे आवश्यक आहे.</translation>
 <translation id="1327527584824210101">तुमची पासकी वापरा</translation>
 <translation id="1327794256477341646">तुमच्या स्थानाची आवश्यकता असलेली वैशिष्ट्ये काम करणार नाहीत</translation>
+<translation id="1328364753167940710"><ph name="NUM_HR" /> तासामध्ये</translation>
 <translation id="1329466763986822896">या हॉटस्पॉटसाठीच्या गोपनीयतेमध्ये सुधारणा करा</translation>
 <translation id="1331977651797684645">ही व्यक्ती मी आहे.</translation>
 <translation id="1333489022424033687">तुम्ही इतर साइटनी तुमच्या डिव्हाइसवर स्टोअर केलेला डेटा साफ करेपर्यंत <ph name="ORIGIN" /> वरील काही वैशिष्ट्ये कदाचित काम करणार नाहीत</translation>
@@ -972,6 +974,7 @@
 <translation id="1697150536837697295">कला</translation>
 <translation id="1697686431566694143">फाइल संपादित करा</translation>
 <translation id="1698796500103229697">&amp;पेमेंट पद्धती</translation>
+<translation id="1698899521169711967">कॅरेट ब्राउझिंग</translation>
 <translation id="1699807488537653303">पासवर्डशी संबंधित एररचे निराकरण करा</translation>
 <translation id="1700201317341192482">तुमचे व्हर्च्युअल कार्ड काढून टाका</translation>
 <translation id="1700517974991662022">भेट दिलेला</translation>
@@ -1003,6 +1006,7 @@
 <translation id="1709762881904163296">नेटवर्क सेटिंग्ज</translation>
 <translation id="1709916727352927457">पासकी हटवा</translation>
 <translation id="1709972045049031556">शेअर करू शकत नाही</translation>
+<translation id="1712143791363119140">प्रगतीपथावर आहे</translation>
 <translation id="1714644264617423774">तुमचे डिव्हाइस वापरण्यास सुलभ करण्यासाठी अ‍ॅक्सेसिबिलिटी वैशिष्ट्ये सुरू करा. <ph name="LINK_BEGIN" />अधिक जाणून घ्या<ph name="LINK_END" /></translation>
 <translation id="1716034099915639464"><ph name="SITE_NAME" /> आणि त्याचे इंस्टॉल केलेले अ‍ॅप यांच्यासाठी साइट डेटा व परवानग्या हटवायच्या आहेत का?</translation>
 <translation id="171826447717908393">आयसोलेटेड वेब ॲप्स (बीटा)</translation>
@@ -1407,6 +1411,7 @@
 <translation id="200928901437634269">तुमच्या लहान मुलाचे Google खाते किंवा शाळेचे खाते वापरा. तुम्ही पालक नियंत्रणेदेखील सेट करू शकता.</translation>
 <translation id="2009590708342941694">इमोजी टूल</translation>
 <translation id="2010501376126504057">कंपॅटिबल डिव्हाइस</translation>
+<translation id="2010636492623189611">निवडले आहे.</translation>
 <translation id="201217432804812273">"गट सेव्ह करा" हे सुरू करा</translation>
 <translation id="2012935757369720523">फाइल हटवा</translation>
 <translation id="2013550551806600826">हे वापरून पहा. सेटिंग सुरू किंवा बंद करा, त्यानंतर चाचणीसाठीच्या भागामध्ये तुमच्या टचपॅडवर दोन बोटांनी स्क्रोल करा. तुम्ही हे नंतर सेटिंग्ज &gt; डिव्हाइस &gt; माउस आणि टचपॅडमध्येदेखील पाहू शकता.</translation>
@@ -2002,6 +2007,7 @@
 <translation id="2435248616906486374">नेटवर्क डिस्कनेक्ट झाले</translation>
 <translation id="2435457462613246316">पासवर्ड दर्शवा</translation>
 <translation id="2436385001956947090">लिंक कॉपी करा</translation>
+<translation id="2437561292559037753">डेटा शेअरिंग</translation>
 <translation id="2438853563451647815">प्रिंटरशी कनेक्ट केले नाही</translation>
 <translation id="2439152382014731627"><ph name="DEVICE_TYPE" /> पासवर्ड रीसेट करा</translation>
 <translation id="2439626940657133600"><ph name="WINDOW_TITLE" /> लोड करत आहे</translation>
@@ -2482,6 +2488,7 @@
 <translation id="2771816809568414714">चीज</translation>
 <translation id="2772936498786524345">Sneaky</translation>
 <translation id="2773288106548584039">लेगसी ब्राउझर सपोर्ट</translation>
+<translation id="2773621783913034737">टॅब इनॅक्टिव्ह करा</translation>
 <translation id="2773802008104670137">या प्रकारची फाइल तुमच्या कॉंप्युटरला हानी पोहोचवू शकते.</translation>
 <translation id="2775104091073479743">फिंगरप्रिंट संपादित करा</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{Extension "<ph name="EXTENSION" />" was accessing devices}=1{"<ph name="EXTENSION" />" हे एक्स्टेंशन {0} डिव्हाइस अ‍ॅक्सेस करत आहे}other{"<ph name="EXTENSION" />" हे एक्स्टेंशन {0} डिव्हाइस अ‍ॅक्सेस करत आहे}}</translation>
@@ -2562,6 +2569,7 @@
 <translation id="2830528677948328648">तुमचे Google खाते व्यवस्थापित करा</translation>
 <translation id="2831430281393059038">डिव्हाइसला सपोर्ट नाही</translation>
 <translation id="2832124733806557606">या डिव्हाइसवर साइन इन करण्यासाठी किंवा ते अनलॉक करण्यासाठी, तुमचे लहान मूल पिन वापरू शकते.</translation>
+<translation id="2833144527504272627">मजकूर कर्सरसह नेव्हिगेट करा</translation>
 <translation id="2835177225987815960">असाइन केलेले सर्व स्विच आणि ऑटो-स्कॅन वेगाशी संबंधित प्राधान्ये यांसह तुमचे सध्याचे स्कॅनिंग सेटअप रीसेट केले जाईल.</translation>
 <translation id="2835547721736623118">स्पीच रेकग्निशन सेवा</translation>
 <translation id="2835761321523638096">वाचा आणि वाचन सूचीमधील एंट्री बदला</translation>
@@ -2578,6 +2586,7 @@
 <translation id="2843698124892775282"><ph name="MEMORY_SAVINGS" /> मोकळी केली</translation>
 <translation id="2844169650293029770">USB-C डिव्‍हाइस (डाव्‍या बाजूचे पुढील पोर्ट)</translation>
 <translation id="2844809857160214557">प्रिंट कार्ये पहा आणि व्यवस्थापित करा</translation>
+<translation id="2845276301195220700">Google Calendar साठी आणखी कृती</translation>
 <translation id="2845382757467349449">नेहमी बुकमार्क बार दर्शवा</translation>
 <translation id="2845751331501453107">तुम्ही ब्राउझ करत असताना, तुम्ही पाहत असलेली जाहिरात पर्सनलाइझ केलेली आहे की नाही ते हे सेटिंग, <ph name="BEGIN_LINK1" />साइटने सुचवलेल्या जाहिराती<ph name="LINK_END1" />, तुमची <ph name="BEGIN_LINK2" />कुकी सेटिंग्ज<ph name="LINK_END2" /> आणि तुम्ही पाहत असलेली साइट जाहिराती पर्सनलाइझ करते की नाही त्यावर अवलंबून असते</translation>
 <translation id="284581348330507117">युनिक पासवर्ड तयार करा</translation>
@@ -3692,6 +3701,7 @@
 <translation id="3694590407685276748">मजकूर कर्सर हायलाइट करा</translation>
 <translation id="369489984217678710">पासवर्ड आणि इतर साइन इन डेटा</translation>
 <translation id="369522892592566391">{NUM_FILES,plural, =0{सुरक्षा तपासण्या पूर्ण झाल्या. तुमचा डेटा अपलोड केला जाईल.}=1{सुरक्षा तपासण्या पूर्ण झाल्या. तुमची फाइल अपलोड केली जाईल.}other{सुरक्षा तपासण्या पूर्ण झाल्या. तुमच्या फाइल अपलोड केल्या जातील.}}</translation>
+<translation id="3695339288331169103"><ph name="BEGIN_LINK" /><ph name="DISPLAY_REFERRER_URL" /><ph name="END_LINK" /> वरून</translation>
 <translation id="369736917241079046">launcher + लेफ्ट अ‍ॅरो</translation>
 <translation id="3697716475445175867">शेवटी उघडलेले</translation>
 <translation id="3697732362672163692">{NUM_SITES,plural, =1{तुम्ही या साइटला भविष्यातील सूचना पाठवण्यापासून थांबवू शकता.}other{तुम्ही या साइटना भविष्यातील सूचना पाठवण्यापासून थांबवू शकता.}}</translation>
@@ -4118,6 +4128,7 @@
 <translation id="3978325380690188371">ChromeVox सुरू असते, तेव्हा स्टिकी की उपलब्ध नसते</translation>
 <translation id="3979395879372752341">नवीन एक्स्टेंशन जोडले (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326"><ph name="NETWORKDEVICE" /> सुरू करा</translation>
+<translation id="398095528354975981">हे टॅब लपवा</translation>
 <translation id="3981058120448670012"><ph name="REMAINING_TIME" /> साठी <ph name="DEVICE_NAME" /> म्हणून जवळपासच्या डिव्हाइसना दृश्यमान...</translation>
 <translation id="3981760180856053153">अवैध सेव्ह प्रकार एंटर केले.</translation>
 <translation id="3982375475032951137">तुमचा ब्राउझर काही सोप्या पायऱ्यांमध्ये सेट करा</translation>
@@ -4990,6 +5001,7 @@
 <translation id="4650591383426000695">तुमचा फोन <ph name="DEVICE_TYPE" /> वरून डिस्कनेक्ट करा</translation>
 <translation id="4651484272688821107">डेमो मोड स्रोतांनी ऑनलाइन घटक लोड करता आला नाही.</translation>
 <translation id="4651921906638302153">हे खाते वापरून साइन इन करू शकत नाही</translation>
+<translation id="4652921642122345344">आवाजाचा वेग <ph name="RATE" />x</translation>
 <translation id="4652935475563630866">कॅमेऱ्याच्या सेटिंगमधील बदलासाठी Parallels Desktop पुन्हा लाँच करणे आवश्यक आहे. Parallels Desktop वर पुढे सुरू ठेवण्यासाठी पुन्हा लाँच करा.</translation>
 <translation id="4653116291358041820">लहान शॅडो</translation>
 <translation id="4653405415038586100">Linux कॉन्फिगर करताना एरर आली</translation>
@@ -5188,6 +5200,7 @@
 <translation id="4809927044794281115">फिकट थीम</translation>
 <translation id="4811212958317149293">स्विच अ‍ॅक्सेस कीबोर्ड ऑटो स्कॅन</translation>
 <translation id="4811503964269049987">निवडलेला टॅब एकत्रित करा</translation>
+<translation id="4812073856515324252"><ph name="APP_NAME" /> साठी तुमची पासकी कुठे सेव्ह करायची ते निवडा</translation>
 <translation id="4813512666221746211">नेटवर्क एरर</translation>
 <translation id="4814114628197290459">IBAN हटवा</translation>
 <translation id="4814327014588285482">वगळा आणि मला नंतर आठवण करून द्या</translation>
@@ -5655,6 +5668,7 @@
 <translation id="5160634252433617617">वास्तविक कीबोर्ड</translation>
 <translation id="5160857336552977725">आपल्या <ph name="DEVICE_TYPE" /> वर साइन इन करा</translation>
 <translation id="5161251470972801814"><ph name="VENDOR_NAME" /> कडील USB डिव्हाइस</translation>
+<translation id="5161442190864186925">मीटिंग मध्ये सामील व्हा</translation>
 <translation id="5161827038979306924">तुमचा Chrome मधील ब्राउझिंग इतिहास आणि तुमचा शोध इतिहास यात काय फरक आहे?</translation>
 <translation id="5162905305237671850"><ph name="DEVICE_TYPE" /> ला ब्लॉक केले आहे</translation>
 <translation id="5163910114647549394">टॅब टॅबस्ट्रिपच्या शेवटी हलवला आहे</translation>
@@ -6308,6 +6322,7 @@
 <translation id="5642508497713047">CRL स्वाक्षरीकर्ता</translation>
 <translation id="5643191124441701136">तुमचा सुरक्षा कोड तुमच्या कार्डच्या समोरील बाजूस आहे</translation>
 <translation id="5643321261065707929">मर्यादित नेटवर्क</translation>
+<translation id="5643717184207603910">परफॉर्मन्स जलद ठेवा</translation>
 <translation id="5646376287012673985">स्थान</translation>
 <translation id="5646558797914161501">व्यवसायी</translation>
 <translation id="5648021990716966815">माइक जॅक</translation>
@@ -6412,6 +6427,7 @@
 <translation id="5733109311583381874">रूपांतरण उमेदवार कस्टमाइझ करण्यासाठी तुमच्या वापरकर्ता शब्दकोशात तुमचे स्वत:चे शब्द जोडा.</translation>
 <translation id="5734362860645681824">संप्रेषणे</translation>
 <translation id="5734697361979786483">फाइल शेअर जोडा</translation>
+<translation id="5735513236153491131">आता बूस्ट करा</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{हा डेटा किंवा तुमचे डिव्हाइस हे तुमच्या संस्थेच्या काही सुरक्षा धोरणांची पूर्तता करत नाहीत. कशाचे निराकरण करण्याची आवश्यकता आहे हे तपासण्यासाठी तुमच्या ॲडमिनशी संपर्क साधा.}=1{ही फाइल किंवा तुमचे डिव्हाइस हे तुमच्या संस्थेच्या काही सुरक्षा धोरणांची पूर्तता करत नाहीत. कशाचे निराकरण करण्याची आवश्यकता आहे हे तपासण्यासाठी तुमच्या ॲडमिनशी संपर्क साधा.}other{या फाइल तुमच्या संस्थेच्या काही सुरक्षा धोरणांची पूर्तता करत नाहीत. कशाचे निराकरण करण्याची आवश्यकता आहे हे तपासण्यासाठी तुमच्या ॲडमिनशी संपर्क साधा.}}</translation>
 <translation id="5738093759615225354">तुम्हाला तुमच्या कॉंप्युटरवर साइन इन करण्यासाठी ही पासकी आवश्यक आहे</translation>
 <translation id="5739017626473506901"><ph name="USER_NAME" /> यांना शाळेच्या खात्यामध्ये जोडण्यात मदत करण्यासाठी साइन इन करा</translation>
@@ -7961,6 +7977,7 @@
 <translation id="6912007319859991306">मोबाइल सिम पिन</translation>
 <translation id="6912380255120084882">वेगळे डिव्हाइस वापरून पहा</translation>
 <translation id="691289340230098384">कॅप्शन प्राधान्ये</translation>
+<translation id="6913051485529944333">तुम्हाला या पेजवर Google Calendar पुन्हा दिसणार नाही</translation>
 <translation id="6914812290245989348">असुरक्षित साइटवर जाण्यापूर्वी कोणत्याही चेतावण्या पाहू नका</translation>
 <translation id="6916590542764765824">विस्तार व्यवस्थापित करा</translation>
 <translation id="6918677045355889289">ChromeOS अपडेट करणे आवश्यक आहे</translation>
@@ -8224,6 +8241,7 @@
 <translation id="7114054701490058191">पासवर्ड जुळत नाहीत</translation>
 <translation id="7114648273807173152">तुमच्या Google खात्यामध्ये साइन इन करण्यासाठी Smart Lock वापरण्याकरिता, सेटिंग्ज &gt; कनेक्ट केलेली डिव्हाइस &gt; तुमचा फोन &gt; Smart Lock वर जा.</translation>
 <translation id="7115361495406486998">कोणत्याही संपर्कांपर्यंत पोहोचू शकत नाही</translation>
+<translation id="7115731767122970828">आता बूस्ट करा</translation>
 <translation id="7116554090938189816">प्रिंटर SSL सर्टिफिकेट एक्स्पायर झाले आहे. प्रिंटर रीस्टार्ट करा आणि पुन्हा प्रयत्न करा.</translation>
 <translation id="7117228822971127758">कृपया नंतर पुन्हा प्रयत्न करा</translation>
 <translation id="7118268675952955085">स्क्रीनशॉट</translation>
@@ -8379,6 +8397,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (उत्कृष्‍ट)</translation>
 <translation id="7246230585855757313">तुमची सिक्युरिटी की पुन्हा घाला आणि पुन्हा प्रयत्न करा</translation>
 <translation id="724835896049478274">Android अ‍ॅप्ससाठी उपलब्ध खाती</translation>
+<translation id="7248802599439396696">टॅब इनॅक्टिव्ह करा</translation>
 <translation id="7249197363678284330">अ‍ॅड्रेस बारमध्ये हे सेटिंग बदला.</translation>
 <translation id="7249764475759804559">फाइल उघडताना या अ‍ॅपचा पर्याय म्हणून समावेश करा</translation>
 <translation id="7250616558727237648">तुम्ही ज्या डिव्हाइससह शेअर करत आहात त्याने प्रतिसाद दिला नाही. कृपया पुन्हा प्रयत्न करा.</translation>
@@ -9162,6 +9181,7 @@
 <translation id="7810202088502699111">या पेजवर पॉप-अप ब्लॉक केलेले होते.</translation>
 <translation id="7810367892333449285">तुमच्या एंट्रीचा फॉरमॅट <ph name="LPA_0" />$<ph name="LPA_1" />SM-DP+ address<ph name="LPA_2" />$<ph name="LPA_3" />optional matching id<ph name="LPA_4" /> असा असायला हवा</translation>
 <translation id="7811263553491007091">पुन्हा प्रयत्न करा किंवा पूर्वी जनरेट केलेल्या खालील थीमपैकी एखादी निवडा.</translation>
+<translation id="7812170317334653156">Google Calendar लपवलेले आहे</translation>
 <translation id="7814090115158024843">या साइटवर कधीही लिहिण्यासंबंधित मदत देऊ करू नका</translation>
 <translation id="7814458197256864873">&amp;कॉपी करा</translation>
 <translation id="7814857791038398352">Microsoft OneDrive</translation>
@@ -9220,6 +9240,7 @@
 <translation id="7853747251428735">अधिक साध&amp;ने</translation>
 <translation id="7853999103056713222">आणखी सुरक्षित पासवर्ड वापरा</translation>
 <translation id="7855678561139483478">टॅब नवीन विंडोवर हलवा</translation>
+<translation id="7856117067008941054">Google Calendar लपवा</translation>
 <translation id="7857004848504343806">तुमच्या कॉंप्युटरमध्ये सुरक्षित मॉड्युल आहे, जे ChromeOS Flex मध्ये अनेक महत्त्वाची सुरक्षा वैशिष्ट्ये लागू करण्यासाठी वापरले जाते. अधिक जाणून घेण्यासाठी Chromebook मदत केंद्र ला भेट द्या: https://support.google.com/chromebook/?p=sm</translation>
 <translation id="7857093393627376423">मजकुराबाबत सूचना</translation>
 <translation id="7858120906780498731">ChromeOS कनेक्ट केलेली इनपुट डिव्हाइस</translation>
@@ -9228,6 +9249,7 @@
 <translation id="786073089922909430">सेवा: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;डाउनलोड</translation>
 <translation id="7861846108263890455">Google खाते ची भाषा</translation>
+<translation id="7864114920800968141"><ph name="NUM_MIN" /> मिनिटामध्‍ये</translation>
 <translation id="7864539943188674973">Bluetooth अक्षम करा</translation>
 <translation id="7864825798076155402">तुमच्या Google खाते मध्ये सेव्ह करायचा आहे का?</translation>
 <translation id="7865127013871431856">भाषांतराचे पर्याय</translation>
@@ -9972,6 +9994,7 @@
 <translation id="8390392581097975659">स्कॅनर सॉफ्टवेअर इंस्टॉल करत आहे</translation>
 <translation id="8390449457866780408">सर्व्हर अनुपलब्ध.</translation>
 <translation id="8391218455464584335">व्हिनेल</translation>
+<translation id="8391918125842702622">परफॉर्मन्ससंबंधित समस्येची सूचना</translation>
 <translation id="8392726714909453725">बोलण्यासाठी निवडा सेटिंग्ज</translation>
 <translation id="8393511274964623038">प्लगइन थांबवा</translation>
 <translation id="839363317075970734">ब्लूटूथ डिव्‍हाइसचे तपशील</translation>
@@ -10072,6 +10095,7 @@
 <translation id="8466052016039127321">मागील सेशन पुन्हा सुरू करू शकत नाही</translation>
 <translation id="8467326454809944210">दुसरी भाषा निवडा</translation>
 <translation id="8468087214092422866">ब्लूटूथ डिव्हाइस शोधण्याची अनुमती नाही</translation>
+<translation id="8469863130477774813">परफॉर्मन्स बूस्ट उपलब्ध आहे</translation>
 <translation id="8470513973197838199"><ph name="ORIGIN" /> साठी सेव्ह केलेले पासवर्ड</translation>
 <translation id="8471525937465764768">दस्तऐवज प्रिंट करणे किंवा स्टोरेज डिव्हाइसमध्ये सेव्ह करणे यांसारख्या वैशिष्ट्यांसाठी साइट सामान्यपणे USB डिव्हाइसशी कनेक्ट करतात</translation>
 <translation id="8471959340398751476">सवलती बंद आहेत. तुम्ही कस्टमाइझ करा मेनूमधून त्या सुरू करू शकता</translation>
diff --git a/chrome/app/resources/generated_resources_ms.xtb b/chrome/app/resources/generated_resources_ms.xtb
index 9620264c7..a1f5e5f 100644
--- a/chrome/app/resources/generated_resources_ms.xtb
+++ b/chrome/app/resources/generated_resources_ms.xtb
@@ -409,6 +409,7 @@
 <translation id="1293556467332435079">Fail</translation>
 <translation id="1294807885394205587">Proses ini mungkin mengambil masa beberapa minit. Memulakan pengurus bekas.</translation>
 <translation id="12951065153783848">Organisasi anda mengurus akaun anda</translation>
+<translation id="1296410481664942178">Jangan paparkan Google Calendar</translation>
 <translation id="1296911687402551044">Sematkan Tab yang Dipilih</translation>
 <translation id="1297175357211070620">Destinasi</translation>
 <translation id="129770436432446029">Hantar maklum balas untuk <ph name="EXPERIMENT_NAME" /></translation>
@@ -447,6 +448,7 @@
 <translation id="1327495825214193325">Untuk mendayakan penyahpepijatan ADB, <ph name="DEVICE_TYPE" /> perlu dimulakan semula. Tindakan melumpuhkan ADB memerlukan tetapan semula kepada tetapan kilang.</translation>
 <translation id="1327527584824210101">Gunakan kunci laluan anda</translation>
 <translation id="1327794256477341646">Ciri yang memerlukan lokasi anda tidak akan berfungsi</translation>
+<translation id="1328364753167940710">Dalam <ph name="NUM_HR" /> jam</translation>
 <translation id="1329466763986822896">Tingkatkan privasi untuk tempat liputan ini</translation>
 <translation id="1331977651797684645">Ini saya.</translation>
 <translation id="1333489022424033687">Sesetengah ciri di <ph name="ORIGIN" /> mungkin tidak berfungsi sehingga anda mengosongkan data yang telah disimpan pada peranti anda oleh tapak lain itu</translation>
@@ -1005,6 +1007,7 @@
 <translation id="1709762881904163296">Tetapan Rangkaian</translation>
 <translation id="1709916727352927457">Padamkan kunci laluan</translation>
 <translation id="1709972045049031556">Tidak dapat berkongsi</translation>
+<translation id="1712143791363119140">Dalam Proses</translation>
 <translation id="1714644264617423774">Dayakan ciri kebolehaksesan untuk menjadikan peranti anda lebih mudah digunakan. <ph name="LINK_BEGIN" />Ketahui lebih lanjut<ph name="LINK_END" /></translation>
 <translation id="1716034099915639464">Padamkan data laman dan kebenaran untuk <ph name="SITE_NAME" /> dan apl yang dipasang laman tersebut?</translation>
 <translation id="171826447717908393">Apl web terpencil (beta)</translation>
@@ -1409,6 +1412,7 @@
 <translation id="200928901437634269">Gunakan Google Account atau akaun sekolah anak anda. Anda juga boleh menetapkan kawalan ibu bapa.</translation>
 <translation id="2009590708342941694">Alat Emoji</translation>
 <translation id="2010501376126504057">Peranti yang serasi</translation>
+<translation id="2010636492623189611">Dipilih.</translation>
 <translation id="201217432804812273">Hidupkan "Simpan Kumpulan"</translation>
 <translation id="2012935757369720523">Padamkan fail</translation>
 <translation id="2013550551806600826">Cubalah. Hidupkan atau matikan tetapan, kemudian tatal dengan dua jari pada pad sentuh anda di kawasan ujian. Anda juga boleh menemukan tetapan ini pada Tetapan &gt; Peranti &gt; Tetikus dan pad sentuh.</translation>
@@ -2004,6 +2008,7 @@
 <translation id="2435248616906486374">Rangkaian diputuskan</translation>
 <translation id="2435457462613246316">Paparkan kata laluan</translation>
 <translation id="2436385001956947090">Salin &amp;pautan</translation>
+<translation id="2437561292559037753">Perkongsian Data</translation>
 <translation id="2438853563451647815">Tidak disambungkan kepada pencetak</translation>
 <translation id="2439152382014731627">Tetapkan semula kata laluan <ph name="DEVICE_TYPE" /></translation>
 <translation id="2439626940657133600">Memuatkan <ph name="WINDOW_TITLE" /></translation>
@@ -2582,6 +2587,7 @@
 <translation id="2843698124892775282"><ph name="MEMORY_SAVINGS" /> Dikosongkan</translation>
 <translation id="2844169650293029770">Peranti USB-C (port depan sebelah kiri)</translation>
 <translation id="2844809857160214557">Lihat dan urus tugas cetak</translation>
+<translation id="2845276301195220700">Lagi tindakan untuk Google Calendar</translation>
 <translation id="2845382757467349449">Sentiasa Paparkan Bar Penanda Halaman</translation>
 <translation id="2845751331501453107">Semasa anda menyemak imbas, sama ada iklan yang anda lihat diperibadikan atau tidak adalah bergantung pada tetapan ini, <ph name="BEGIN_LINK1" />Iklan yang dicadangkan laman<ph name="LINK_END1" />, <ph name="BEGIN_LINK2" />tetapan kuki<ph name="LINK_END2" /> anda dan sama ada laman yang anda lihat memeribadikan iklan atau tidak</translation>
 <translation id="284581348330507117">Buat kata laluan yang unik</translation>
@@ -3696,6 +3702,7 @@
 <translation id="3694590407685276748">Serlahkan kursor teks</translation>
 <translation id="369489984217678710">Kata laluan dan data log masuk yang lain</translation>
 <translation id="369522892592566391">{NUM_FILES,plural, =0{Semakan keselamatan sudah selesai. Data anda akan dimuat naik.}=1{Semakan keselamatan sudah selesai. Fail anda akan dimuat naik.}other{Semakan keselamatan sudah selesai. Fail anda akan dimuat naik.}}</translation>
+<translation id="3695339288331169103">Daripada <ph name="BEGIN_LINK" /><ph name="DISPLAY_REFERRER_URL" /><ph name="END_LINK" /></translation>
 <translation id="369736917241079046">pelancar + anak panah ke kiri</translation>
 <translation id="3697716475445175867">terakhir dibuka</translation>
 <translation id="3697732362672163692">{NUM_SITES,plural, =1{Anda boleh menghentikan laman ini daripada menghantar pemberitahuan masa hadapan.}other{Anda boleh menghentikan laman ini daripada menghantar pemberitahuan masa hadapan.}}</translation>
@@ -4997,6 +5004,7 @@
 <translation id="4650591383426000695">Putuskan sambungan telefon anda daripada <ph name="DEVICE_TYPE" /></translation>
 <translation id="4651484272688821107">Tidak dapat memuatkan komponen dalam talian dengan sumber mod tunjuk cara.</translation>
 <translation id="4651921906638302153">Tidak dapat log masuk dengan akaun ini</translation>
+<translation id="4652921642122345344">Kelajuan suara <ph name="RATE" />x</translation>
 <translation id="4652935475563630866">Perubahan dalam tetapan kamera memerlukan Desktop Parallels dilancarkan semula. Lancarkan semula Desktop Parallels untuk meneruskan.</translation>
 <translation id="4653116291358041820">Bebayang kecil</translation>
 <translation id="4653405415038586100">Ralat semasa mengkonfigurasi Linux</translation>
@@ -5195,6 +5203,7 @@
 <translation id="4809927044794281115">Tema cerah</translation>
 <translation id="4811212958317149293">Autoimbas papan kekunci akses suis</translation>
 <translation id="4811503964269049987">Tab Pilihan Kumpulan</translation>
+<translation id="4812073856515324252">Pilih tempat untuk menyimpan kunci laluan bagi <ph name="APP_NAME" /></translation>
 <translation id="4813512666221746211">Ralat rangkaian</translation>
 <translation id="4814114628197290459">Padamkan IBAN</translation>
 <translation id="4814327014588285482">Langkau dan ingatkan saya kemudian</translation>
@@ -5662,6 +5671,7 @@
 <translation id="5160634252433617617">Papan kekunci fizikal</translation>
 <translation id="5160857336552977725">Log masuk ke <ph name="DEVICE_TYPE" /> anda</translation>
 <translation id="5161251470972801814">Peranti USB daripada <ph name="VENDOR_NAME" /></translation>
+<translation id="5161442190864186925">Sertai Mesyuarat</translation>
 <translation id="5161827038979306924">Apakah perbezaan antara sejarah penyemakan imbas anda dalam Chrome dengan sejarah carian anda?</translation>
 <translation id="5162905305237671850"><ph name="DEVICE_TYPE" /> telah disekat</translation>
 <translation id="5163910114647549394">Tab dialihkan ke bahagian hujung jalur tab</translation>
@@ -7969,6 +7979,7 @@
 <translation id="6912007319859991306">PIN SIM Selular</translation>
 <translation id="6912380255120084882">Cuba peranti yang berbeza</translation>
 <translation id="691289340230098384">Pilihan kapsyen</translation>
+<translation id="6913051485529944333">Anda tidak akan melihat Google Calendar pada halaman ini lagi</translation>
 <translation id="6914812290245989348">Tidak memberikan sebarang amaran sebelum mengakses laman yang tidak selamat</translation>
 <translation id="6916590542764765824">Urus Sambungan</translation>
 <translation id="6918677045355889289">Kemaskinian Chrome OS diperlukan</translation>
@@ -9174,6 +9185,7 @@
 <translation id="7810202088502699111">Pop muncul disekat pada halaman ini.</translation>
 <translation id="7810367892333449285">Masukan anda sepatutnya mengandungi format <ph name="LPA_0" />$<ph name="LPA_1" />alamat SM-DP+<ph name="LPA_2" />$<ph name="LPA_3" />ID padanan pilihan<ph name="LPA_4" /></translation>
 <translation id="7811263553491007091">Cuba lagi atau pilih salah satu daripada tema yang dijana sebelum ini di bawah.</translation>
+<translation id="7812170317334653156">Google Calendar disembunyikan</translation>
 <translation id="7814090115158024843">Jangan sekali-kali menawarkan bantuan penulisan pada laman ini</translation>
 <translation id="7814458197256864873">&amp;Salin</translation>
 <translation id="7814857791038398352">Microsoft® OneDrive</translation>
@@ -9232,6 +9244,7 @@
 <translation id="7853747251428735">Lagi Al&amp;atan</translation>
 <translation id="7853999103056713222">Gunakan Kata Laluan yang Lebih Selamat</translation>
 <translation id="7855678561139483478">Alihkan tab ke tetingkap baharu</translation>
+<translation id="7856117067008941054">Sembunyikan Google Calendar</translation>
 <translation id="7857004848504343806">Komputer anda mengandungi modul selamat, yang digunakan untuk melaksanakan banyak ciri keselamatan penting dalam Chrome OS Flex. Lawati Pusat Bantuan Chromebook untuk mengetahui lebih lanjut: https://support.google.com/chromebook/?p=sm</translation>
 <translation id="7857093393627376423">Cadangan teks</translation>
 <translation id="7858120906780498731">Peranti Input ChromeOS yang Disambungkan</translation>
@@ -9240,6 +9253,7 @@
 <translation id="786073089922909430">Perkhidmatan: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;Muat turun</translation>
 <translation id="7861846108263890455">Bahasa Google Account</translation>
+<translation id="7864114920800968141">Dalam <ph name="NUM_MIN" /> minit</translation>
 <translation id="7864539943188674973">Lumpuhkan Bluetooth</translation>
 <translation id="7864825798076155402">Simpan dalam Google Account anda?</translation>
 <translation id="7865127013871431856">Pilihan Translate</translation>
diff --git a/chrome/app/resources/generated_resources_my.xtb b/chrome/app/resources/generated_resources_my.xtb
index 4701a56..738d676 100644
--- a/chrome/app/resources/generated_resources_my.xtb
+++ b/chrome/app/resources/generated_resources_my.xtb
@@ -972,6 +972,7 @@
 <translation id="1697150536837697295">အနုပညာ</translation>
 <translation id="1697686431566694143">ဖိုင်တည်းဖြတ်ရန်</translation>
 <translation id="1698796500103229697">&amp;ငွေပေးချေနည်းလမ်းများ</translation>
+<translation id="1698899521169711967">Caret ဖြင့် ဖွင့်ကြည့်ခြင်း</translation>
 <translation id="1699807488537653303">စကားဝှက်အမှား ပြင်ဆင်ပါ</translation>
 <translation id="1700201317341192482">သင်၏ပကတိအသွင်ကတ် ဖယ်ရှားရန်</translation>
 <translation id="1700517974991662022">ဝင်ကြည့်ခဲ့သည်</translation>
@@ -2481,6 +2482,7 @@
 <translation id="2771816809568414714">ဒိန်ခဲ</translation>
 <translation id="2772936498786524345">အတို့ထောင်လုပ်ခြင်း</translation>
 <translation id="2773288106548584039">ဝဘ်ဆိုက်အဟောင်း ဖွင့်ရန် အကူအညီ</translation>
+<translation id="2773621783913034737">တဘ်များကို ပိတ်ရန်</translation>
 <translation id="2773802008104670137">ဤဖိုင်အမျိုးအစားသည် သင့်ကွန်ပျူတာကို ပျက်စီးစေနိုင်ပါသည်။</translation>
 <translation id="2775104091073479743">လက်ဗွေများကို တည်းဖြတ်ရန်</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{“<ph name="EXTENSION" />” နောက်ဆက်တွဲသည် စက်များကို သုံးထားသည်}=1{“<ph name="EXTENSION" />” နောက်ဆက်တွဲသည် စက် {0} ခုကို သုံးနေသည်}other{“<ph name="EXTENSION" />” နောက်ဆက်တွဲသည် စက် {0} ခုကို သုံးနေသည်}}</translation>
@@ -2562,6 +2564,7 @@
 <translation id="2830528677948328648">သင့် &amp;Google အကောင့်ကို စီမံရန်</translation>
 <translation id="2831430281393059038">စက်ကို ပံ့ပိုးထားသည်</translation>
 <translation id="2832124733806557606">သင့်ကလေးသည် ဤစက်သို့ လက်မှတ်ထိုးဝင်ရန် (သို့) ဖွင့်ရန် ပင်နံပါတ် သုံးနိုင်သည်။</translation>
+<translation id="2833144527504272627">စာသားကာဆာဖြင့် ရွှေ့ရန်</translation>
 <translation id="2835177225987815960">သတ်မှတ်ထားသော အသွင်တူခလုတ်များနှင့် အလိုအလျောက် ရှာဖွေသည့် အမြန်နှုန်း စိတ်ကြိုက်ရွေးချယ်မှုများ အပါအဝင် သင်လက်ရှိ ရှာဖွေနေသော စနစ်ထည့်သွင်းမှုကို ပြင်ဆင်သတ်မှတ်ပါမည်။</translation>
 <translation id="2835547721736623118">စကားသံ အသိအမှတ်ပြုခြင်း ဝန်ဆောင်မှု</translation>
 <translation id="2835761321523638096">ဖတ်ရန်စာရင်းတွင် ထည့်သွင်းမှုများကို ဖတ်ပြီးပြောင်းပါ</translation>
@@ -4117,6 +4120,7 @@
 <translation id="3978325380690188371">ChromeVox ဖွင့်ထားစဉ် ကပ်ခွာကီးများ မရနိုင်ပါ</translation>
 <translation id="3979395879372752341">အိတ်စတန်းရှင်း အသစ် ထပ်ထည့်ပြီး (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326"><ph name="NETWORKDEVICE" /> ကို ဖွင့်ထားရန်</translation>
+<translation id="398095528354975981">ဤတဘ်များကို ဖျောက်ထားရန်</translation>
 <translation id="3981058120448670012">အနီးရှိစက်များက <ph name="DEVICE_NAME" /> အဖြစ် <ph name="REMAINING_TIME" /> ကြာ မြင်နိုင်သည်...</translation>
 <translation id="3981760180856053153">ဝင်ခဲ့သည့် သိမ်းဆည်းမှု ပုံစံ မမှန်ပါ။</translation>
 <translation id="3982375475032951137">ရိုးရှင်းသည့်အဆင့်အနည်းငယ် ပြုလုပ်ရုံဖြင့် သင်၏ဘရောင်ဇာကို စနစ်ထည့်သွင်းပါ</translation>
@@ -6310,6 +6314,7 @@
 <translation id="5642508497713047">CRL လက်မှတ်ထိုးသူ</translation>
 <translation id="5643191124441701136">သင့်ကတ်ရှေ့ခြမ်းတွင် လုံခြုံရေးကုဒ်ရှိသည်</translation>
 <translation id="5643321261065707929">အခမဲ့မဟုတ်သော ကွန်ရက်</translation>
+<translation id="5643717184207603910">စွမ်းဆောင်ရည် မြန်ဆန်စေခြင်း</translation>
 <translation id="5646376287012673985">တည်နေရာ</translation>
 <translation id="5646558797914161501">စီးပွားရေးလုပ်ငန်းရှင်</translation>
 <translation id="5648021990716966815">မိုက်ခရိုဖုန်း ဂျက်ပင်</translation>
@@ -6414,6 +6419,7 @@
 <translation id="5733109311583381874">သင့်လျော်သည့် ရလဒ်ကောင်းများကို စိတ်ကြိုက်ပြင်ဆင်ရန်အတွက် အသုံးပြုသူအဘိဓာန်များသို့ ကိုယ်ပိုင်စကားလုံးထည့်ရန်။</translation>
 <translation id="5734362860645681824">ဆက်သွယ်မှုများ</translation>
 <translation id="5734697361979786483">ဖိုင်မျှဝေမှုကို ထည့်ရန်</translation>
+<translation id="5735513236153491131">ယခု မြှင့်တင်ရန်</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{ဤဒေတာ (သို့) စက်သည် သင့်အဖွဲ့အစည်း၏ လုံခြုံရေးမူဝါဒအချို့နှင့် မကိုက်ညီပါ။ ပြုပြင်ရန်လိုအပ်သည်များကို သင့်စီမံခန့်ခွဲသူနှင့် စစ်ဆေးပါ။}=1{ဤဖိုင် (သို့) စက်သည် သင့်အဖွဲ့အစည်း၏ လုံခြုံရေးမူဝါဒအချို့နှင့် မကိုက်ညီပါ။ ပြုပြင်ရန်လိုအပ်သည်များကို သင့်စီမံခန့်ခွဲသူနှင့် စစ်ဆေးပါ။}other{ဤဖိုင်များသည် သင့်အဖွဲ့အစည်း၏ လုံခြုံရေးမူဝါဒအချို့နှင့် မကိုက်ညီပါ။ ပြုပြင်ရန်လိုအပ်သည်များကို သင့်စီမံခန့်ခွဲသူနှင့် စစ်ဆေးပါ။}}</translation>
 <translation id="5738093759615225354">သင့်ကွန်ပျူတာသို့ လက်မှတ်ထိုးဝင်ရန် ဤလျှို့ဝှက်ကီး လိုအပ်သည်</translation>
 <translation id="5739017626473506901"><ph name="USER_NAME" /> ကျောင်းအကောင့်ထည့်ရာတွင် ကူညီရန် လက်မှတ်ထိုးဝင်ပါ</translation>
@@ -8221,6 +8227,7 @@
 <translation id="7114054701490058191">စကားဝှက်များ မတူပါ</translation>
 <translation id="7114648273807173152">သင့် Google အကောင့်သို့ လက်မှတ်ထိုးဝင်ရာတွင် Smart Lock သုံးရန် 'ဆက်တင်များ &gt; ချိတ်ဆက်ထားသော ကိရိယာများ &gt; သင်၏ဖုန်း &gt; Smart Lock' သို့ သွားပါ။</translation>
 <translation id="7115361495406486998">ဆက်သွယ်နိုင်သော အဆက်အသွယ်များ မရှိပါ</translation>
+<translation id="7115731767122970828">ယခု မြှင့်တင်ရန်</translation>
 <translation id="7116554090938189816">ပရင်တာ SSL အသိအမှတ်ပြုလက်မှတ် သက်တမ်းကုန်သွားပြီ။ ပရင်တာကို ပြန်စပြီး ထပ်စမ်းကြည့်ပါ။</translation>
 <translation id="7117228822971127758">နောက်မှ ထပ်စမ်းကြည့်ပါ</translation>
 <translation id="7118268675952955085">ဖန်သားပြင်ဓာတ်ပုံ</translation>
@@ -8376,6 +8383,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (အကောင်းဆုံး)</translation>
 <translation id="7246230585855757313">သင့်လုံခြုံရေးကီးကို ပြန်ထည့်ပြီး ထပ်စမ်းကြည့်ပါ</translation>
 <translation id="724835896049478274">Android အက်ပ်များအတွက် ရနိုင်သော အကောင့်များ</translation>
+<translation id="7248802599439396696">တဘ်များကို ပိတ်ရန်</translation>
 <translation id="7249197363678284330">လိပ်စာ ဘားတွင် ဤဆက်တင်ကို ပြောင်းနိုင်သည်။</translation>
 <translation id="7249764475759804559">ဖိုင်များဖွင့်သောအခါ ရွေးစရာအဖြစ် ဤအက်ပ်ကိုထည့်ရန်</translation>
 <translation id="7250616558727237648">သင်မျှဝေနေသော ကိရိယာက တုံ့ပြန်ခြင်းမရှိပါ။ ထပ်စမ်းကြည့်ပါ။</translation>
@@ -9970,6 +9978,7 @@
 <translation id="8390392581097975659">စကင်ဖတ်စနစ်ဆော့ဖ်ဝဲ ထည့်သွင်းနေသည်</translation>
 <translation id="8390449457866780408">ဆာဗာ မရရှိနိုင်ပါ။</translation>
 <translation id="8391218455464584335">ဗီနိုင်း</translation>
+<translation id="8391918125842702622">စွမ်းဆောင်ရည်ပြဿနာ သတိပေးချက်</translation>
 <translation id="8392726714909453725">စကားပြော ရွေးရန် ဆက်တင်များ</translation>
 <translation id="8393511274964623038">ပလတ်အင် ရပ်ရန်</translation>
 <translation id="839363317075970734">ဘလူးတုသ်သုံးစက် အသေးစိတ်</translation>
@@ -10070,6 +10079,7 @@
 <translation id="8466052016039127321">ယခင်စက်ရှင်ကို ဆက်လုပ်၍မရပါ</translation>
 <translation id="8467326454809944210">အခြားဘာသာစကားတစ်ခု ရွေးရန်</translation>
 <translation id="8468087214092422866">ဘလူးတုသ်သုံးစက်များ ရှာရန် ခွင့်ပြုမထားပါ</translation>
+<translation id="8469863130477774813">စွမ်းဆောင်ရည် မြှင့်တင်နိုင်သည်</translation>
 <translation id="8470513973197838199"><ph name="ORIGIN" /> အတွက် သိမ်းဆည်းထားသည့် စကားဝှက်များ</translation>
 <translation id="8471525937465764768">မှတ်တမ်းဖိုင်ပုံနှိပ်ထုတ်ရန် သို့မဟုတ် သိုလှောင်ခန်းကိရိယာတွင် သိမ်းရန်ကဲ့သို့ ဝန်ဆောင်မှုများအတွက် USB ကိရိယာများသို့ ဝဘ်ဆိုက်များက ချိတ်ဆက်လေ့ရှိသည်</translation>
 <translation id="8471959340398751476">လျှော့ဈေးများကို ပိတ်ထားသည်။ မီနူးစိတ်ကြိုက်ပြင်သည့် နေရာတွင် ၎င်းတို့ကို ပြန်ဖွင့်နိုင်သည်</translation>
diff --git a/chrome/app/resources/generated_resources_ne.xtb b/chrome/app/resources/generated_resources_ne.xtb
index 33e8ccd..2a1329043 100644
--- a/chrome/app/resources/generated_resources_ne.xtb
+++ b/chrome/app/resources/generated_resources_ne.xtb
@@ -971,6 +971,7 @@
 <translation id="1697150536837697295">कला</translation>
 <translation id="1697686431566694143">फाइल सम्पादन गर्नुहोस्</translation>
 <translation id="1698796500103229697">भुक्तानी विधिहरू</translation>
+<translation id="1698899521169711967">क्यारेट ब्राउजिङ</translation>
 <translation id="1699807488537653303">पासवर्डसम्बन्धी त्रुटि सच्याउनुहोस्</translation>
 <translation id="1700201317341192482">आफ्नो भर्चुअल कार्ड हटाउनुहोस्</translation>
 <translation id="1700517974991662022">भ्रमण गरियो</translation>
@@ -2472,6 +2473,7 @@
 <translation id="2771816809568414714">चिज</translation>
 <translation id="2772936498786524345">गुप्त</translation>
 <translation id="2773288106548584039">लिगेसी ब्राउजरको समर्थन</translation>
+<translation id="2773621783913034737">ट्याबहरू निष्क्रिय बनाउनुहोस्</translation>
 <translation id="2773802008104670137">यस प्रकारको फाइलले तपाइँको कम्प्युटरलाई हानि गर्न सक्छ।</translation>
 <translation id="2775104091073479743">फिंगरप्रिन्टहरू सम्पादन गर्नुहोस्</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{"<ph name="EXTENSION" />" एक्स्टेन्सनले डिभाइसहरू एक्सेस गरिरहेको थियो}=1{"<ph name="EXTENSION" />" एक्स्टेन्सनले {0} वटा डिभाइस एक्सेस गरिरहेको छ}other{"<ph name="EXTENSION" />" एक्स्टेन्सनले {0} वटा डिभाइसहरू एक्सेस गरिरहेको छ}}</translation>
@@ -2552,6 +2554,7 @@
 <translation id="2830528677948328648">आफ्नो Google खाता व्यवस्थापन गर्नुहोस्</translation>
 <translation id="2831430281393059038">डिभाइस प्रयोग गर्न मिल्ने हुनु पर्छ</translation>
 <translation id="2832124733806557606">तपाईंका बच्चा PIN प्रयोग गरेर यो डिभाइस अनलक गर्न वा यसमा साइन इन गर्न सक्छन्।</translation>
+<translation id="2833144527504272627">टेक्स्ट कर्सर प्रयोग गरी नेभिगेट गर्नुहोस्</translation>
 <translation id="2835177225987815960">तपाईंले स्क्यान गर्नका निम्ति तय गरेको हालको सेटअप रिसेट हुने छ। साथै, तोकिएका स्विच तथा अटो-स्क्यानको गतिसम्बन्धी प्राथमिकताहरू पनि रिसेट हुने छन्।</translation>
 <translation id="2835547721736623118">वाक् पहिचान सेवा</translation>
 <translation id="2835761321523638096">पछि पढ्न सेभ गरिएका वेबपेजको सूचीमा भएका इन्ट्रीहरू रिड गर्ने तथा बदल्ने अनुमति</translation>
@@ -4108,6 +4111,7 @@
 <translation id="3978325380690188371">ChromeVox अन भएका बेला स्टिकी कीहरू उपलब्ध हुँदैनन्</translation>
 <translation id="3979395879372752341">नयाँ विस्तार थिपियो (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326"><ph name="NETWORKDEVICE" /> लाई सक्षम बनाउनुहोस्</translation>
+<translation id="398095528354975981">यी ट्याबहरू लुकाउनुहोस्</translation>
 <translation id="3981058120448670012"><ph name="REMAINING_TIME" /> सम्म नजिकैका यन्त्रहरूमा <ph name="DEVICE_NAME" /> का रूपमा देखिने...</translation>
 <translation id="3981760180856053153">अवैध बचत प्रकार प्रविष्ट भयो।</translation>
 <translation id="3982375475032951137">केही सरल चरणमार्फत आफ्नो ब्राउजर सेटअप गर्नुहोस्</translation>
@@ -6303,6 +6307,7 @@
 <translation id="5642508497713047">CRL हस्ताक्षरकर्ता</translation>
 <translation id="5643191124441701136">तपाईंको सुरक्षा कोड तपाईंको कार्डको अगाडिको भागमा हुन्छ</translation>
 <translation id="5643321261065707929">सीमा तोकिएको नेटवर्क</translation>
+<translation id="5643717184207603910">पर्फर्मेन्स अझ छिटो बनाइराख्नुहोस्</translation>
 <translation id="5646376287012673985">लोकेसन</translation>
 <translation id="5646558797914161501">व्यापारी</translation>
 <translation id="5648021990716966815">माइकको ज्याक</translation>
@@ -6407,6 +6412,7 @@
 <translation id="5733109311583381874">रूपान्तरण गर्नु पर्ने शब्दहरू कस्टमाइज गर्न प्रयोगकर्ताका शब्दकोशमा आफ्नै शब्दहरू हाल्नुहोस्।</translation>
 <translation id="5734362860645681824">सञ्चारहरू</translation>
 <translation id="5734697361979786483">फाइल आदान प्रदान गर्ने सुविधा थप्नुहोस्</translation>
+<translation id="5735513236153491131">अहिले नै बुस्ट गर्नुहोस्</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{यो डेटा वा तपाईंको डिभाइसले तपाईंको सङ्गठनका सुरक्षासम्बन्धी केही नीतिहरूको पालना गरेको छैन। आफ्ना एड्मिनलाई सम्पर्क गरेर कुन कुन समस्या समाधान गर्नु पर्छ भन्ने कुरा थाहा पाउनुहोस्।}=1{यो फाइल वा तपाईंको डिभाइसले तपाईंको सङ्गठनका सुरक्षासम्बन्धी केही नीतिहरूको पालना गरेको छैन। आफ्ना एड्मिनलाई सम्पर्क गरेर कुन कुन समस्या समाधान गर्नु पर्छ भन्ने कुरा थाहा पाउनुहोस्।}other{यी फाइलहरूले तपाईंको सङ्गठनका सुरक्षासम्बन्धी केही नीतिहरूको पालना गरेका छैनन्। आफ्ना एड्मिनलाई सम्पर्क गरेर कुन कुन समस्या समाधान गर्नु पर्छ भन्ने कुरा थाहा पाउनुहोस्।}}</translation>
 <translation id="5738093759615225354">तपाईंसँग यो पासकी छ भने मात्र तपाईं आफ्नो कम्प्युटरमा साइन इन गर्न सक्नुहुन्छ</translation>
 <translation id="5739017626473506901"><ph name="USER_NAME" /> लाई विद्यालयको खाता थप्न मद्दत गर्न साइन इन गर्नुहोस्</translation>
@@ -8217,6 +8223,7 @@
 <translation id="7114054701490058191">पासवर्ड मिलेन</translation>
 <translation id="7114648273807173152">आफ्नो Google खातामा साइन इन गर्नका निम्ति Smart Lock को प्रयोग गर्न सेटिङहरू &gt; कनेक्ट गरिएका डिभाइस &gt; तपाईंको फोन &gt; Smart Lock मा जानुहोस्।</translation>
 <translation id="7115361495406486998">कन्ट्याक्टमा Google खाता भएका कोही पनि हुनुहुन्न</translation>
+<translation id="7115731767122970828">अहिले नै बुस्ट गर्नुहोस्</translation>
 <translation id="7116554090938189816">प्रिन्टरको SSL प्रमाणपत्रको म्याद सकिएको छ। प्रिन्टर रिस्टार्ट गरेर फेरि प्रयास गर्नुहोस्।</translation>
 <translation id="7117228822971127758">कृपया पछि फेरि प्रयास गर्नुहोस्</translation>
 <translation id="7118268675952955085">स्क्रिनसट</translation>
@@ -8372,6 +8379,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> गुणा <ph name="HEIGHT" /> (उत्कृष्ट)</translation>
 <translation id="7246230585855757313">आफ्नो सुरक्षा साँचो पुनः प्रविष्टि गरी फेरि प्रयास गर्नुहोस्</translation>
 <translation id="724835896049478274">Android एपहरूका लागि उपलब्ध खाताहरू</translation>
+<translation id="7248802599439396696">ट्याबहरू निष्क्रिय बनाउनुहोस्</translation>
 <translation id="7249197363678284330">एड्रेस बारमा गई यो सेटिङ बदल्नुहोस्।</translation>
 <translation id="7249764475759804559">फाइलहरू खोल्दा यो एप विकल्पका रूपमा समावेश गर्नुहोस्</translation>
 <translation id="7250616558727237648">तपाईंले जुन यन्त्रसँग यो फाइल सेयर गर्न चाहनुहुन्छ उक्त यन्त्रबाट कुनै प्रतिक्रिया प्राप्त भएन। कृपया फेरि प्रयास गर्नुहोस्।</translation>
@@ -9969,6 +9977,7 @@
 <translation id="8390392581097975659">स्क्यानर सफ्टवेयर इन्स्टल गरिँदै छ</translation>
 <translation id="8390449457866780408">सर्भर उपलब्ध छैन।</translation>
 <translation id="8391218455464584335">भाइनल</translation>
+<translation id="8391918125842702622">पर्फर्मेन्समा देखिएको समस्यासम्बन्धी अलर्ट</translation>
 <translation id="8392726714909453725">सेलेक्ट टु स्पिकसम्बन्धी सेटिङ</translation>
 <translation id="8393511274964623038">प्लगइनलाई रोक्नुहोस्</translation>
 <translation id="839363317075970734">ब्लुटुथ डिभाइससम्बन्धी विवरण</translation>
@@ -10069,6 +10078,7 @@
 <translation id="8466052016039127321">अघिल्लो सत्र सुचारु गर्न मिल्दैन</translation>
 <translation id="8467326454809944210">अर्को भाषा छनौट गर्नुहोस्</translation>
 <translation id="8468087214092422866">ब्लुटुथ डिभाइसहरू खोज्ने अनुमति नदिइएका साइटहरू</translation>
+<translation id="8469863130477774813">तपाईं पर्फर्मेन्स बुस्ट गर्न सक्नुहुन्छ</translation>
 <translation id="8470513973197838199"><ph name="ORIGIN" /> का सुरक्षित गरिएका पासवर्डहरू</translation>
 <translation id="8471525937465764768">साइटहरूले डकुमेन्ट प्रिन्ट गर्ने वा भण्डारण यन्त्रमा सुरक्षित गर्ने जस्ता सुविधाहरू प्रदान गर्न सामान्यतया USB मा कनेक्ट गर्छन्।</translation>
 <translation id="8471959340398751476">छुटसम्बन्धी जानकारी प्राप्त गर्ने सुविधा अफ गरिएको छ। तपाईं 'आफूले चाहेको जस्तो बनाउनुहोस्' नामक मेनुमा गएर यो सुविधा अन गर्न सक्नुहुन्छ</translation>
diff --git a/chrome/app/resources/generated_resources_nl.xtb b/chrome/app/resources/generated_resources_nl.xtb
index 1eee894..fe33930 100644
--- a/chrome/app/resources/generated_resources_nl.xtb
+++ b/chrome/app/resources/generated_resources_nl.xtb
@@ -409,6 +409,7 @@
 <translation id="1293556467332435079">Bestanden</translation>
 <translation id="1294807885394205587">Dit kan een paar minuten duren. Containerbeheer wordt gestart.</translation>
 <translation id="12951065153783848">Je organisatie beheert je account</translation>
+<translation id="1296410481664942178">Google Agenda niet tonen</translation>
 <translation id="1296911687402551044">Geselecteerd tabblad vastzetten</translation>
 <translation id="1297175357211070620">Bestemming</translation>
 <translation id="129770436432446029">Feedback sturen voor <ph name="EXPERIMENT_NAME" /></translation>
@@ -447,6 +448,7 @@
 <translation id="1327495825214193325">Als je ADB-foutopsporing wilt aanzetten, moet je deze <ph name="DEVICE_TYPE" /> opnieuw opstarten. Je kunt ADB-foutopsporing alleen uitzetten door de fabrieksinstellingen van je apparaat te herstellen.</translation>
 <translation id="1327527584824210101">Je toegangssleutel gebruiken</translation>
 <translation id="1327794256477341646">Functies waarvoor je locatie nodig is, werken niet</translation>
+<translation id="1328364753167940710">Over <ph name="NUM_HR" /> u</translation>
 <translation id="1329466763986822896">De privacy voor deze hotspot verbeteren</translation>
 <translation id="1331977651797684645">Dit was ik.</translation>
 <translation id="1333489022424033687">Sommige functies op <ph name="ORIGIN" /> werken mogelijk pas als je gegevens wist die andere sites op je apparaat hebben opgeslagen</translation>
@@ -996,6 +998,7 @@
 <translation id="1709762881904163296">Netwerkinstellingen</translation>
 <translation id="1709916727352927457">Toegangscode verwijderen</translation>
 <translation id="1709972045049031556">Kan niet delen</translation>
+<translation id="1712143791363119140">Bezig</translation>
 <translation id="1714644264617423774">Zet toegankelijkheidsfuncties aan om je apparaat gebruiksvriendelijker te maken. <ph name="LINK_BEGIN" />Meer informatie<ph name="LINK_END" /></translation>
 <translation id="1716034099915639464">Sitegegevens en rechten verwijderen voor <ph name="SITE_NAME" /> en de geïnstalleerde app?</translation>
 <translation id="171826447717908393">Geïsoleerde web-apps (bèta)</translation>
@@ -1399,6 +1402,7 @@
 <translation id="200928901437634269">Gebruik het Google-account van je kind of een schoolaccount. Je kunt ook ouderlijk toezicht instellen.</translation>
 <translation id="2009590708342941694">Tool Emoji</translation>
 <translation id="2010501376126504057">Geschikte apparaten</translation>
+<translation id="2010636492623189611">Geselecteerd.</translation>
 <translation id="201217432804812273">'Groep opslaan' aanzetten</translation>
 <translation id="2012935757369720523">Bestand verwijderen</translation>
 <translation id="2013550551806600826">Probeer het uit. Zet de instelling aan of uit en scroll met 2 vingers op je touchpad in het testgebied. Je kunt deze optie ook later vinden via Instellingen &gt; Apparaat &gt; Muis en touchpad.</translation>
@@ -1991,6 +1995,7 @@
 <translation id="2435248616906486374">Geen verbinding met netwerk</translation>
 <translation id="2435457462613246316">Wachtwoord bekijken</translation>
 <translation id="2436385001956947090">&amp;Link kopiëren</translation>
+<translation id="2437561292559037753">Gegevens delen</translation>
 <translation id="2438853563451647815">Niet verbonden met printer</translation>
 <translation id="2439152382014731627"><ph name="DEVICE_TYPE" />-wachtwoord resetten</translation>
 <translation id="2439626940657133600"><ph name="WINDOW_TITLE" /> laden</translation>
@@ -2569,6 +2574,7 @@
 <translation id="2843698124892775282"><ph name="MEMORY_SAVINGS" /> vrijgemaakt</translation>
 <translation id="2844169650293029770">USB-C-apparaat (poort links aan de voorkant)</translation>
 <translation id="2844809857160214557">Afdruktaken bekijken en beheren</translation>
+<translation id="2845276301195220700">Meer acties voor Google Agenda</translation>
 <translation id="2845382757467349449">Bookmarkbalk altijd tonen</translation>
 <translation id="2845751331501453107">Of een advertentie wordt gepersonaliseerd terwijl je browst, is afhankelijk van deze instelling, <ph name="BEGIN_LINK1" />door sites voorgestelde advertenties<ph name="LINK_END1" />, je <ph name="BEGIN_LINK2" />cookie-instellingen<ph name="LINK_END2" /> en of de site die je bekijkt advertenties personaliseert</translation>
 <translation id="284581348330507117">Maak unieke wachtwoorden</translation>
@@ -3681,6 +3687,7 @@
 <translation id="3694590407685276748">Tekstcursor markeren</translation>
 <translation id="369489984217678710">Wachtwoorden en andere inloggegevens</translation>
 <translation id="369522892592566391">{NUM_FILES,plural, =0{Beveiligingscontroles zijn uitgevoerd. Je gegevens worden geüpload.}=1{Beveiligingscontroles zijn uitgevoerd. Je bestand wordt geüpload.}other{Beveiligingscontroles zijn uitgevoerd. Je bestanden worden geüpload.}}</translation>
+<translation id="3695339288331169103">Van <ph name="BEGIN_LINK" /><ph name="DISPLAY_REFERRER_URL" /><ph name="END_LINK" /></translation>
 <translation id="369736917241079046">Launcher + pijl-links</translation>
 <translation id="3697716475445175867">laatst geopend</translation>
 <translation id="3697732362672163692">{NUM_SITES,plural, =1{Je kunt voorkomen dat deze site in de toekomst meldingen stuurt.}other{Je kunt voorkomen dat deze sites in de toekomst meldingen sturen.}}</translation>
@@ -4981,6 +4988,7 @@
 <translation id="4650591383426000695">Je telefoon ontkoppelen van je <ph name="DEVICE_TYPE" /></translation>
 <translation id="4651484272688821107">Kan online component niet laden met bronnen van demomodus.</translation>
 <translation id="4651921906638302153">Kan niet inloggen met dit account</translation>
+<translation id="4652921642122345344">Spraaksnelheid <ph name="RATE" />x</translation>
 <translation id="4652935475563630866">Parallels Desktop moet worden herstart om de camera-instelling te wijzigen. Herstart Parallels Desktop om door te gaan.</translation>
 <translation id="4653116291358041820">Kleine schaduw</translation>
 <translation id="4653405415038586100">Fout bij configureren van Linux</translation>
@@ -5178,6 +5186,7 @@
 <translation id="4809927044794281115">Licht thema</translation>
 <translation id="4811212958317149293">Automatische scan van toetsenbord voor Toegang via schakelaar</translation>
 <translation id="4811503964269049987">Geselecteerd tabblad toevoegen aan groep</translation>
+<translation id="4812073856515324252">Kies waar je je toegangssleutel voor <ph name="APP_NAME" /> wilt opslaan</translation>
 <translation id="4813512666221746211">Netwerkfout</translation>
 <translation id="4814114628197290459">IBAN verwijderen</translation>
 <translation id="4814327014588285482">Overslaan en later herinneren</translation>
@@ -5645,6 +5654,7 @@
 <translation id="5160634252433617617">Fysiek toetsenbord</translation>
 <translation id="5160857336552977725">Log in bij je <ph name="DEVICE_TYPE" /></translation>
 <translation id="5161251470972801814">USB-apparaten van <ph name="VENDOR_NAME" /></translation>
+<translation id="5161442190864186925">Deelnemen aan vergadering</translation>
 <translation id="5161827038979306924">Wat is het verschil tussen je browsegeschiedenis in Chrome en je zoekgeschiedenis?</translation>
 <translation id="5162905305237671850"><ph name="DEVICE_TYPE" /> is geblokkeerd</translation>
 <translation id="5163910114647549394">Tabblad verplaatst naar einde van tabbladstrook</translation>
@@ -6368,7 +6378,7 @@
 <translation id="5702749864074810610">Suggestie afgewezen</translation>
 <translation id="5703716265115423771">volume omlaag</translation>
 <translation id="5704875434923668958">Synchroniseren naar</translation>
-<translation id="5705005699929844214">Toegankelijkheidsopties altijd bekijken</translation>
+<translation id="5705005699929844214">Toegankelijkheidsopties altijd tonen</translation>
 <translation id="5705882733397021510">Terug</translation>
 <translation id="5707185214361380026">Laden van extensie mislukt vanuit:</translation>
 <translation id="5708171344853220004">Principal-naam van Microsoft</translation>
@@ -7947,6 +7957,7 @@
 <translation id="6912007319859991306">Pincode voor mobiele simkaart</translation>
 <translation id="6912380255120084882">Probeer een ander apparaat.</translation>
 <translation id="691289340230098384">Voorkeuren voor ondertiteling</translation>
+<translation id="6913051485529944333">Je ziet Google Agenda niet meer op deze pagina</translation>
 <translation id="6914812290245989348">Geen waarschuwingen tonen voordat je naar niet-beveiligde sites gaat</translation>
 <translation id="6916590542764765824">Extensies beheren</translation>
 <translation id="6918677045355889289">Chrome OS-update vereist</translation>
@@ -9148,6 +9159,7 @@
 <translation id="7810202088502699111">Er zijn pop-ups op deze pagina geblokkeerd</translation>
 <translation id="7810367892333449285">Je invoer moet deze indeling hebben: <ph name="LPA_0" />$<ph name="LPA_1" />SM-DP+ adres<ph name="LPA_2" />$<ph name="LPA_3" />optionele overeenkomende ID<ph name="LPA_4" /></translation>
 <translation id="7811263553491007091">Probeer het opnieuw of maak een keuze uit een van de eerder gegenereerde thema's hieronder.</translation>
+<translation id="7812170317334653156">Google Agenda verborgen</translation>
 <translation id="7814090115158024843">Nooit hulp bij schrijven aanbieden op deze sites</translation>
 <translation id="7814458197256864873">&amp;Kopiëren</translation>
 <translation id="7814857791038398352">Microsoft OneDrive</translation>
@@ -9206,6 +9218,7 @@
 <translation id="7853747251428735">Meer hu&amp;lpprogramma's</translation>
 <translation id="7853999103056713222">Een veiliger wachtwoord gebruiken</translation>
 <translation id="7855678561139483478">Tabblad verplaatsen naar nieuw venster</translation>
+<translation id="7856117067008941054">Google Agenda verbergen</translation>
 <translation id="7857004848504343806">Je computer bevat een beveiligde module die wordt gebruikt om veel van de belangrijke beveiligingsfuncties in Chrome OS Flex te implementeren. Ga voor meer informatie naar het Helpcentrum voor Chromebooks: https://support.google.com/chromebook/?p=sm</translation>
 <translation id="7857093393627376423">Tekstsuggesties</translation>
 <translation id="7858120906780498731">Gekoppelde ChromeOS-invoerapparaten</translation>
@@ -9214,6 +9227,7 @@
 <translation id="786073089922909430">Service: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;Downloads</translation>
 <translation id="7861846108263890455">Taal van Google-account</translation>
+<translation id="7864114920800968141">Over <ph name="NUM_MIN" /> min</translation>
 <translation id="7864539943188674973">Bluetooth uitzetten</translation>
 <translation id="7864825798076155402">Opslaan in je Google-account?</translation>
 <translation id="7865127013871431856">Opties voor vertalen</translation>
diff --git a/chrome/app/resources/generated_resources_ro.xtb b/chrome/app/resources/generated_resources_ro.xtb
index 99b2f83e..c907b55 100644
--- a/chrome/app/resources/generated_resources_ro.xtb
+++ b/chrome/app/resources/generated_resources_ro.xtb
@@ -973,6 +973,7 @@
 <translation id="1697150536837697295">Artă</translation>
 <translation id="1697686431566694143">Editează fișierul</translation>
 <translation id="1698796500103229697">&amp;Metode de plată</translation>
+<translation id="1698899521169711967">Navigare cu tastatura</translation>
 <translation id="1699807488537653303">Remediază eroarea legată de parolă</translation>
 <translation id="1700201317341192482">Elimină cardul virtual</translation>
 <translation id="1700517974991662022">Accesat</translation>
@@ -2471,6 +2472,7 @@
 <translation id="2771816809568414714">Brânză</translation>
 <translation id="2772936498786524345">Ninja</translation>
 <translation id="2773288106548584039">Compatibilitate pentru browsere vechi</translation>
+<translation id="2773621783913034737">Dezactivează filele</translation>
 <translation id="2773802008104670137">Este posibil ca acest tip de fișier să dăuneze computerului.</translation>
 <translation id="2775104091073479743">Editează amprentele</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{Extensia <ph name="EXTENSION" /> accesa dispozitive}=1{Extensia <ph name="EXTENSION" /> accesează {0} dispozitiv}few{Extensia <ph name="EXTENSION" /> accesează {0} dispozitive}other{Extensia <ph name="EXTENSION" /> accesează {0} de dispozitive}}</translation>
@@ -2551,6 +2553,7 @@
 <translation id="2830528677948328648">Gestionează-ți Contul &amp;Google</translation>
 <translation id="2831430281393059038">Dispozitivul este compatibil</translation>
 <translation id="2832124733806557606">Copilul tău poate folosi un cod PIN pentru a se conecta sau a debloca dispozitivul.</translation>
+<translation id="2833144527504272627">Navighează folosind cursorul pentru text</translation>
 <translation id="2835177225987815960">Configurația actuală de scanare va fi resetată, inclusiv comutatoarele atribuite și setările pentru viteza de scanare automată.</translation>
 <translation id="2835547721736623118">Serviciul de recunoaștere vocală</translation>
 <translation id="2835761321523638096">Citește și modifică intrările din lista de lecturi</translation>
@@ -4106,6 +4109,7 @@
 <translation id="3978325380690188371">Tastele adezive nu sunt disponibile când ChromeVox este activat</translation>
 <translation id="3979395879372752341">A fost adăugată o extensie (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326">Activează <ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">Ascunde aceste file</translation>
 <translation id="3981058120448670012">Vizibil pentru dispozitivele din apropiere ca <ph name="DEVICE_NAME" /> timp de <ph name="REMAINING_TIME" />...</translation>
 <translation id="3981760180856053153">A fost introdus un tip de salvare nevalid.</translation>
 <translation id="3982375475032951137">Configurează browserul în câțiva pași simpli</translation>
@@ -6297,6 +6301,7 @@
 <translation id="5642508497713047">Semnatar CRL</translation>
 <translation id="5643191124441701136">Codul de securitate se află pe partea din față a cardului</translation>
 <translation id="5643321261065707929">Rețea contorizată</translation>
+<translation id="5643717184207603910">Menține performanța rapidă</translation>
 <translation id="5646376287012673985">Locație</translation>
 <translation id="5646558797914161501">Om de afaceri</translation>
 <translation id="5648021990716966815">Mufă pentru microfon</translation>
@@ -6401,6 +6406,7 @@
 <translation id="5733109311583381874">Pentru a personaliza sugestiile de conversie, adaugă propriile cuvinte în dicționarele utilizatorului.</translation>
 <translation id="5734362860645681824">Comunicații</translation>
 <translation id="5734697361979786483">Adaugă un dispozitiv de stocare în rețea</translation>
+<translation id="5735513236153491131">Accelerează acum</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{Aceste date sau dispozitivul nu respectă unele dintre politicile de securitate ale organizației. Consultă administratorul pentru a afla ce trebuie remediat.}=1{Acest fișier sau dispozitivul nu respectă unele dintre politicile de securitate ale organizației. Consultă administratorul pentru a afla ce trebuie remediat.}few{Aceste fișiere nu respectă unele dintre politicile de securitate ale organizației. Consultă administratorul pentru a afla ce trebuie remediat.}other{Aceste fișiere nu respectă unele dintre politicile de securitate ale organizației. Consultă administratorul pentru a afla ce trebuie remediat.}}</translation>
 <translation id="5738093759615225354">Ai nevoie de această cheie de acces pentru a te conecta la computer</translation>
 <translation id="5739017626473506901">Conectează-te pentru a ajuta utilizatorul <ph name="USER_NAME" /> să adauge un cont de la școală</translation>
@@ -8214,6 +8220,7 @@
 <translation id="7114054701490058191">Parolele nu corespund</translation>
 <translation id="7114648273807173152">Pentru a folosi Smart Lock ca să te conectezi la Contul Google, accesează Setări &gt; Dispozitive conectate &gt; Telefon &gt; Smart Lock.</translation>
 <translation id="7115361495406486998">Nu sunt disponibile persoane de contact</translation>
+<translation id="7115731767122970828">Accelerează acum</translation>
 <translation id="7116554090938189816">Certificatul SSL al imprimantei a expirat. Repornește imprimanta și încearcă din nou.</translation>
 <translation id="7117228822971127758">Încearcă din nou mai târziu</translation>
 <translation id="7118268675952955085">captură de ecran</translation>
@@ -8369,6 +8376,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (optimă)</translation>
 <translation id="7246230585855757313">Reintrodu cheia de securitate și încearcă din nou</translation>
 <translation id="724835896049478274">Conturi disponibile pentru aplicații pentru Android</translation>
+<translation id="7248802599439396696">Dezactivează filele</translation>
 <translation id="7249197363678284330">Schimbă această setare în bara de adrese.</translation>
 <translation id="7249764475759804559">Include aplicația ca opțiune la deschiderea fișierelor</translation>
 <translation id="7250616558727237648">Dispozitivul căruia îi trimiți nu a răspuns. Încearcă din nou.</translation>
@@ -9964,6 +9972,7 @@
 <translation id="8390392581097975659">Se instalează software-ul scanerului</translation>
 <translation id="8390449457866780408">Server indisponibil.</translation>
 <translation id="8391218455464584335">Vinil</translation>
+<translation id="8391918125842702622">Alertă privind problema performanței</translation>
 <translation id="8392726714909453725">Setări Selectează și ascultă</translation>
 <translation id="8393511274964623038">Oprește pluginul</translation>
 <translation id="839363317075970734">Detalii despre dispozitivul Bluetooth</translation>
@@ -10064,6 +10073,7 @@
 <translation id="8466052016039127321">Nu se poate relua sesiunea anterioară</translation>
 <translation id="8467326454809944210">Alege altă limbă</translation>
 <translation id="8468087214092422866">Nu au permisiunea de a căuta dispozitive Bluetooth</translation>
+<translation id="8469863130477774813">Este disponibil un plus de performanță</translation>
 <translation id="8470513973197838199">Parole salvate pentru <ph name="ORIGIN" /></translation>
 <translation id="8471525937465764768">Site-urile se conectează de obicei la dispozitive USB pentru funcții cum ar fi imprimarea unui document sau salvarea pe un dispozitiv de stocare</translation>
 <translation id="8471959340398751476">Reducerile sunt dezactivate. Le poți activa în meniul de personalizare</translation>
diff --git a/chrome/app/resources/generated_resources_ru.xtb b/chrome/app/resources/generated_resources_ru.xtb
index 491e5e4..4a2f25d 100644
--- a/chrome/app/resources/generated_resources_ru.xtb
+++ b/chrome/app/resources/generated_resources_ru.xtb
@@ -974,6 +974,7 @@
 <translation id="1697150536837697295">Искусство</translation>
 <translation id="1697686431566694143">Разрешить</translation>
 <translation id="1698796500103229697">Способы оплаты</translation>
+<translation id="1698899521169711967">Режим активного курсора</translation>
 <translation id="1699807488537653303">Устраните проблему с паролем</translation>
 <translation id="1700201317341192482">Удаление виртуальной карты</translation>
 <translation id="1700517974991662022">Посещено</translation>
@@ -2472,6 +2473,7 @@
 <translation id="2771816809568414714">Сыр</translation>
 <translation id="2772936498786524345">Ниндзя</translation>
 <translation id="2773288106548584039">Поддержка альтернативного браузера</translation>
+<translation id="2773621783913034737">Сделать вкладки неактивными</translation>
 <translation id="2773802008104670137">Файлы этого типа могут нанести вред вашему компьютеру.</translation>
 <translation id="2775104091073479743">Настроить отпечатки</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{Расширение "<ph name="EXTENSION" />" обращалось к устройствам}=1{Расширение "<ph name="EXTENSION" />" обращается к {0} устройству}one{Расширение "<ph name="EXTENSION" />" обращается к {0} устройству}few{Расширение "<ph name="EXTENSION" />" обращается к {0} устройствам}many{Расширение "<ph name="EXTENSION" />" обращается к {0} устройствам}other{Расширение "<ph name="EXTENSION" />" обращается к {0} устройства}}</translation>
@@ -2552,6 +2554,7 @@
 <translation id="2830528677948328648">Управление аккаунтом &amp;Google</translation>
 <translation id="2831430281393059038">Устройство поддерживается.</translation>
 <translation id="2832124733806557606">Ребенок может использовать PIN-код для входа в аккаунт или разблокировки устройства.</translation>
+<translation id="2833144527504272627">Навигация с помощью текстового курсора</translation>
 <translation id="2835177225987815960">Текущие настройки сканирования будут сброшены, включая назначенные переключатели и скорость автосканирования.</translation>
 <translation id="2835547721736623118">Сервис распознавания речи</translation>
 <translation id="2835761321523638096">Чтение и изменение записей в списке для чтения</translation>
@@ -4108,6 +4111,7 @@
 <translation id="3978325380690188371">Режим залипания клавиш недоступен при включенной программе ChromeVox</translation>
 <translation id="3979395879372752341">Добавлено новое расширение (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326">Включить <ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">Скрыть эти вкладки</translation>
 <translation id="3981058120448670012">Отображается под названием "<ph name="DEVICE_NAME" />" для других устройств поблизости в течение <ph name="REMAINING_TIME" />…</translation>
 <translation id="3981760180856053153">Введен недействительный тип сохранения.</translation>
 <translation id="3982375475032951137">Настройте браузер за несколько простых шагов.</translation>
@@ -6300,6 +6304,7 @@
 <translation id="5642508497713047">Сторона, подписавшая список отзыва сертификатов</translation>
 <translation id="5643191124441701136">Защитный код можно найти на лицевой стороне карты</translation>
 <translation id="5643321261065707929">Сеть с тарификацией</translation>
+<translation id="5643717184207603910">Поддерживайте высокую производительность</translation>
 <translation id="5646376287012673985">Местоположение</translation>
 <translation id="5646558797914161501">Бизнесмен</translation>
 <translation id="5648021990716966815">Микрофонный разъем</translation>
@@ -6404,6 +6409,7 @@
 <translation id="5733109311583381874">Чтобы настроить варианты преобразования текста, добавьте свои слова в пользовательский словарь</translation>
 <translation id="5734362860645681824">Оборудование</translation>
 <translation id="5734697361979786483">Добавить общую папку</translation>
+<translation id="5735513236153491131">Повысить</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{Эти данные или ваше устройство не соответствуют некоторым правилам безопасности организации. Обратитесь к администратору.}=1{Этот файл или ваше устройство не соответствует некоторым правилам безопасности организации. Обратитесь к администратору.}one{Эти файлы не соответствуют некоторым правилам безопасности вашей организации. Обратитесь к администратору.}few{Эти файлы не соответствуют некоторым правилам безопасности вашей организации. Обратитесь к администратору.}many{Эти файлы не соответствуют некоторым правилам безопасности вашей организации. Обратитесь к администратору.}other{Эти файлы не соответствуют некоторым правилам безопасности вашей организации. Обратитесь к администратору.}}</translation>
 <translation id="5738093759615225354">Этот ключ доступа нужен, чтобы входить в систему на компьютере.</translation>
 <translation id="5739017626473506901">Войдите в систему, чтобы помочь пользователю <ph name="USER_NAME" /> добавить учебный аккаунт.</translation>
@@ -8221,6 +8227,7 @@
 <translation id="7114054701490058191">Пароли не совпадают</translation>
 <translation id="7114648273807173152">Чтобы использовать Smart Lock для входа в аккаунт Google, нажмите "Настройки &gt; Подключенные устройства &gt; Телефон &gt; Smart Lock".</translation>
 <translation id="7115361495406486998">Нет доступных контактов</translation>
+<translation id="7115731767122970828">Повысить</translation>
 <translation id="7116554090938189816">Срок действия SSL-сертификата принтера истек. Перезапустите принтер и повторите попытку.</translation>
 <translation id="7117228822971127758">Повторите попытку позже.</translation>
 <translation id="7118268675952955085">скриншот</translation>
@@ -8376,6 +8383,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (оптимальное)</translation>
 <translation id="7246230585855757313">Вставьте электронный ключ ещё раз и повторите попытку.</translation>
 <translation id="724835896049478274">Аккаунты, доступные для приложений Android</translation>
+<translation id="7248802599439396696">Сделать вкладки неактивными</translation>
 <translation id="7249197363678284330">Измените эту настройку в адресной строке.</translation>
 <translation id="7249764475759804559">Добавить в список приложений, с помощью которых можно открывать файлы</translation>
 <translation id="7250616558727237648">Устройство, на которое вы отправляете файлы, не отвечает. Повторите попытку.</translation>
@@ -9970,6 +9978,7 @@
 <translation id="8390392581097975659">Установка ПО для сканера…</translation>
 <translation id="8390449457866780408">Сервер недоступен.</translation>
 <translation id="8391218455464584335">Виниловая пластинка</translation>
+<translation id="8391918125842702622">Оповещение о проблеме производительности</translation>
 <translation id="8392726714909453725">Настройки озвучивания при нажатии</translation>
 <translation id="8393511274964623038">Остановить плагин</translation>
 <translation id="839363317075970734">Сведения об устройстве Bluetooth</translation>
@@ -10070,6 +10079,7 @@
 <translation id="8466052016039127321">Невозможно возобновить предыдущий сеанс</translation>
 <translation id="8467326454809944210">Выбрать другой язык</translation>
 <translation id="8468087214092422866">Запрещено искать устройства Bluetooth</translation>
+<translation id="8469863130477774813">Повысьте производительность</translation>
 <translation id="8470513973197838199">Сохраненные пароли для <ph name="ORIGIN" /></translation>
 <translation id="8471525937465764768">Обычно сайты подключаются к USB-устройствам, чтобы использовать некоторые функции, например печатать документы или сохранять данные на внешних накопителях.</translation>
 <translation id="8471959340398751476">Скидки отключены. Включить их можно в меню настройки.</translation>
diff --git a/chrome/app/resources/generated_resources_si.xtb b/chrome/app/resources/generated_resources_si.xtb
index 950aad1..d416198 100644
--- a/chrome/app/resources/generated_resources_si.xtb
+++ b/chrome/app/resources/generated_resources_si.xtb
@@ -67,6 +67,7 @@
 <translation id="1043505821207197890">යම් දෙයක් වැරදිණි. Linux යාවත්කාලීන කළ හැක්කේ අර්ධ වශයෙන් පමණක් විය හැකිය. වැඩි විස්තර සඳහා ලොග සමාලෝචනය කරන්න. ලොග Files &gt; මගේ ගොනු &gt; <ph name="LOG_FILE" /> තුළ සුරැක ඇත</translation>
 <translation id="104419033123549300">යතුරු අනුරූපණ විලාසය</translation>
 <translation id="1046521327593783388">{NUM_PASSWORDS,plural, =1{මෙම උපාංගය මත <ph name="BRAND" /> වෙත 1 මුරපදයක් ආයාත කරන ලදි}one{මෙම උපාංය මත <ph name="BRAND" /> වෙත මුරපද {NUM_PASSWORDS}ක් ආයාත කරන ලදි}other{මෙම උපාංය මත <ph name="BRAND" /> වෙත මුරපද {NUM_PASSWORDS}ක් ආයාත කරන ලදි}}</translation>
+<translation id="1046572983040892965">කවුළුව ඉහළට සහ වමට ගෙන ගියා</translation>
 <translation id="104710386808485638">ලිනක්ස් යළි අරඹන්නේද?</translation>
 <translation id="1047431265488717055">සබැඳි පෙළ පිටපත් කරන්න</translation>
 <translation id="1048286738600630630">සංදර්ශක</translation>
@@ -187,6 +188,7 @@
 <translation id="1130589222747246278"><ph name="WINDOW_TITLE" /> - <ph name="GROUP_NAME" /> කණ්ඩායමේ කොටසකි</translation>
 <translation id="1130676589211693127">දකුණු බැටරි මට්ටම <ph name="PERCENTAGE" />%.</translation>
 <translation id="1133418583142946603">වත්මන් ටැබය එක් කරන්න</translation>
+<translation id="1134363466745332968">ඔබට පිටු මාතෘකාය සහ URL පමණක් නොව සාමාන්‍ය පිටු අන්තර්ගතය මත පදනම්ව ඔබේ බ්‍රවුස් කිරීමේ ඉතිහාසය සෙවිය හැක. ඔබ @history භාවිත කර ලිපින තීරුව තුළ හෝ බ්‍රවුස් කිරීමේ ඉතිහාස පිටුවෙන් සොයන්නේ වූවාත් මෙය ඔබට දියුණු ප්‍රතිඵල දෙයි.</translation>
 <translation id="1136179794690960030"><ph name="EMOJI_NAME" />. <ph name="EMOJI_COUNT" />න් <ph name="EMOJI_INDEX" /></translation>
 <translation id="1136712381129578788">ඉතා වැඩි අවස්ථාවක් වැරදි රහස් අංකය ඇතුළත් කළ බැවින් ආරක්‍ෂක යතුරට අඟුලු දමා ඇත. එය අඟුලු ඇරීමට, එය ඉවත් කර යළි ඇතුළත් කරන්න.</translation>
 <translation id="1137589305610962734">තාවකාලික දත්ත</translation>
@@ -218,6 +220,7 @@
 <translation id="1158080958325422608">කැපිටල් අකුරු බවට පත් කරන්න</translation>
 <translation id="1158238185437008462">මතක බලන්න</translation>
 <translation id="1159879754517035595">දිගු සැකසීම් කළමනාකරණය කරන්න</translation>
+<translation id="1160800016654917722">කවුළුව පහළට සහ වමට ගෙන ගියා</translation>
 <translation id="1161575384898972166">කරුණාකර සේවාදායක සහතික නිර්යාත කිරීමට <ph name="TOKEN_NAME" /> වෙත සයින් ඉන් වන්න.</translation>
 <translation id="116173250649946226">ඔබගේ පරිපාලක වෙනස් කළ නොහැකි පෙරනිමි තේමාවක් සකසා ඇත.</translation>
 <translation id="1162213688509394031">මාතෘකා තීරුව සඟවන්න</translation>
@@ -325,6 +328,7 @@
 <translation id="1227993798763400520">විකාශය කිරීමට අසමත් විය. නැවත උත්සාහ කරන්න.</translation>
 <translation id="1230417814058465809">සම්මත ආරක්ෂව ක්‍රියාත්මකයි. ඊටත් වඩා ආරක්ෂාව සඳහා, වැඩි දියුණු කළ ආරක්ෂාව භාවිතා කරන්න.</translation>
 <translation id="1231426483209637778">ඔබ මීළඟ වතාවේ <ph name="DEVICE_TYPE" /> භාවිතා කරන විට අපි ඔබේ ජාලය මතක තබා ගන්නෙමු</translation>
+<translation id="1231572247662419826">අඩවිවලට ඔබේ මූසික ආදානය ග්‍රහණ කර භාවිත කිරීමට අවසර ඉල්ලිය හැක</translation>
 <translation id="1232569758102978740">මාතෘකා නොමැති</translation>
 <translation id="1233497634904001272">ඉල්ලීම සම්පූර්ණ කිරීමට ඔබේ ආරක්‍ෂක යතුර නැවතත් ස්පර්ශ කරන්න.</translation>
 <translation id="1233721473400465416">ස්ථානය</translation>
@@ -547,6 +551,7 @@
 <translation id="1407069428457324124">අඳුරු තේමාව</translation>
 <translation id="1407135791313364759">සියල්ල විවෘත කරන්න</translation>
 <translation id="140723521119632973">සෙලියුලර් ක්‍රියාත්මක කිරීම</translation>
+<translation id="1407970155431887387"><ph name="SEARCH_ENGINE_NAME" /> සඳහා සංස්කරණ සංවාදය විවෘත කිරීමට ක්ලික් කරන්න</translation>
 <translation id="1408504635543854729">ගොනු යෙදුම්වල උපාංගයෙහි අන්තර්ගතය ගවේෂණය කරන්න. පරිපාලක විසින් අනතර්ගතය අවහිර කර තිබේ එම නිසා වෙනස් කළ නොහැක.</translation>
 <translation id="1408980562518920698">පුද්ගලික තොරතුරු කළමනා කරන්න</translation>
 <translation id="1410197035576869800">යෙදුම් නිරූපකය</translation>
@@ -1107,6 +1112,7 @@
 <translation id="1803531841600994172">පරිවර්තන කළ යුතු භාෂාව</translation>
 <translation id="1803545009660609783">නැවත පුහුණු කරන්න</translation>
 <translation id="1804195280859010019">Google සෙවීම් පැති පැනලය වැනි විශේෂාංග තුළ ඔබට වඩාත් ප්‍රයෝජනවත් තොරතුරු හෝ යෝජනා පෙනෙනු ඇත</translation>
+<translation id="180441032496361123"><ph name="SEARCH_ENGINE_NAME" /> ක්‍රියාත්මක කිරීමට ක්ලික් කරන්න</translation>
 <translation id="1805738995123446102">පසුබිම් පටිත්ත ඔබගේ මයික්‍රෆෝනය භාවිතා කරයි</translation>
 <translation id="1805822111539868586">දසුන් පිරික්සන්න</translation>
 <translation id="1805888043020974594">මුද්‍රණ සේවාදායකය</translation>
@@ -1180,6 +1186,7 @@
 <translation id="1848219224579402567">පියන වසා ඇති විට වරන්න</translation>
 <translation id="184862733444771842">විශේෂාංග ඉල්ලීම</translation>
 <translation id="1849016657376805933">ඕනෑම HID උපාංගයක්</translation>
+<translation id="1849022541429818637">ඔබේ මූසික ආදානය ග්‍රහණ කර භාවිත කිරීමට ඉඩ දෙන ලදි</translation>
 <translation id="1850145825777333687">උපාංග අක්තපත්‍ර</translation>
 <translation id="1850508293116537636">දක්ෂිණාවර්ථව කරකවන්න (&amp;c)</translation>
 <translation id="185111092974636561"><ph name="BEGIN_PARAGRAPH1" />ලියාපදිංචි කිරීමට පෙර ඔබ TPM හිස් කිරීම අවශ්‍යයි, එවිට <ph name="DEVICE_OS" /> හට ඔබගේ උපාංගයෙහි හිමිකාරත්වය ලබා ගත හැකිය.<ph name="END_PARAGRAPH1" />
@@ -1728,6 +1735,7 @@
 <translation id="2251809247798634662">නව අප්‍රසිද්ධ කවුළුව</translation>
 <translation id="2252017960592955005">බැලීමේ ආරක්ෂණය (බීටා)</translation>
 <translation id="2253318212986772520"><ph name="PRINTER_NAME" /> සඳහා PPD ලබා ගැනීමට නොහැකි වේ.</translation>
+<translation id="2253797136365098595">ඉතිහාස සෙවීම් ගැන තව දැන ගන්න</translation>
 <translation id="2253927598983295051"><ph name="APP_NAME" /> සමග බෙදා ගත යුතු දේ තෝරා ගන්න</translation>
 <translation id="2255077166240162850">මෙම උපාංගය වෙනත් වසමට හෝ ප්‍රකාරයට අඟුලු දමා ඇත.</translation>
 <translation id="2255317897038918278">Microsoft වේලාව මුද්‍රා තැබීම</translation>
@@ -2126,6 +2134,7 @@
 <translation id="2515586267016047495">Alt</translation>
 <translation id="251722524540674480">ඔබගේ පරිශීලක නාමය තහවුරු කරන්න</translation>
 <translation id="2517472476991765520">ස්කෑන් කරන්න</translation>
+<translation id="2517851527960406492">අඩවිවලට ඔබේ යතුරු පුවරු ආදානය ග්‍රහණ කර භාවිත කිරීමට අවසර ඉල්ලිය හැක</translation>
 <translation id="2518024842978892609">ඔබේ සේවාලාභී සහතික භාවිත කරන්න</translation>
 <translation id="2518620532958109495">පූර්ණ තිරයට ස්වයංක්‍රීයව ඇතුළු වීමට අවසර දෙන ලදි</translation>
 <translation id="2519250377986324805">ආකාරය බලන්න</translation>
@@ -2304,6 +2313,7 @@
 <translation id="265748523151262387">ඔබේ දුරකථනය සමග සම්බන්ධව සිටින්න</translation>
 <translation id="2657612187216250073">ලකුණුකර ප්‍රවේශ්‍යතා සැකසීම්</translation>
 <translation id="2658941648214598230">මුල් අන්තර්ගතය පෙන්වන්නද?</translation>
+<translation id="2659694935349347275">කවුළුව පහළට සහ දකුණට ගෙන ගියා</translation>
 <translation id="2659971421398561408">Crostini තැටි ප්‍රතිප්‍රමාණය</translation>
 <translation id="2660115748527982021">ඉඟිය: බොහෝ Android යෙදුම් වෙබය මත ලැබේ. ලැබීම සඳහා යෙදුම් හෝ සංවර්ධක වෙබ් අඩවිය පරීක්‍ෂා කරන්න.</translation>
 <translation id="2660779039299703961">ඉසව්ව</translation>
@@ -2349,6 +2359,7 @@
 <translation id="2690024944919328218">භාෂා විකල්ප පෙන්වන්න</translation>
 <translation id="2691385045260836588">මාදිලිය</translation>
 <translation id="2691440343905273290">ආදාන සැකසීම් වෙනස් කරන්න</translation>
+<translation id="2691811116976138467">අඩවි ක්‍රීඩා හෝ දුරස්ථ ඩෙස්ක්ටොප යෙදුම් සඳහා වැනියෙන් ඔබේ යතුරු පුවරුවේ ආදානය ග්‍රහණ කර භාවිත කිරීමට මෙම විශේෂාංගය භාවිත කරයි</translation>
 <translation id="2692503699962701720">කථන මූලාංගය ටයිප් කරන විට සහ පෙළ හැඩ ගැන් වූ විට තාරතාව වෙනස් කරන්න</translation>
 <translation id="2692901429679246677">ඇක්වා</translation>
 <translation id="2693134906590795721">ආරෝපණය වීමේ ශබ්ද</translation>
@@ -3115,6 +3126,7 @@
 <translation id="3261090393424563833">අනුපාතය වැඩි කරන්න</translation>
 <translation id="3261268979727295785">වයසින් වැඩි දරුවන් සඳහා, ඔබ පිහිටුවීම අවසන් කළ පසු ඔබට මාපිය පාලන එක් කළ හැකිය. Explore යෙදුමෙන් ඔබ මාපිය පාලන පිළිබඳ තොරතුරු සොයා ගනු ඇත.</translation>
 <translation id="3261832505033014216"><ph name="USER_EMAIL" /> සඳහා මුරයතුර</translation>
+<translation id="3262261769033093854">අඩවිවලට ඔබේ මූසික ආදානය ග්‍රහණ කර භාවිත කිරීමට ඉඩ නොදෙන්න</translation>
 <translation id="3262336253311870293">මෙම ගිණුම <ph name="DOMAIN" /> විසින් කළමනාකරණය කරන බැවින් ඔබව ඔබේ Google ගිණුමෙන් වරනය නොවනු ඇත. ඔබේ පිටුසන්, ඉතිහාසය, මුරපද, සහ අනෙකුත් සැකසීම් තවදුරටත් සමමුහුර්ත නොවනු ඇත. කෙසේ වෙතත්, ඔබේ කලින් සමමුහුර්ත කළ දත්ත ඔබේ Google ගිණුමේ ගබඩා වී පවතින අතර <ph name="BEGIN_LINK" />Google උපකරණ පුවරුව<ph name="END_LINK" /> මත කළමනාකරණය කළ හැක.</translation>
 <translation id="3262986719682892278">විශාල වැඩිය</translation>
 <translation id="3264544094376351444">සංස්-සෙරිෆ් අකුරු</translation>
@@ -3428,6 +3440,7 @@
 <translation id="3497501929010263034"><ph name="VENDOR_NAME" /> වෙතින් USB උපාංගය (නිෂ්පාදන <ph name="PRODUCT_ID" />)</translation>
 <translation id="3497560059572256875">Doodle බෙදා ගන්න</translation>
 <translation id="3497915391670770295">ඔබේ උපාංග වෙත යවන්න</translation>
+<translation id="3499091376302796297">ඔබ අඩවි බ්‍රවුස් කරන විට, ඒවායේ පිටු අන්තර්ගත ඔබේ උපාංගය මත සංකේතිත ආකාරයකින් සුරකිනු ලැබේ.</translation>
 <translation id="3500417806337761827">පංගුව නැංවීමේ දෝෂය. දැනටමත් නංවා ඇත SMB පංගු සංඛ්‍යාව ඉතා වැඩියි.</translation>
 <translation id="3500764001796099683">එකලා වෙබ් යෙදුම් සබල කරන්න</translation>
 <translation id="350397915809787283">ඔබට ගිණුමක් නොමැති නම්, එකක් තැනීම සඳහා පළමු විකල්පය තෝරන්න.</translation>
@@ -4236,6 +4249,7 @@
 <translation id="4062561150282203854">ඔබගේ <ph name="DEVICE_TYPE" /> යෙදුම්, සැකසීම්, සහ තවත් දේ සමමුහුර්ත කරන්න</translation>
 <translation id="4065876735068446555">ඔබ භාවිතා කරන ජාලයට (<ph name="NETWORK_ID" />) ඔබ එහි පුරනය වීමේ පිටුවට පිවිසීම අවශ්‍ය වනු ඇත.</translation>
 <translation id="4066207411788646768">ඔබේ ජාලයේ ඇති මුද්‍රක බැලීමට ඔබේ සබැඳුම පරීක්ෂා කරන්න</translation>
+<translation id="4066458014195202324">ඔබේ යතුරු පුවරු ආදානය ග්‍රහණ කර භාවිත කිරීමට ඉඩ දෙන ලදි</translation>
 <translation id="4067839975993712852">වත්මන් පටිත්ත කියවූ ලෙස ලකුණු කරන්න</translation>
 <translation id="4068776064906523561">සුරැකි ඇඟිලි සලකුණු</translation>
 <translation id="4070132839822635162">පුරන්න එපා</translation>
@@ -4375,6 +4389,7 @@
 <translation id="4184803915913850597">HID උපාංගය (<ph name="VENDOR_ID" />:<ph name="PRODUCT_ID" />)</translation>
 <translation id="4186749321808907788"><ph name="QUERY_NAME" /> - <ph name="DEFAULT_SEARCH_ENGINE_NAME" /> සෙවීම</translation>
 <translation id="4187424053537113647"><ph name="APP_NAME" /> සකසනු ලැබේ...</translation>
+<translation id="4190446002599583608">ඉතිහාස සෙවීම, AI බලගන්වයි</translation>
 <translation id="4190492351494485814">මූලික පිහිටුවීම සඳහා, ගොනු ඔබේ Chromebook වෙත සමමුහුර්ත කිරීමට හැකි වන පරිදි ඔබට අන්තර්ජාලයට සම්බන්ධ වීමට අවශ්‍ය වේ</translation>
 <translation id="4190828427319282529">යතුරු පුවරු අවධානය උද්දීපන කරන්න</translation>
 <translation id="4191892134568599822"><ph name="FEATURE_NAME" /> සමගින් ලබන්න ද?</translation>
@@ -4870,6 +4885,7 @@
 <translation id="4562155214028662640">ඇඟිලි සලකුණ එක් කරන්න</translation>
 <translation id="4562155266774382038">යෝජනාව ඉවත ලන්න</translation>
 <translation id="4562364000855074606">මෙම <ph name="DEVICE_TYPE" /> මත ස්ථාපිත යෙදුම් අවහිර කරන්න. යෙදුම් හෝ අන්තර්ගත බා ගැනීම සීමා කිරීමට Google Play සැකසීම් වෙත යන්න. <ph name="BEGIN_LINK_LEARN_MORE" />තව දැන ගන්න<ph name="END_LINK_LEARN_MORE" /></translation>
+<translation id="4562925006886238518">ඔබේ බ්‍රවුස් කිරීමේ ඉතිහාසය සෙවීමට සහ ඔබ පැමිණි අඩවි සොයා ගැනීමට එදිනෙදා භාෂාව භාවිත කරන්න.</translation>
 <translation id="4563210852471260509">ආරම්භක ආදාන භාශාව චීන</translation>
 <translation id="4563382028841851106">ගිණුමෙන් ඉවත් කරන්න</translation>
 <translation id="4563880231729913339">ඇඟිල්ල 3</translation>
@@ -4921,6 +4937,7 @@
 <translation id="4598549027014564149">අප්‍රසිද්ධව සිටින අතරේ, අඩවි හරහා, අදාළ අඩවි හරහා පවා, ඔබේ බ්‍රවුස් කිරීමේ ක්‍රියාකාරකම් බැලීමට අඩවිවලට ඔබේ කුකීස් භාවිතා කළ නොහැක. ඔබේ බ්‍රවුස් කිරීමේ ක්‍රියාකාරකම් දැන්වීම් පෞද්ගලීකරණය කිරීම වැනි දේවල් සඳහා භාවිතා නොවේ. සමහර අඩවිවල විශේෂාංග ක්‍රියා නොකළ හැක.</translation>
 <translation id="4598556348158889687">ගබඩාව කළමනාකරණය</translation>
 <translation id="4598776695426288251">Wi-Fi බහුවිධ උපාංග හරහා ලබා ගත හැකිය</translation>
+<translation id="4599323532350839656">ඔබේ යතුරු පුවරු ආදානය ග්‍රහණ කර භාවිත කිරීමට ඉඩ නොදෙනු ලැබේ</translation>
 <translation id="4600071396330666617">යෝජනා සංඛ්‍යාව</translation>
 <translation id="4601095002996233687">සැක සහිත බාගැනීම් සඳහා ගැඹුරු ස්කෑන් කිරීම්.</translation>
 <translation id="4601426376352205922">නොකියවූ ලෙස ලකුණු කරන්න</translation>
@@ -5236,6 +5253,7 @@
 <translation id="484462545196658690">ස්වයං</translation>
 <translation id="4846628405149428620">මෙම අඩවියට වෙනස් කිරීම් සුරැකිය හැකි ස්ථානය තෝරන්න</translation>
 <translation id="4846680374085650406">ඔබ මෙම සැකසුම සඳහා පරිපාලකයේ නිර්දේශය අනුගමනය කරයි.</translation>
+<translation id="4846897209694249040">ඔබේ මූසික ආදානය ග්‍රහණ කර භාවිත කිරීමට ඉඩ නොදෙනු ලැබේ</translation>
 <translation id="4847242508757499006">සීමිත බැලීම් සහ සංස්කරණ විකල්ප භාවිතා කිරීමට "නැවත උත්සාහ කරන්න" තෝරන්න, නැතහොත් "මූලික සංස්කාරකයේ විවෘත කරන්න" තෝරා ගන්න.</translation>
 <translation id="4847742514726489375">අඩු කළ චලනය</translation>
 <translation id="4848191975108266266">Google සහකරු "Ok Google"</translation>
@@ -5356,6 +5374,7 @@
 <translation id="4927753642311223124">මෙහි දැක්මට කිසිවක් නොමැත, ඉදිරියට යන්න.</translation>
 <translation id="4928629450964837566">සුරක්ෂිත මුරපදයක් භාවිතා කරන්න</translation>
 <translation id="4929386379796360314">මුද්‍රණ ගමනාන්ත</translation>
+<translation id="4930406318748549391">පැති පැනල ස්ථානය</translation>
 <translation id="4930447554870711875">සංවර්ධකයින්</translation>
 <translation id="4930714375720679147">ක්‍රියාත්මක කරන්න</translation>
 <translation id="4931347390544064118">ජාල පෙරනිමිය භාවිත කරන විට ආරක්ෂිත සම්බන්ධතා සැම විට ම නොතිබිය හැකි ය. ඔබ සැම විට ම ආරක්ෂිත සම්බන්ධතාවයක් භාවිත කරන බව සහතික කිරීමට වෙනත් සැපයුම්කරුවෙකු තෝරා ගැනීම සලකා බලන්න.</translation>
@@ -5705,6 +5724,7 @@
 <translation id="5195074424945754995">මෙම රීතිවලට ගැළපෙන URL බ්‍රවුසර ස්විචයක් ප්‍රේරණය නොකරනු ඇති අතර ඒවා <ph name="BROWSER_NAME" /> හෝ <ph name="ALTERNATIVE_BROWSER_NAME" /> යන දෙකින් ඕනෑම එකක විවෘත කළ හැකිය.</translation>
 <translation id="5195863934285556588"><ph name="BEGIN_PARAGRAPH1" />Google හි ස්ථාන සේවාව මෙම උපාංගයේ ස්ථානය නිමානය උදවු කිරීමට Wi-Fi, ජංගම ජාල, සහ සංවේදක වැනි මූලාශ්‍ර භාවිත කරයි.<ph name="END_PARAGRAPH1" />
     <ph name="BEGIN_PARAGRAPH2" />ඔබට සැකසීම් &gt; යෙදුම් &gt; Google Play Store &gt; Android මනාප කළමනාකරණය &gt; ආරක්ෂාව සහ ස්ථානය &gt; ස්ථානය වෙත යාමෙන් ඔබට ඕනෑම වේලාවක මෙම උපාංගයේ Android ස්ථානය ක්‍රියාවිරහිත කළ හැකිය. ඔබට එම මෙනුවේම “Google ස්ථාන නිරවද්‍යතාව” ක්‍රියාවිරහිත කිරීමෙන් Android ස්ථානය සඳහා Wi-Fi, ජංගම ජාල සහ සංවේදක භාවිතය ක්‍රියාවිරහිත කළ හැකිය.<ph name="END_PARAGRAPH2" /></translation>
+<translation id="5197150086680615104">ඔබට ඕනෑම අවස්ථාවක පටිති සමූහ යෝජනා තිබේද පරීක්‍ෂා කළ හැක</translation>
 <translation id="5197255632782567636">අන්තර්ජාලය</translation>
 <translation id="5198430103906431024">භාවිත සහ දෝෂ නිර්ණ දත්ත යවන්න. මෙම උපාංගය ස්වයංක්‍රියව රෝග විනිශ්චය, උපාංග සහ යෙදුම් භාවිත දත්ත Google වෙත යවයි. මෙය පද්ධති සහ යෙදුම් ස්ථායිතාවට සහ අනෙකුත් වැඩිදියුණු කිරීම්වලට උදවු කරයි. සමහර එකතු කළ දත්ත Google යෙදුම්වලට සහ Android සංවර්ධකයින් වැනි හවුල්කරුවන්ට ද උදවු කරති. ඔබේ අමතර වෙබ් සහ යෙදුම් ක්‍රියාකාරකම් සැකසීම සක්‍රීය නම්, මෙම දත්ත ඔබේ Google ගිණුුමට සුරකිනු ලැබේ.</translation>
 <translation id="5199729219167945352">පරීක්ෂණ</translation>
@@ -7219,6 +7239,7 @@
 <translation id="6341850831632289108">ඔබේ භෞතික පිහිටීම සොයා ගන්න</translation>
 <translation id="6342069812937806050">මේ දැන්</translation>
 <translation id="6343003829431264373">ඉරට්ටේ පිටු පමණි</translation>
+<translation id="6343981313228733146">කවුළුව ඉහළට සහ දකුණට ගෙන ගියා</translation>
 <translation id="6344170822609224263">ජාල සබැඳුම් ලැයිස්තුව ප්‍රවේශ වන්න</translation>
 <translation id="6344576354370880196">සුරැකි මුද්‍රක</translation>
 <translation id="6344608411615208519">ඔබේ බ්‍රව්සරය ඔබේ මාපියන් විසින් <ph name="BEGIN_LINK" />කළමනාකරණය කරනු ලැබේ<ph name="END_LINK" /></translation>
@@ -7799,6 +7820,7 @@
 <translation id="6798780071646309401">කැප්ස් ලොක් ක්‍රියාත්මකයි</translation>
 <translation id="6798954102094737107">ප්ලගින: <ph name="PLUGIN_NAME" /></translation>
 <translation id="679905836499387150">සැඟවුණු මෙවලම් තීරු බොත්තම්</translation>
+<translation id="6800623240347398745">එම පටිත්ත සඳහා සමූහයක් නැත, නමුත් මෙම සමූහ පරීක්‍ෂා කරන්න</translation>
 <translation id="6800893479155997609">ඔබේ <ph name="DEVICE_TYPE" /> සඳහා වන ඉහළ යෙදුම්</translation>
 <translation id="6801308659697002152">{NUM_EXTENSIONS,plural, =1{මෙම දිගුවට මෙම අඩවිය කියවීමට හෝ වෙනස් කිරීමට හැකි ද යන්න තෝරා ගන්න}one{මෙම දිගුවලට මෙම වෙබ් අඩවිය කියවීමට හෝ වෙනස් කිරීමට හැකි ද යන්න තෝරා ගන්න}other{මෙම දිගුවලට මෙම වෙබ් අඩවිය කියවීමට හෝ වෙනස් කිරීමට හැකි ද යන්න තෝරා ගන්න}}</translation>
 <translation id="6801435275744557998">ස්පර්ශ තිරය ක්‍රමාංකනය කරන්න</translation>
@@ -7840,6 +7862,7 @@
 <translation id="6818920801736417483">මුරපද සුරකින්නද?</translation>
 <translation id="6820079682647046800">Kerberos සත්‍යාපනය අසමත් විය</translation>
 <translation id="6821439254917412979"><ph name="EXTENSION_NAME" /> ගලවන්න</translation>
+<translation id="6823097506504975234">ඔබ බ්‍රවුස් කිරීමේ ඉතිහාසයට සොයන විට, ඔබේ ඉතිහාස සෙවුම් පද, හොඳ ගැළපුම්වල පිටු අන්තර්ගතය, සහ ජනිත මාදිලි ප්‍රතිදාන Google වෙත යවනු ලබන අතර මෙම විශේෂාංගය දියුණු කිරීමට මානව සමාලෝචකයින් විසින් දකිනු ලැබේවි.</translation>
 <translation id="6823174134746916417">ස්පර්ශ පුවරු ක්ලික් කිරීමට තට්ටු කිරීම</translation>
 <translation id="6823561724060793716">ලිපින තීරුවෙන්, ඔබ පිවිසෙන පිටුව පිළිබඳ අතිරේක තතු බැලීමට ඔබට පිටු තතු විවෘත කළ හැක</translation>
 <translation id="6824564591481349393">ඊමේල් ලිපිනය පිටපත් කරන්න (&amp;E)</translation>
@@ -8869,6 +8892,7 @@
 <translation id="761530003705945209">Google Drive වෙත උපස්ථ කරන්න. ඕනෑම වේලාවක ඔබගේ දත්ත පහසුවෙන් ප්‍රතිසාධන කරන්න හෝ උපාංග අතර මාරු වන්න. ඔබගේ උපස්ථයට යෙදුම් දත්ත අන්තර්ගතයි. ඔබේ උපස්ථ Google වෙත උඩුගත කෙරෙන අතර ඔබේ Google ගිණුමේ මුරපදය භාවිත කර සංකේතන කෙරේ.</translation>
 <translation id="7615365294369022248">ගිණුමක් එක් කිරීමේ දෝෂයක් විය</translation>
 <translation id="7616214729753637086">උපාංගය ඇතුළත් කරමින්...</translation>
+<translation id="7616964248951412133">අඩවි ක්‍රීඩා හෝ දුරස්ථ ඩෙස්ක්ටොප යෙදුම් සඳහා වැනියෙන් ඔබේ මූසිකයේ ආදානය ග්‍රහණ කර භාවිත කිරීමට මෙම විශේෂාංගය භාවිත කරයි</translation>
 <translation id="7617263010641145920">Play Store සක්‍රීය කරන්න</translation>
 <translation id="7617648809369507487">වඩා නිශ්ශබ්ද පණිවිඩ යැවීම භාවිත කරන්න</translation>
 <translation id="7619937211696316184">නඩත්තු කටයුතු සිදු කර ඇත</translation>
@@ -9374,6 +9398,7 @@
 <translation id="7959665254555683862">නව අප්‍රකට &amp;ටැබය</translation>
 <translation id="7961015016161918242">කිසිවිට එපා</translation>
 <translation id="7963001036288347286">ස්පර්ශ පුවරු ත්වරණය</translation>
+<translation id="7963513503134856713">කවුළුව දකුණට ගෙන ගියා</translation>
 <translation id="7963608432878156675">මෙම නම බ්ලූටූත් සහ ජාල සම්බන්ධතා සඳහා වෙනත් උපාංගවලට දැකිය හැකිය</translation>
 <translation id="7963826112438303517">ඔබ Voice Match සක්‍රීය කර ඇති උපාංග තුළ පමණක් ගබඩා කෙරෙන ඔබේ හඬ මාදිලිය නිර්මාණ කිරීමටත් යාවත්කාලීන කිරීමටත් ඔබේ සහකරු මෙම පටිගත කිරීම් සහ කථන ඉල්ලීම් භාවිත කරයි. සහකරු සැකසීම් තුළ හඬ ක්‍රියාකාරකම බලන්න හෝ යළි පුහුණු කරන්න.</translation>
 <translation id="7964458523224581615">විරිඩියන්</translation>
@@ -10025,6 +10050,7 @@
 <translation id="8428271547607112339">පාසල් ගිණුම එක් කරන්න</translation>
 <translation id="8428634594422941299">තේරුණා</translation>
 <translation id="84297032718407999">ඔබ <ph name="LOGOUT_TIME_LEFT" />කින් වරනු ඇත</translation>
+<translation id="8429928917752180743"><ph name="EXTENSION_NAME" /> සඳහා තව විකල්ප</translation>
 <translation id="8431190899827883166">තට්ටු කිරීම් පෙන්වන්න</translation>
 <translation id="843173223122814223">AI සමග පසුබිම් සාදන්න</translation>
 <translation id="8433186206711564395">ජාල සැකසීම්</translation>
@@ -10114,6 +10140,7 @@
 <translation id="8498214519255567734">අඳුරු ආලෝකයේදී ඔබේ තිරය දෙස බැලීම සහ කියවීම වඩා පහසු කරන්න</translation>
 <translation id="8499083585497694743">මයික්‍රෆෝනය නිහඬ කිරීම ඉවත් කරන්න</translation>
 <translation id="8500044868721690197">මෙම වෙබ් අඩවිය ඔබේ MIDI උපාංග පාලන කිරීමෙන් සහ නැවත ක්‍රමලේඛන කිරීමෙන් අවහිර කර ඇත</translation>
+<translation id="8500123638242682652">කවුළුව ඉහළට ගෙන ගියා</translation>
 <translation id="8502536196501630039">Google Play වෙතින් යෙදුම් භාවිතා කිරීම සඳහා, පළමුව ඔබ ඔබගේ යෙදුම් ප්‍රතිස්ථාපනය කළ යුතුය. ඇතැම් දත්ත නොමැති වී යනු ඇත.</translation>
 <translation id="8503813439785031346">පරිශීලක නාමය</translation>
 <translation id="850382998924680137">අද බැලු</translation>
@@ -10213,6 +10240,7 @@
 <translation id="8577052309681449949">ස්වයංක්‍රීය ක්ලික් කිරීම්, කර්සරයේ ප්‍රමාණය, කර්සරයේ වර්ණය, සහ තවත් දේ</translation>
 <translation id="8578639784464423491">අකුරු 99 ඉක්මවිය නොහැක</translation>
 <translation id="8581809080475256101">ඉදිරියට යාමට ඔබන්න, ඉතිහාසය බැලීමට සන්දර්භ මෙනුව</translation>
+<translation id="8583122761178401199">අඩවිවලට ඔබේ යතුරු පුවරු ආදානය ග්‍රහණ කර භාවිත කිරීමට ඉඩ නොදෙන්න</translation>
 <translation id="8584280235376696778">නව ටැබයෙහි වීඩියෝව විවෘත කරන්න</translation>
 <translation id="858451212965845553">ඔබේ උපාංග වෙත යවන්න</translation>
 <translation id="8584843865238667486"><ph name="USAGE_PAGE" /> භාවිත පිටුවෙන් <ph name="USAGE" /> භාවිතය සහිත HID උපාංග</translation>
@@ -10228,6 +10256,7 @@
 <translation id="859246725979739260">මෙම අඩවිය ඔබගේ ස්ථානයට පිවිසීමෙන් අවහිර කරනු ලැබ ඇත.</translation>
 <translation id="8593450223647418235">පිහිටුවීම සම්පූර්ණ වන තෙක් ඔබට Microsoft 365 හි ගොනු විවෘත කිරීමට නොහැකි වනු ඇත.</translation>
 <translation id="8593686980889923154"><ph name="APP_NAME" /> ඔබේ <ph name="DEVICE_TYPE" /> තුළ අවහිර කෙරේ</translation>
+<translation id="8596400097994526901"><ph name="SEARCH_ENGINE_NAME" /> සඳහා තව ක්‍රියා</translation>
 <translation id="8596540852772265699">සැකසුම් ගොනු</translation>
 <translation id="8597845839771543242">වත්කම් හැඩසවිය:</translation>
 <translation id="8598249292448297523">මුද්‍රණය කරන්න</translation>
@@ -10313,6 +10342,7 @@
 <translation id="8657393004602556571">ඔබට ප්‍රතිපෝෂණය ඉවත ලෑමට අවශ්‍යද?</translation>
 <translation id="8657542881463614516">පිටු අතර සංචලන කිරීමට ස්වයිප් ඉංගිතයක් භාවිත කරන්න</translation>
 <translation id="8659608856364348875"><ph name="FEATURE_NAME" /> සම්බන්ධතා</translation>
+<translation id="8659609431223166673">කවුළුව පහළට ගෙන ගියා</translation>
 <translation id="8661290697478713397">Incognito කවුළුව තුළ සබැඳිය විවෘත කරන්න</translation>
 <translation id="8662474268934425487"><ph name="SITE_ETLD_PLUS_ONE" /> වෙත පුරන්න</translation>
 <translation id="8662671328352114214"><ph name="TYPE" /> ජාලයට එකතු වන්න</translation>
@@ -10359,6 +10389,7 @@
 <translation id="8682730193597992579"><ph name="PRINTER_NAME" /> සම්බන්ධව සහ සූදානම්ව තිබේ</translation>
 <translation id="8684471948980641888">මනුගත ජාල මත සමමුහුර්ත කිරීමට ඉඩ දෙන්න</translation>
 <translation id="8685540043423825702">ඔබේ Chrome පැතිකඩ</translation>
+<translation id="8685882652128627032">අඩවි සෙවුම එක් කරන්න යන සංවාදය විවෘත කිරීමට ක්ලික් කරන්න</translation>
 <translation id="8686142379631285985"><ph name="BEGIN_BOLD" /><ph name="DRIVE_ACCOUNT_EMAIL" /><ph name="END_BOLD" /> ලෙස පුරනය වී ඇත</translation>
 <translation id="8687103160920393343"><ph name="FILE_NAME" /> අවලංගු කරන්න</translation>
 <translation id="8687527282898211955">ඔබේ PIN පිහිටුවන්න</translation>
@@ -10548,6 +10579,7 @@
 <translation id="881799181680267069">අනෙක් ඒවා සඟවන්න</translation>
 <translation id="8818152010000655963">වෝල්පේපරය</translation>
 <translation id="8818958672113348984">ඔබගේ දුරකථනය හරහා තහවුරු කරන්න</translation>
+<translation id="8818988764764862764">කවුළුව වමට ගෙන ගියා</translation>
 <translation id="8819510664278523111">ඔබේ උපාංග EID <ph name="EID_NUMBER" /> සහ උපාංගයේ IMEI <ph name="IMEI_NUMBER" /> වන අතර උපාංගයේ අනුක්‍රමික අංකය <ph name="SERIAL_NUMBER" /> වෙයි. සේවය ක්‍රියාත්මක කිරීමට උදවු කිරීමට මෙම අංක භාවිත කළ හැක.</translation>
 <translation id="8820817407110198400">පිටුසන්</translation>
 <translation id="8821045908425223359">IP ලිපිනය ස්වයංක්‍රීයව වින්‍යාස කරන්න</translation>
@@ -10626,6 +10658,7 @@
 <translation id="8872506776304248286">යෙදුමෙහි විවෘත කරන්න</translation>
 <translation id="8872774989979382243">හඬ ක්‍රියා විරහිතයි. හඬ ක්‍රියාත්මක කරන්න.</translation>
 <translation id="887292602123626481">පෙරනිමි සෙවීම් යන්ත්‍ර පිළිබඳව තව දැන ගන්න</translation>
+<translation id="8873075098103007382">පටිති සමූහ සමග සංවිධානව සිටින්න</translation>
 <translation id="8874341931345877644">උපාංගයක් වෙත විකාශ කරන්න:</translation>
 <translation id="8874790741333031443">තෙවන පාර්ශ්ව කුකීස් සඳහා තාවකාලිකව ඉඩ දීමට උත්සාහ කරන්න, ඉන් අදහස් වන්නේ බ්‍රවුස් කිරීමේ ආරක්ෂාව අඩු නමුත් අඩවි විශේෂාංග අපේක්ෂිත පරිදි ක්‍රියා කිරීමට වැඩි ඉඩක් ඇති බවයි.</translation>
 <translation id="8875520811099717934">ලිනක්ස් උත්ශ්‍රේණිය</translation>
@@ -10758,6 +10791,7 @@
 <translation id="8973557916016709913">විශාලන මට්ටම ඉවත් කරන්න</translation>
 <translation id="8973596347849323817">ඔබට ඔබේ අවශ්‍යතාවන්ට ගැළපෙන පරිදි මෙම උපාංගය අභිරුචිකරණය කළ හැකිය. මෙම ප්‍රවේශ්‍යතා විශේෂාංග සැකසීම්වල පසුව වෙනස් කළ හැකිය.</translation>
 <translation id="897414447285476047">ගමනාන්ත ගොනුව සබැඳුමේ ගැටලුවක් හේතුවෙන් අසම්පූර්ණයි.</translation>
+<translation id="8974261761101622391"><ph name="EXTENSION_NAME" /> සඳහා විකල්පය සොයා ගන්න</translation>
 <translation id="897525204902889653">නිරෝධායන සේවය</translation>
 <translation id="8975396729541388937">ඔබට ලැබෙන ඉ-තැපැල්වල ඇති සබැඳිය ක්ලික් කිරීමෙන් ඕනෑම වේලාවක දායකත්වයෙන් ඉවත් වන්න.</translation>
 <translation id="8975562453115131273">{NUM_OTHER_TABS,plural, =0{"<ph name="TAB_TITLE" />"}=1{"<ph name="TAB_TITLE" />" සහ වෙන 1 පටිත්තක්}one{"<ph name="TAB_TITLE" />" සහ වෙනත් පටිති # ක්}other{"<ph name="TAB_TITLE" />" සහ වෙනත් පටිති # ක්}}</translation>
diff --git a/chrome/app/resources/generated_resources_sk.xtb b/chrome/app/resources/generated_resources_sk.xtb
index f43c803..f045124 100644
--- a/chrome/app/resources/generated_resources_sk.xtb
+++ b/chrome/app/resources/generated_resources_sk.xtb
@@ -974,6 +974,7 @@
 <translation id="1697150536837697295">Umenie</translation>
 <translation id="1697686431566694143">Upraviť súbor</translation>
 <translation id="1698796500103229697">&amp;Spôsoby platby</translation>
+<translation id="1698899521169711967">Kurzorové prehliadanie</translation>
 <translation id="1699807488537653303">Opravte chybu hesla</translation>
 <translation id="1700201317341192482">Odstránenie virtuálnej karty</translation>
 <translation id="1700517974991662022">Navštívené</translation>
@@ -2472,6 +2473,7 @@
 <translation id="2771816809568414714">Syr</translation>
 <translation id="2772936498786524345">Rafinovaný</translation>
 <translation id="2773288106548584039">Podpora starších prehliadačov</translation>
+<translation id="2773621783913034737">Deaktivovať karty</translation>
 <translation id="2773802008104670137">Tento typ súboru môže poškodiť váš počítač.</translation>
 <translation id="2775104091073479743">Upraviť odtlačky prstov</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{Rozšírenie <ph name="EXTENSION" /> malo prístup k zariadeniam}=1{Rozšírenie <ph name="EXTENSION" /> má prístup k {0} zariadeniu}few{Rozšírenie <ph name="EXTENSION" /> má prístup k {0} zariadeniam}many{Extension "<ph name="EXTENSION" />" is accessing {0} devices}other{Rozšírenie <ph name="EXTENSION" /> má prístup k {0} zariadeniam}}</translation>
@@ -2552,6 +2554,7 @@
 <translation id="2830528677948328648">Spravovať účet &amp;Google</translation>
 <translation id="2831430281393059038">Zariadenie je podporované</translation>
 <translation id="2832124733806557606">Vaše dieťa sa môže prihlásiť do zariadenia alebo ho odomknúť kódom PIN.</translation>
+<translation id="2833144527504272627">Navigácia textovým kurzorom</translation>
 <translation id="2835177225987815960">Aktuálne nastavenie prehľadávania bude resetované vrátane všetkých pridelených prepínačov a predvolieb rýchlosti automatického prehľadávania.</translation>
 <translation id="2835547721736623118">Služba rozpoznávania reči</translation>
 <translation id="2835761321523638096">Čítanie a zmena vstupov v čitateľskom zozname</translation>
@@ -4108,6 +4111,7 @@
 <translation id="3978325380690188371">Režim uzamknutia klávesa nie je k dispozícii, keď je čítačka ChromeVox zapnutá</translation>
 <translation id="3979395879372752341">Bolo pridané nové rozšírenie (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326">Povoliť <ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">Skryť tieto karty</translation>
 <translation id="3981058120448670012">Zariadeniam v okolí sa na <ph name="REMAINING_TIME" /> zobrazuje ako <ph name="DEVICE_NAME" />...</translation>
 <translation id="3981760180856053153">Zadali ste neplatný typ uloženia.</translation>
 <translation id="3982375475032951137">Nastavte si prehliadač niekoľkými jednoduchými krokmi</translation>
@@ -6299,6 +6303,7 @@
 <translation id="5642508497713047">Podpisovateľ CRL</translation>
 <translation id="5643191124441701136">Bezpečnostný kód nájdete na prednej strane karty</translation>
 <translation id="5643321261065707929">Meraná sieť</translation>
+<translation id="5643717184207603910">Zaistenie rýchleho výkonu</translation>
 <translation id="5646376287012673985">Poloha</translation>
 <translation id="5646558797914161501">Obchodník</translation>
 <translation id="5648021990716966815">Konektor mikrofónu</translation>
@@ -6403,6 +6408,7 @@
 <translation id="5733109311583381874">Ak chcete prispôsobiť kandidátov konverzie, pridajte do používateľského slovníka vlastné slová.</translation>
 <translation id="5734362860645681824">Komunikácia</translation>
 <translation id="5734697361979786483">Pridať zdieľanie súboru</translation>
+<translation id="5735513236153491131">Zvýšiť</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{Tieto údaje alebo vaše zariadenie nespĺňa niektoré pravidlá zabezpečenia vašej organizácie. Zistite od správcu, čo je treba opraviť.}=1{Tento súbor alebo vaše zariadenie nespĺňa niektoré pravidlá zabezpečenia vašej organizácie. Zistite od správcu, čo je treba opraviť.}few{Tieto súbory nespĺňajú niektoré pravidlá zabezpečenia vašej organizácie. Zistite od správcu, čo je treba opraviť.}many{Tieto súbory nespĺňajú niektoré pravidlá zabezpečenia vašej organizácie. Zistite od správcu, čo je treba opraviť.}other{Tieto súbory nespĺňajú niektoré pravidlá zabezpečenia vašej organizácie. Zistite od správcu, čo je treba opraviť.}}</translation>
 <translation id="5738093759615225354">Tento prístupový kľúč potrebujete na prihlásenie do počítača</translation>
 <translation id="5739017626473506901">Ak chce dieťaťu <ph name="USER_NAME" /> pomôcť pridať školský účet, prihláste sa</translation>
@@ -8218,6 +8224,7 @@
 <translation id="7114054701490058191">Heslá sa nezhodujú</translation>
 <translation id="7114648273807173152">Do účtu Google sa môžete prihlásiť pomocou funkcie Smart Lock v časti Nastavenia &gt; Pripojené zariadenia &gt; Váš telefón &gt; Smart Lock.</translation>
 <translation id="7115361495406486998">Žiadne dostupné kontakty</translation>
+<translation id="7115731767122970828">Zvýšiť</translation>
 <translation id="7116554090938189816">Certifikát SSL tlačiarne vypršal. Reštartujte tlačiareň a skúste to znova.</translation>
 <translation id="7117228822971127758">Skúste to neskôr</translation>
 <translation id="7118268675952955085">snímka obrazovky</translation>
@@ -8373,6 +8380,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /></translation>
 <translation id="7246230585855757313">Bezpečnostný kľúč opäť vložte a skúste to znova</translation>
 <translation id="724835896049478274">Účty dostupné pre aplikácie pre Android</translation>
+<translation id="7248802599439396696">Deaktivovať karty</translation>
 <translation id="7249197363678284330">Toto nastavenie môžete zmeniť na paneli s adresou.</translation>
 <translation id="7249764475759804559">Zahŕňať túto aplikáciu ako možnosť pri otváraní súborov</translation>
 <translation id="7250616558727237648">Zariadenie, s ktorým položku zdieľate, neodpovedalo. Skúste to znova.</translation>
@@ -9967,6 +9975,7 @@
 <translation id="8390392581097975659">Inštaluje sa softvér skenera</translation>
 <translation id="8390449457866780408">Server je nedostupný.</translation>
 <translation id="8391218455464584335">Vinyl</translation>
+<translation id="8391918125842702622">Upozornenie na výkonnostný problém</translation>
 <translation id="8392726714909453725">Nastavenia počúvania vybraného textu</translation>
 <translation id="8393511274964623038">Ukončiť doplnok</translation>
 <translation id="839363317075970734">Podrobnosti o zariadení s rozhraním Bluetooth</translation>
@@ -10067,6 +10076,7 @@
 <translation id="8466052016039127321">Predchádzajúca relácia sa nedá obnoviť</translation>
 <translation id="8467326454809944210">Vybrať iný jazyk</translation>
 <translation id="8468087214092422866">Nemôžu vyhľadávať zariadenia s rozhraním Bluetooth</translation>
+<translation id="8469863130477774813">K dispozícii je zvýšenie výkonu</translation>
 <translation id="8470513973197838199">Uložené heslá pre <ph name="ORIGIN" /></translation>
 <translation id="8471525937465764768">Weby sa zvyčajne pripájajú k zariadeniam USB, aby mohli poskytovať funkcie, ako tlač dokumentu alebo uloženie do zariadenia</translation>
 <translation id="8471959340398751476">Zľavy sú vypnuté. Môžete ich zapnúť v ponuke prispôsobenia.</translation>
diff --git a/chrome/app/resources/generated_resources_sr-Latn.xtb b/chrome/app/resources/generated_resources_sr-Latn.xtb
index 0f24c2e..3a7c48a9 100644
--- a/chrome/app/resources/generated_resources_sr-Latn.xtb
+++ b/chrome/app/resources/generated_resources_sr-Latn.xtb
@@ -67,6 +67,7 @@
 <translation id="1043505821207197890">Došlo je do greške. Linux je možda samo delimično nadograđen. Pregledajte evidenciju za više informacija. Evidencija je sačuvana u odeljku Fajlovi &gt; Moji fajlovi &gt; <ph name="LOG_FILE" /></translation>
 <translation id="104419033123549300">Stil mape tastera</translation>
 <translation id="1046521327593783388">{NUM_PASSWORDS,plural, =1{Uvezena je 1 lozinka u <ph name="BRAND" /> na ovom uređaju}one{Uvezena je {NUM_PASSWORDS} lozinka u <ph name="BRAND" /> na ovom uređaju}few{Uvezene su {NUM_PASSWORDS} lozinke u <ph name="BRAND" /> na ovom uređaju}other{Uvezeno je {NUM_PASSWORDS} lozinki u <ph name="BRAND" /> na ovom uređaju}}</translation>
+<translation id="1046572983040892965">Prozor je pomeren nagore i ulevo</translation>
 <translation id="104710386808485638">Želite li da restartujete Linux?</translation>
 <translation id="1047431265488717055">Kopiraj tek&amp;st linka</translation>
 <translation id="1048286738600630630">Prikazi</translation>
@@ -187,6 +188,7 @@
 <translation id="1130589222747246278"><ph name="WINDOW_TITLE" /> – deo grupe <ph name="GROUP_NAME" /></translation>
 <translation id="1130676589211693127">Nivo napunjenosti baterije za desnu <ph name="PERCENTAGE" />%.</translation>
 <translation id="1133418583142946603">Dodaj aktuelnu karticu</translation>
+<translation id="1134363466745332968">Istoriju pregledanja možete da pretražujete na osnovu opšteg sadržaja stranice, a ne samo na osnovu naslova i URL-a stranice. Ovo vam daje poboljšane rezultate, bilo da pretražujete istoriju pregledanja u traci za adresu koristeći @history ili sa stranice Istorija.</translation>
 <translation id="1136179794690960030"><ph name="EMOJI_NAME" />. <ph name="EMOJI_INDEX" /> od <ph name="EMOJI_COUNT" />.</translation>
 <translation id="1136712381129578788">Bezbednosni ključ je zaključan jer ste previše puta uneli pogrešan PIN. Da biste ga otključali, uklonite ga, pa ga ponovo umetnite.</translation>
 <translation id="1137589305610962734">privremeni podaci</translation>
@@ -218,6 +220,7 @@
 <translation id="1158080958325422608">Prebaci na velika slova</translation>
 <translation id="1158238185437008462">Prikaži uspomene</translation>
 <translation id="1159879754517035595">Upravljajte podešavanjima dodataka</translation>
+<translation id="1160800016654917722">Prozor je pomeren nadole i ulevo</translation>
 <translation id="1161575384898972166">Prijavite se na <ph name="TOKEN_NAME" /> da biste izvezli sertifikat klijenta.</translation>
 <translation id="116173250649946226">Administrator je podesio podrazumevanu temu koja ne može da se menja.</translation>
 <translation id="1162213688509394031">Sakrijte traku naslova</translation>
@@ -326,6 +329,7 @@
 <translation id="1227993798763400520">Prebacivanje nije uspelo. Probajte ponovo.</translation>
 <translation id="1230417814058465809">Standardna zaštita je uključena. Koristite naprednu zaštitu da biste se dodatno zaštitili.</translation>
 <translation id="1231426483209637778">Zapamtićemo mrežu kada sledeći put koristite <ph name="DEVICE_TYPE" /></translation>
+<translation id="1231572247662419826">Sajtovi mogu da traže da snimaju i koriste unos mišem</translation>
 <translation id="1232569758102978740">Bez naslova</translation>
 <translation id="1233497634904001272">Ponovo dodirnite bezbednosni ključ da biste dovršili zahtev.</translation>
 <translation id="1233721473400465416">Lokalitet</translation>
@@ -546,6 +550,7 @@
 <translation id="1407069428457324124">Tamna tema</translation>
 <translation id="1407135791313364759">Otvori sve</translation>
 <translation id="140723521119632973">Mobilna aktivacija</translation>
+<translation id="1407970155431887387">Kliknite da biste otvorili dijalog za izmene za <ph name="SEARCH_ENGINE_NAME" /></translation>
 <translation id="1408504635543854729">Istražite sadržaj uređaja u aplikaciji Datoteke. Administrator ograničava sadržaj i sadržaj ne može da se menja.</translation>
 <translation id="1408980562518920698">Upravljajte ličnim podacima</translation>
 <translation id="1410197035576869800">Ikona aplikacije</translation>
@@ -1106,6 +1111,7 @@
 <translation id="1803531841600994172">Jezik na koji želite da prevodite</translation>
 <translation id="1803545009660609783">Ponovo obučite</translation>
 <translation id="1804195280859010019">Videćete korisnije informacije ili predloge u funkcijama kao što je bočna tabla Google pretrage</translation>
+<translation id="180441032496361123">Kliknite da biste aktivirali <ph name="SEARCH_ENGINE_NAME" /></translation>
 <translation id="1805738995123446102">Kartica u pozadini koristi mikrofon</translation>
 <translation id="1805822111539868586">Proverite prikaze</translation>
 <translation id="1805888043020974594">Server za štampanje</translation>
@@ -1179,6 +1185,7 @@
 <translation id="1848219224579402567">Odjavi me kad se poklopac zatvori</translation>
 <translation id="184862733444771842">Zahtev za funkciju</translation>
 <translation id="1849016657376805933">Bilo koji HID uređaj</translation>
+<translation id="1849022541429818637">Dozvoljeno im je da snimaju i koriste unos mišem</translation>
 <translation id="1850145825777333687">Akreditivi za uređaj</translation>
 <translation id="1850508293116537636">Okreći &amp;u smeru kretanja kazaljke na satu</translation>
 <translation id="185111092974636561"><ph name="BEGIN_PARAGRAPH1" />Pre nego što se registrujete, treba da obrišete TPM da bi <ph name="DEVICE_OS" /> mogao da preuzme vlasništvo nad uređajem.<ph name="END_PARAGRAPH1" />
@@ -1724,6 +1731,7 @@
 <translation id="2251809247798634662">Novi prozor bez arhiviranja</translation>
 <translation id="2252017960592955005">Zaštita od pregleda (beta)</translation>
 <translation id="2253318212986772520">Preuzimanje PPD-a za štampač <ph name="PRINTER_NAME" /> nije uspelo.</translation>
+<translation id="2253797136365098595">Saznajte više o pretragama istorije</translation>
 <translation id="2253927598983295051">Odaberite šta ćete deliti sa aplikacijom <ph name="APP_NAME" /></translation>
 <translation id="2255077166240162850">Ovaj uređaj je zaključan na neki drugi domen ili režim.</translation>
 <translation id="2255317897038918278">Microsoft označavanje vremena</translation>
@@ -2118,6 +2126,7 @@
 <translation id="2515586267016047495">Alt</translation>
 <translation id="251722524540674480">Potvrdite korisničko ime</translation>
 <translation id="2517472476991765520">Skeniraj</translation>
+<translation id="2517851527960406492">Sajtovi mogu da traže da snimaju i koriste unos sa tastature</translation>
 <translation id="2518024842978892609">Koristi sertifikate klijenta</translation>
 <translation id="2518620532958109495">Dozvoljeno im je da automatski uđu u režim celog ekrana</translation>
 <translation id="2519250377986324805">Prikaži kako</translation>
@@ -2296,6 +2305,7 @@
 <translation id="265748523151262387">Ostanite povezani sa telefonom</translation>
 <translation id="2657612187216250073">Podešavanja pristupačnosti pokazivača</translation>
 <translation id="2658941648214598230">Želite da vidite originalni sadržaj?</translation>
+<translation id="2659694935349347275">Prozor je pomeren nadole i nadesno</translation>
 <translation id="2659971421398561408">Promena veličine diska za Crostini</translation>
 <translation id="2660115748527982021">Savet: Mnoge Android aplikacije su dostupne na vebu. Proverite dostupnost aplikacije ili veb-sajta programera.</translation>
 <translation id="2660779039299703961">Događaj</translation>
@@ -2341,6 +2351,7 @@
 <translation id="2690024944919328218">Prikazuj opcije jezika</translation>
 <translation id="2691385045260836588">Model</translation>
 <translation id="2691440343905273290">Promenite podešavanja unosa</translation>
+<translation id="2691811116976138467">Sajtovi koriste ovu funkciju za snimanje i korišćenje unosa sa tastature, na primer, za igre ili aplikacije za udaljene računare</translation>
 <translation id="2692503699962701720">Promeni intonaciju prilikom izgovora tipova elemenata i formatiranog teksta</translation>
 <translation id="2692901429679246677">Tirkizna</translation>
 <translation id="2693134906590795721">Zvukovi punjenja</translation>
@@ -3110,6 +3121,7 @@
 <translation id="3261090393424563833">Povećaj stopu</translation>
 <translation id="3261268979727295785">Možete da dodate roditeljski nadzor za stariju decu kada dovršite podešavanje. Pronaći ćete informacije o roditeljskom nadzoru u aplikaciji Istražite.</translation>
 <translation id="3261832505033014216">Pristupni ključ za <ph name="USER_EMAIL" /></translation>
+<translation id="3262261769033093854">Ne dozvoljavaj sajtovima da snimaju i koriste unos mišem</translation>
 <translation id="3262336253311870293">Pošto ovim nalogom upravlja <ph name="DOMAIN" />, nećete biti odjavljeni sa Google naloga. Obeleživači, istorija, lozinke i druga podešavanja se više neće sinhronizovati. Međutim, prethodno sinhronizovani podaci se čuvaju na Google nalogu i možete da upravljate njima na <ph name="BEGIN_LINK" />Google kontrolnoj tabli<ph name="END_LINK" />.</translation>
 <translation id="3262986719682892278">Preveliko</translation>
 <translation id="3264544094376351444">Font Sans-serif</translation>
@@ -3423,6 +3435,7 @@
 <translation id="3497501929010263034">USB uređaj prodavca <ph name="VENDOR_NAME" /> (proizvod <ph name="PRODUCT_ID" />)</translation>
 <translation id="3497560059572256875">Deli dudl logotip</translation>
 <translation id="3497915391670770295">Pošalji na uređaje</translation>
+<translation id="3499091376302796297">Dok pregledate sajtove, njihov sadržaj stranica se čuva u šifrovanom obliku na uređaju.</translation>
 <translation id="3500417806337761827">Greška pri instalaciji deljene stavke. Previše SMB deljenih stavki je već instalirano.</translation>
 <translation id="3500764001796099683">Omogući izolovane veb-aplikacije</translation>
 <translation id="350397915809787283">Ako nemate nalog, izaberite prvu opciju da biste ga otvorili.</translation>
@@ -4230,6 +4243,7 @@
 <translation id="4062561150282203854">Sinhronizujte<ph name="DEVICE_TYPE" /> aplikacije, podešavanja i drugo</translation>
 <translation id="4065876735068446555">Mreža koju koristite (<ph name="NETWORK_ID" />) će možda zahtevati da posetite stranicu za prijavljivanje.</translation>
 <translation id="4066207411788646768">Proverite vezu da biste videli dostupne štampače na mreži</translation>
+<translation id="4066458014195202324">Dozvoljeno im je da snimaju i koriste unos sa tastature</translation>
 <translation id="4067839975993712852">Označi aktuelnu karticu kao pročitanu</translation>
 <translation id="4068776064906523561">Sačuvani otisci prstiju</translation>
 <translation id="4070132839822635162">Ne prijavljuj me</translation>
@@ -4369,6 +4383,7 @@
 <translation id="4184803915913850597">HID uređaj (<ph name="VENDOR_ID" />:<ph name="PRODUCT_ID" />)</translation>
 <translation id="4186749321808907788"><ph name="QUERY_NAME" /> – <ph name="DEFAULT_SEARCH_ENGINE_NAME" /> pretraga</translation>
 <translation id="4187424053537113647">Podešava se <ph name="APP_NAME" />…</translation>
+<translation id="4190446002599583608">Pretraga istorije, koju omogućava AI</translation>
 <translation id="4190492351494485814">Za početno podešavanje treba da se povežete na internet da bi fajlovi mogli da se sinhronizuju sa Chromebook-om</translation>
 <translation id="4190828427319282529">Isticanje fokusa tastature</translation>
 <translation id="4191892134568599822">Želite da primate sadržaj uz <ph name="FEATURE_NAME" />?</translation>
@@ -4864,6 +4879,7 @@
 <translation id="4562155214028662640">Dodaj digitalni otisak</translation>
 <translation id="4562155266774382038">Odbacite predlog</translation>
 <translation id="4562364000855074606">Blokirajte aplikacije instalirane na ovom uređaju <ph name="DEVICE_TYPE" />. Da biste ograničili preuzimanje aplikacija ili sadržaja, idite u podešavanja Google Play-a. <ph name="BEGIN_LINK_LEARN_MORE" />Saznajte više<ph name="END_LINK_LEARN_MORE" /></translation>
+<translation id="4562925006886238518">Koristite svakodnevni jezik da biste pretraživali istoriju pregledanja i pronalazili sajtove koje ste posetili.</translation>
 <translation id="4563210852471260509">Početni jezik za unos je kineski</translation>
 <translation id="4563382028841851106">Ukloni sa naloga</translation>
 <translation id="4563880231729913339">Prst 3</translation>
@@ -4915,6 +4931,7 @@
 <translation id="4598549027014564149">Kada ste u režimu bez arhiviranja, sajtovi ne mogu da koriste kolačiće da bi videli vaše aktivnosti pregledanja na svim sajtovima, čak i na srodnim sajtovima. Aktivnosti pregledanja se ne koriste za stvari kao što je personalizovanje oglasa. Funkcije na nekim sajtovima mogu da ne rade.</translation>
 <translation id="4598556348158889687">Upravljanje memorijskim prostorom</translation>
 <translation id="4598776695426288251">Dostupan je WiFi preko više uređaja</translation>
+<translation id="4599323532350839656">Nije dozvoljeno snimanje i korišćenje unosa sa tastature</translation>
 <translation id="4600071396330666617">Broj predloga</translation>
 <translation id="4601095002996233687">Detaljna skeniranja sumnjivih preuzimanja.</translation>
 <translation id="4601426376352205922">Označi kao nepročitano</translation>
@@ -5228,6 +5245,7 @@
 <translation id="484462545196658690">Automatski</translation>
 <translation id="4846628405149428620">Izaberite gde ovaj sajt može da čuva izmene</translation>
 <translation id="4846680374085650406">Poštujete preporuku administratora za ovo podešavanje.</translation>
+<translation id="4846897209694249040">Nije im dozvoljeno da snimaju i koriste unos mišem</translation>
 <translation id="4847242508757499006">Odaberite Probaj ponovo ili odaberite Otvori u osnovnom uređivaču da biste koristili opcije ograničenog prikaza i izmena.</translation>
 <translation id="4847742514726489375">Umanjeno kretanje</translation>
 <translation id="4848191975108266266">Komanda „Hej Google“ za Google pomoćnik</translation>
@@ -5348,6 +5366,7 @@
 <translation id="4927753642311223124">Nema šta da se vidi ovde. Nastavite dalje.</translation>
 <translation id="4928629450964837566">Koristite bezbedniju lozinku</translation>
 <translation id="4929386379796360314">Odredišta za štampanje</translation>
+<translation id="4930406318748549391">Položaj bočne table</translation>
 <translation id="4930447554870711875">Programeri</translation>
 <translation id="4930714375720679147">Uključi</translation>
 <translation id="4931347390544064118">Bezbedne veze možda neće uvek biti dostupne kada koristite podrazumevanu mrežu. Razmislite o izboru drugog dobavljača da biste bili sigurni da uvek koristite bezbednu vezu.</translation>
@@ -5696,6 +5715,7 @@
 <translation id="5195074424945754995">URL-ovi koji se podudaraju sa ovim pravilima neće pokrenuti promenu pregledača i mogu da se otvaraju ili u pregledaču <ph name="BROWSER_NAME" /> ili u pregledaču <ph name="ALTERNATIVE_BROWSER_NAME" />.</translation>
 <translation id="5195863934285556588"><ph name="BEGIN_PARAGRAPH1" />Google usluga lokacije koristi izvore kao što su WiFi mreže, mobilne mreže i senzori da bi odredila približnu lokaciju ovog uređaja.<ph name="END_PARAGRAPH1" />
     <ph name="BEGIN_PARAGRAPH2" />Možete da isključite Android lokaciju na ovom uređaju u bilo kom trenutku ako odete u Podešavanja &gt; Aplikacije &gt; Google Play prodavnica &gt; Upravljajte Android podešavanjima &gt; Bezbednost i lokacija &gt; Lokacija. Ako isključite Google preciznost lokacije u istom meniju, možete i da isključite korišćenje WiFi mreža, mobilnih mreža i senzora za Android lokaciju.<ph name="END_PARAGRAPH2" /></translation>
+<translation id="5197150086680615104">Predloge za grupu kartica možete da potražite u svakom trenutku</translation>
 <translation id="5197255632782567636">Internet</translation>
 <translation id="5198430103906431024">Šaljite podatke o korišćenju i dijagnostičke podatke. Ovaj uređaj trenutno automatski šalje podatke o dijagnostici, uređaju i korišćenju aplikacija Google-u. To doprinosi održavanju stabilnosti sistema i aplikacije i drugim podešavanjima. Neki objedinjeni podaci će takođe pomoći Google aplikacijama i partnerima, poput Android programera. Ako uključite podešavanje dodatne aktivnosti na vebu i u aplikacijama, ti podaci će se možda čuvati na Google nalogu.</translation>
 <translation id="5199729219167945352">Eksperimenti</translation>
@@ -7211,6 +7231,7 @@
 <translation id="6341850831632289108">Otkrivanje vaše fizičke lokacije</translation>
 <translation id="6342069812937806050">Malopre</translation>
 <translation id="6343003829431264373">Samo stranice sa parnim brojevima</translation>
+<translation id="6343981313228733146">Prozor je pomeren nagore i nadesno</translation>
 <translation id="6344170822609224263">Pristup listi mrežnih veza</translation>
 <translation id="6344576354370880196">Sačuvani štampači</translation>
 <translation id="6344608411615208519">Roditelj <ph name="BEGIN_LINK" />upravlja pregledačem<ph name="END_LINK" /></translation>
@@ -7795,6 +7816,7 @@
 <translation id="6798780071646309401">caps lock je uključen</translation>
 <translation id="6798954102094737107">Dodatna komponenta: <ph name="PLUGIN_NAME" /></translation>
 <translation id="679905836499387150">Skrivena dugmad na traci s alatkama</translation>
+<translation id="6800623240347398745">Ne postoji grupa za tu karticu, ali pogledajte ove grupe</translation>
 <translation id="6800893479155997609">Najbolje aplikacije za <ph name="DEVICE_TYPE" /></translation>
 <translation id="6801308659697002152">{NUM_EXTENSIONS,plural, =1{Odaberite da li ovaj dodatak može da čita i menja ovaj sajt}one{Odaberite da li ovi dodaci mogu da čitaju ili menjaju ovaj sajt}few{Odaberite da li ovi dodaci mogu da čitaju ili menjaju ovaj sajt}other{Odaberite da li ovi dodaci mogu da čitaju ili menjaju ovaj sajt}}</translation>
 <translation id="6801435275744557998">Kalibracija dodirnog ekrana</translation>
@@ -7836,6 +7858,7 @@
 <translation id="6818920801736417483">Želite da sačuvate lozinke?</translation>
 <translation id="6820079682647046800">Kerberos potvrda identiteta nije uspela</translation>
 <translation id="6821439254917412979">Otkačite <ph name="EXTENSION_NAME" /></translation>
+<translation id="6823097506504975234">Kada pretražujete istoriju pregledanja, termini za pretragu istorije, sadržaj stranice sa najboljim podudaranjima i generisani rezultati modela se šalju Google-u i mogu ih videti ljudi koji pregledaju da bi poboljšali ovu funkciju.</translation>
 <translation id="6823174134746916417">Dodirni za klik na tačpedu</translation>
 <translation id="6823561724060793716">Na traci za adresu možete da otvorite informacije o stranici da biste videli dodatne informacije o stranici koju posećujete</translation>
 <translation id="6824564591481349393">Kopiraj imejl adresu</translation>
@@ -8867,6 +8890,7 @@
 <translation id="761530003705945209">Pravite rezervne kopije na Google disku. Lako vratite podatke ili pređite na drugi uređaj u bilo kom trenutku. Rezervna kopija obuhvata podatke aplikacija. Rezervne kopije se otpremaju na Google i šifruju pomoću lozinke za Google nalog.</translation>
 <translation id="7615365294369022248">Došlo je do greške pri dodavanju naloga</translation>
 <translation id="7616214729753637086">Uređaj se registruje...</translation>
+<translation id="7616964248951412133">Sajtovi koriste ovu funkciju za snimanje i korišćenje unosa mišem, na primer, za igre ili aplikacije za udaljene računare</translation>
 <translation id="7617263010641145920">Uključite Play prodavnicu</translation>
 <translation id="7617648809369507487">Koristi nenametljivu razmenu poruka</translation>
 <translation id="7619937211696316184">Održavanje je završeno</translation>
@@ -9370,6 +9394,7 @@
 <translation id="7959665254555683862">Nova kartica bez arhiviranja</translation>
 <translation id="7961015016161918242">Nikad</translation>
 <translation id="7963001036288347286">Ubrzavanje tačpeda</translation>
+<translation id="7963513503134856713">Prozor je pomeren nadesno</translation>
 <translation id="7963608432878156675">Ovo ime je vidljivo drugim uređajima za Bluetooth i mrežne veze</translation>
 <translation id="7963826112438303517">Pomoćnik koristi te snimke i glasovne zahteve da bi napravio i ažurirao glasovni model, koji se čuva samo na onim uređajima na kojima ste uključili Voice Match. Izbrišite ili ponovo uvežbajte glasovne aktivnosti u podešavanjima Pomoćnika.</translation>
 <translation id="7964458523224581615">Tamnozelena</translation>
@@ -10023,6 +10048,7 @@
 <translation id="8428271547607112339">Dodajte školski nalog</translation>
 <translation id="8428634594422941299">Važi</translation>
 <translation id="84297032718407999">Odjavićete se za <ph name="LOGOUT_TIME_LEFT" /></translation>
+<translation id="8429928917752180743">Još opcija za: <ph name="EXTENSION_NAME" /></translation>
 <translation id="8431190899827883166">Prikaz dodira</translation>
 <translation id="843173223122814223">Pravite pozadine pomoću veštačke inteligencije</translation>
 <translation id="8433186206711564395">Mrežna podešavanja</translation>
@@ -10113,6 +10139,7 @@
 <translation id="8498214519255567734">Omogućava da lakše pregledate sadržaj ekrana ili da čitate pri prigušenom svetlu</translation>
 <translation id="8499083585497694743">Uključi zvuk mikrofona</translation>
 <translation id="8500044868721690197">Ovom sajtu je onemogućeno da kontroliše i reprogramira MIDI uređaje</translation>
+<translation id="8500123638242682652">Prozor je pomeren nagore</translation>
 <translation id="8502536196501630039">Da biste koristili aplikacije sa Google Play-a, prvo morate da vratite aplikacije. Neki podaci su možda izgubljeni.</translation>
 <translation id="8503813439785031346">Korisničko ime</translation>
 <translation id="850382998924680137">Pogledano danas</translation>
@@ -10212,6 +10239,7 @@
 <translation id="8577052309681449949">Automatski klikovi, veličina kursora, boja kursora i drugo</translation>
 <translation id="8578639784464423491">Dozvoljeno je najviše 99 znakova</translation>
 <translation id="8581809080475256101">Pritisnite da biste išli unapred ili otvorite kontekstualni meni da biste videli istoriju</translation>
+<translation id="8583122761178401199">Ne dozvoljavaj sajtovima da snimaju i koriste unos sa tastature</translation>
 <translation id="8584280235376696778">&amp;Otvori video snimak na novoj kartici</translation>
 <translation id="858451212965845553">Pošalji na uređaje</translation>
 <translation id="8584843865238667486">HID uređaji sa korišćenjem <ph name="USAGE" /> sa stranice o korišćenju <ph name="USAGE_PAGE" /></translation>
@@ -10227,6 +10255,7 @@
 <translation id="859246725979739260">Ovom sajtu je zabranjeno da pristupa lokaciji.</translation>
 <translation id="8593450223647418235">Nećete moći da otvarate fajlove u Microsoft-u 365 dok se podešavanje ne završi.</translation>
 <translation id="8593686980889923154">Aplikacija <ph name="APP_NAME" /> je blokirana na uređaju <ph name="DEVICE_TYPE" /></translation>
+<translation id="8596400097994526901">Još radnji za <ph name="SEARCH_ENGINE_NAME" /></translation>
 <translation id="8596540852772265699">Prilagođene datoteke</translation>
 <translation id="8597845839771543242">Format svojstva:</translation>
 <translation id="8598249292448297523">štampaj</translation>
@@ -10312,6 +10341,7 @@
 <translation id="8657393004602556571">Želite da odbacite povratne informacije?</translation>
 <translation id="8657542881463614516">Koristite pokret prevlačenja da biste se kretali između stranica</translation>
 <translation id="8659608856364348875">Kontakti za <ph name="FEATURE_NAME" /></translation>
+<translation id="8659609431223166673">Prozor je pomeren nadole</translation>
 <translation id="8661290697478713397">Otvori link u prozoru za pre&amp;gledanje bez arhiviranja</translation>
 <translation id="8662474268934425487">Prijavite se na <ph name="SITE_ETLD_PLUS_ONE" /></translation>
 <translation id="8662671328352114214">Pridružite se <ph name="TYPE" /> mreži</translation>
@@ -10358,6 +10388,7 @@
 <translation id="8682730193597992579">Štampač <ph name="PRINTER_NAME" /> je povezan i spreman</translation>
 <translation id="8684471948980641888">Dozvoli sinhronizaciju na mrežama sa ograničenjem</translation>
 <translation id="8685540043423825702">Chrome profil</translation>
+<translation id="8685882652128627032">Kliknite da biste otvorili dijalog Dodajte pretragu sajta</translation>
 <translation id="8686142379631285985">Prijavljeni ste kao <ph name="BEGIN_BOLD" /><ph name="DRIVE_ACCOUNT_EMAIL" /><ph name="END_BOLD" /></translation>
 <translation id="8687103160920393343">Otkažite fajl <ph name="FILE_NAME" /></translation>
 <translation id="8687527282898211955">Podesite PIN</translation>
@@ -10548,6 +10579,7 @@
 <translation id="881799181680267069">Sakrij druge</translation>
 <translation id="8818152010000655963">Pozadina</translation>
 <translation id="8818958672113348984">Potvrdi pomoću telefona</translation>
+<translation id="8818988764764862764">Prozor je pomeren ulevo</translation>
 <translation id="8819510664278523111">EID uređaja je <ph name="EID_NUMBER" />, IMEI uređaja je <ph name="IMEI_NUMBER" />, a serijski broj uređaja je <ph name="SERIAL_NUMBER" />. Ove brojeve možete da koristite da biste aktivirali uslugu.</translation>
 <translation id="8820817407110198400">Obeleživači</translation>
 <translation id="8821045908425223359">Automatski konfiguriši IP adresu</translation>
@@ -10626,6 +10658,7 @@
 <translation id="8872506776304248286">Otvori u aplikaciji</translation>
 <translation id="8872774989979382243">Zvuk je isključen. Uključite zvuk.</translation>
 <translation id="887292602123626481">Saznajte više o podrazumevanim pretraživačima</translation>
+<translation id="8873075098103007382">Ostanite organizovani pomoću grupa kartica</translation>
 <translation id="8874341931345877644">Prebacujte na uređaj:</translation>
 <translation id="8874790741333031443">Probajte privremeno da dozvolite kolačiće treće strane, što znači slabiju zaštitu pregledanja, ali veću verovatnoću da će funkcije sajta raditi na očekivani način.</translation>
 <translation id="8875520811099717934">Nadogradnja Linux-a</translation>
@@ -10758,6 +10791,7 @@
 <translation id="8973557916016709913">Ukloni nivo zumiranja</translation>
 <translation id="8973596347849323817">Možete da prilagodite ovaj uređaj prema potrebama. Te funkcije pristupačnosti možete kasnije da promenite u Podešavanjima.</translation>
 <translation id="897414447285476047">Odredišna datoteka je nepotpuna zbog problema sa vezom.</translation>
+<translation id="8974261761101622391">Pronađite alternativu za: <ph name="EXTENSION_NAME" /></translation>
 <translation id="897525204902889653">Usluga karantina</translation>
 <translation id="8975396729541388937">Opozovite prijavu u bilo kom trenutku tako što ćete kliknuti na link u imejlovima koje dobijate.</translation>
 <translation id="8975562453115131273">{NUM_OTHER_TABS,plural, =0{„<ph name="TAB_TITLE" />“}=1{„<ph name="TAB_TITLE" />“ i još 1 kartica}one{„<ph name="TAB_TITLE" />“ i još # kartica}few{„<ph name="TAB_TITLE" />“ i još # kartice}other{„<ph name="TAB_TITLE" />“ i još # kartica}}</translation>
diff --git a/chrome/app/resources/generated_resources_sr.xtb b/chrome/app/resources/generated_resources_sr.xtb
index 2fcedcb4..901b852 100644
--- a/chrome/app/resources/generated_resources_sr.xtb
+++ b/chrome/app/resources/generated_resources_sr.xtb
@@ -67,6 +67,7 @@
 <translation id="1043505821207197890">Дошло је до грешке. Linux је можда само делимично надограђен. Прегледајте евиденцију за више информација. Евиденција је сачувана у одељку Фајлови &gt; Моји фајлови &gt; <ph name="LOG_FILE" /></translation>
 <translation id="104419033123549300">Стил мапе тастера</translation>
 <translation id="1046521327593783388">{NUM_PASSWORDS,plural, =1{Увезена је 1 лозинка у <ph name="BRAND" /> на овом уређају}one{Увезена је {NUM_PASSWORDS} лозинка у <ph name="BRAND" /> на овом уређају}few{Увезене су {NUM_PASSWORDS} лозинке у <ph name="BRAND" /> на овом уређају}other{Увезено је {NUM_PASSWORDS} лозинки у <ph name="BRAND" /> на овом уређају}}</translation>
+<translation id="1046572983040892965">Прозор је померен нагоре и улево</translation>
 <translation id="104710386808485638">Желите ли да рестартујете Linux?</translation>
 <translation id="1047431265488717055">Копирај тек&amp;ст линка</translation>
 <translation id="1048286738600630630">Прикази</translation>
@@ -187,6 +188,7 @@
 <translation id="1130589222747246278"><ph name="WINDOW_TITLE" /> – део групе <ph name="GROUP_NAME" /></translation>
 <translation id="1130676589211693127">Ниво напуњености батерије за десну <ph name="PERCENTAGE" />%.</translation>
 <translation id="1133418583142946603">Додај актуелну картицу</translation>
+<translation id="1134363466745332968">Историју прегледања можете да претражујете на основу општег садржаја странице, а не само на основу наслова и URL-а странице. Ово вам даје побољшане резултате, било да претражујете историју прегледања у траци за адресу користећи @history или са странице Историја.</translation>
 <translation id="1136179794690960030"><ph name="EMOJI_NAME" />. <ph name="EMOJI_INDEX" /> од <ph name="EMOJI_COUNT" />.</translation>
 <translation id="1136712381129578788">Безбедносни кључ је закључан јер сте превише пута унели погрешан PIN. Да бисте га откључали, уклоните га, па га поново уметните.</translation>
 <translation id="1137589305610962734">привремени подаци</translation>
@@ -218,6 +220,7 @@
 <translation id="1158080958325422608">Пребаци на велика слова</translation>
 <translation id="1158238185437008462">Прикажи успомене</translation>
 <translation id="1159879754517035595">Управљајте подешавањима додатака</translation>
+<translation id="1160800016654917722">Прозор је померен надоле и улево</translation>
 <translation id="1161575384898972166">Пријавите се на <ph name="TOKEN_NAME" /> да бисте извезли сертификат клијента.</translation>
 <translation id="116173250649946226">Администратор је подесио подразумевану тему која не може да се мења.</translation>
 <translation id="1162213688509394031">Сакријте траку наслова</translation>
@@ -326,6 +329,7 @@
 <translation id="1227993798763400520">Пребацивање није успело. Пробајте поново.</translation>
 <translation id="1230417814058465809">Стандардна заштита је укључена. Користите напредну заштиту да бисте се додатно заштитили.</translation>
 <translation id="1231426483209637778">Запамтићемо мрежу када следећи пут користите <ph name="DEVICE_TYPE" /></translation>
+<translation id="1231572247662419826">Сајтови могу да траже да снимају и користе унос мишем</translation>
 <translation id="1232569758102978740">Без наслова</translation>
 <translation id="1233497634904001272">Поново додирните безбедносни кључ да бисте довршили захтев.</translation>
 <translation id="1233721473400465416">Локалитет</translation>
@@ -546,6 +550,7 @@
 <translation id="1407069428457324124">Тамна тема</translation>
 <translation id="1407135791313364759">Отвори све</translation>
 <translation id="140723521119632973">Мобилна активација</translation>
+<translation id="1407970155431887387">Кликните да бисте отворили дијалог за измене за <ph name="SEARCH_ENGINE_NAME" /></translation>
 <translation id="1408504635543854729">Истражите садржај уређаја у апликацији Датотеке. Администратор ограничава садржај и садржај не може да се мења.</translation>
 <translation id="1408980562518920698">Управљајте личним подацима</translation>
 <translation id="1410197035576869800">Икона апликације</translation>
@@ -1106,6 +1111,7 @@
 <translation id="1803531841600994172">Језик на који желите да преводите</translation>
 <translation id="1803545009660609783">Поново обучите</translation>
 <translation id="1804195280859010019">Видећете корисније информације или предлоге у функцијама као што је бочна табла Google претраге</translation>
+<translation id="180441032496361123">Кликните да бисте активирали <ph name="SEARCH_ENGINE_NAME" /></translation>
 <translation id="1805738995123446102">Картица у позадини користи микрофон</translation>
 <translation id="1805822111539868586">Проверите приказе</translation>
 <translation id="1805888043020974594">Сервер за штампање</translation>
@@ -1179,6 +1185,7 @@
 <translation id="1848219224579402567">Одјави ме кад се поклопац затвори</translation>
 <translation id="184862733444771842">Захтев за функцију</translation>
 <translation id="1849016657376805933">Било који HID уређај</translation>
+<translation id="1849022541429818637">Дозвољено им је да снимају и користе унос мишем</translation>
 <translation id="1850145825777333687">Акредитиви за уређај</translation>
 <translation id="1850508293116537636">Окрећи &amp;у смеру кретања казаљке на сату</translation>
 <translation id="185111092974636561"><ph name="BEGIN_PARAGRAPH1" />Пре него што се региструјете, треба да обришете TPM да би <ph name="DEVICE_OS" /> могао да преузме власништво над уређајем.<ph name="END_PARAGRAPH1" />
@@ -1724,6 +1731,7 @@
 <translation id="2251809247798634662">Нови прозор без архивирања</translation>
 <translation id="2252017960592955005">Заштита од прегледа (бета)</translation>
 <translation id="2253318212986772520">Преузимање PPD-а за штампач <ph name="PRINTER_NAME" /> није успело.</translation>
+<translation id="2253797136365098595">Сазнајте више о претрагама историје</translation>
 <translation id="2253927598983295051">Одаберите шта ћете делити са апликацијом <ph name="APP_NAME" /></translation>
 <translation id="2255077166240162850">Овај уређај је закључан на неки други домен или режим.</translation>
 <translation id="2255317897038918278">Microsoft означавање времена</translation>
@@ -2118,6 +2126,7 @@
 <translation id="2515586267016047495">Alt</translation>
 <translation id="251722524540674480">Потврдите корисничко име</translation>
 <translation id="2517472476991765520">Скенирај</translation>
+<translation id="2517851527960406492">Сајтови могу да траже да снимају и користе унос са тастатуре</translation>
 <translation id="2518024842978892609">Користи сертификате клијента</translation>
 <translation id="2518620532958109495">Дозвољено им је да аутоматски уђу у режим целог екрана</translation>
 <translation id="2519250377986324805">Прикажи како</translation>
@@ -2296,6 +2305,7 @@
 <translation id="265748523151262387">Останите повезани са телефоном</translation>
 <translation id="2657612187216250073">Подешавања приступачности показивача</translation>
 <translation id="2658941648214598230">Желите да видите оригинални садржај?</translation>
+<translation id="2659694935349347275">Прозор је померен надоле и надесно</translation>
 <translation id="2659971421398561408">Промена величине диска за Crostini</translation>
 <translation id="2660115748527982021">Савет: Многе Android апликације су доступне на вебу. Проверите доступност апликације или веб-сајта програмера.</translation>
 <translation id="2660779039299703961">Догађај</translation>
@@ -2341,6 +2351,7 @@
 <translation id="2690024944919328218">Приказуј опције језика</translation>
 <translation id="2691385045260836588">Модел</translation>
 <translation id="2691440343905273290">Промените подешавања уноса</translation>
+<translation id="2691811116976138467">Сајтови користе ову функцију за снимање и коришћење уноса са тастатуре, на пример, за игре или апликације за удаљене рачунаре</translation>
 <translation id="2692503699962701720">Промени интонацију приликом изговора типова елемената и форматираног текста</translation>
 <translation id="2692901429679246677">Тиркизна</translation>
 <translation id="2693134906590795721">Звукови пуњења</translation>
@@ -3110,6 +3121,7 @@
 <translation id="3261090393424563833">Повећај стопу</translation>
 <translation id="3261268979727295785">Можете да додате родитељски надзор за старију децу када довршите подешавање. Пронаћи ћете информације о родитељском надзору у апликацији Истражите.</translation>
 <translation id="3261832505033014216">Приступни кључ за <ph name="USER_EMAIL" /></translation>
+<translation id="3262261769033093854">Не дозвољавај сајтовима да снимају и користе унос мишем</translation>
 <translation id="3262336253311870293">Пошто овим налогом управља <ph name="DOMAIN" />, нећете бити одјављени са Google налога. Обележивачи, историја, лозинке и друга подешавања се више неће синхронизовати. Међутим, претходно синхронизовани подаци се чувају на Google налогу и можете да управљате њима на <ph name="BEGIN_LINK" />Google контролној табли<ph name="END_LINK" />.</translation>
 <translation id="3262986719682892278">Превелико</translation>
 <translation id="3264544094376351444">Фонт Sans-serif</translation>
@@ -3423,6 +3435,7 @@
 <translation id="3497501929010263034">USB уређај продавца <ph name="VENDOR_NAME" /> (производ <ph name="PRODUCT_ID" />)</translation>
 <translation id="3497560059572256875">Дели дудл логотип</translation>
 <translation id="3497915391670770295">Пошаљи на уређаје</translation>
+<translation id="3499091376302796297">Док прегледате сајтове, њихов садржај страница се чува у шифрованом облику на уређају.</translation>
 <translation id="3500417806337761827">Грешка при инсталацији дељене ставке. Превише SMB дељених ставки је већ инсталирано.</translation>
 <translation id="3500764001796099683">Омогући изоловане веб-апликације</translation>
 <translation id="350397915809787283">Ако немате налог, изаберите прву опцију да бисте га отворили.</translation>
@@ -4230,6 +4243,7 @@
 <translation id="4062561150282203854">Синхронизујте<ph name="DEVICE_TYPE" /> апликације, подешавања и друго</translation>
 <translation id="4065876735068446555">Мрежа коју користите (<ph name="NETWORK_ID" />) ће можда захтевати да посетите страницу за пријављивање.</translation>
 <translation id="4066207411788646768">Проверите везу да бисте видели доступне штампаче на мрежи</translation>
+<translation id="4066458014195202324">Дозвољено им је да снимају и користе унос са тастатуре</translation>
 <translation id="4067839975993712852">Означи актуелну картицу као прочитану</translation>
 <translation id="4068776064906523561">Сачувани отисци прстију</translation>
 <translation id="4070132839822635162">Не пријављуј ме</translation>
@@ -4369,6 +4383,7 @@
 <translation id="4184803915913850597">HID уређај (<ph name="VENDOR_ID" />:<ph name="PRODUCT_ID" />)</translation>
 <translation id="4186749321808907788"><ph name="QUERY_NAME" /> – <ph name="DEFAULT_SEARCH_ENGINE_NAME" /> претрага</translation>
 <translation id="4187424053537113647">Подешава се <ph name="APP_NAME" />…</translation>
+<translation id="4190446002599583608">Претрага историје, коју омогућава AI</translation>
 <translation id="4190492351494485814">За почетно подешавање треба да се повежете на интернет да би фајлови могли да се синхронизују са Chromebook-ом</translation>
 <translation id="4190828427319282529">Истицање фокуса тастатуре</translation>
 <translation id="4191892134568599822">Желите да примате садржај уз <ph name="FEATURE_NAME" />?</translation>
@@ -4864,6 +4879,7 @@
 <translation id="4562155214028662640">Додај дигитални отисак</translation>
 <translation id="4562155266774382038">Одбаците предлог</translation>
 <translation id="4562364000855074606">Блокирајте апликације инсталиране на овом уређају <ph name="DEVICE_TYPE" />. Да бисте ограничили преузимање апликација или садржаја, идите у подешавања Google Play-а. <ph name="BEGIN_LINK_LEARN_MORE" />Сазнајте више<ph name="END_LINK_LEARN_MORE" /></translation>
+<translation id="4562925006886238518">Користите свакодневни језик да бисте претраживали историју прегледања и проналазили сајтове које сте посетили.</translation>
 <translation id="4563210852471260509">Почетни језик за унос је кинески</translation>
 <translation id="4563382028841851106">Уклони са налога</translation>
 <translation id="4563880231729913339">Прст 3</translation>
@@ -4915,6 +4931,7 @@
 <translation id="4598549027014564149">Када сте у режиму без архивирања, сајтови не могу да користе колачиће да би видели ваше активности прегледања на свим сајтовима, чак и на сродним сајтовима. Активности прегледања се не користе за ствари као што је персонализовање огласа. Функције на неким сајтовима могу да не раде.</translation>
 <translation id="4598556348158889687">Управљање меморијским простором</translation>
 <translation id="4598776695426288251">Доступан је WiFi преко више уређаја</translation>
+<translation id="4599323532350839656">Није дозвољено снимање и коришћење уноса са тастатуре</translation>
 <translation id="4600071396330666617">Број предлога</translation>
 <translation id="4601095002996233687">Детаљна скенирања сумњивих преузимања.</translation>
 <translation id="4601426376352205922">Означи као непрочитано</translation>
@@ -5228,6 +5245,7 @@
 <translation id="484462545196658690">Аутоматски</translation>
 <translation id="4846628405149428620">Изаберите где овај сајт може да чува измене</translation>
 <translation id="4846680374085650406">Поштујете препоруку администратора за ово подешавање.</translation>
+<translation id="4846897209694249040">Није им дозвољено да снимају и користе унос мишем</translation>
 <translation id="4847242508757499006">Одаберите Пробај поново или одаберите Отвори у основном уређивачу да бисте користили опције ограниченог приказа и измена.</translation>
 <translation id="4847742514726489375">Умањено кретање</translation>
 <translation id="4848191975108266266">Команда „Хеј Google“ за Google помоћник</translation>
@@ -5348,6 +5366,7 @@
 <translation id="4927753642311223124">Нема шта да се види овде. Наставите даље.</translation>
 <translation id="4928629450964837566">Користите безбеднију лозинку</translation>
 <translation id="4929386379796360314">Одредишта за штампање</translation>
+<translation id="4930406318748549391">Положај бочне табле</translation>
 <translation id="4930447554870711875">Програмери</translation>
 <translation id="4930714375720679147">Укључи</translation>
 <translation id="4931347390544064118">Безбедне везе можда неће увек бити доступне када користите подразумевану мрежу. Размислите о избору другог добављача да бисте били сигурни да увек користите безбедну везу.</translation>
@@ -5696,6 +5715,7 @@
 <translation id="5195074424945754995">URL-ови који се подударају са овим правилима неће покренути промену прегледача и могу да се отварају или у прегледачу <ph name="BROWSER_NAME" /> или у прегледачу <ph name="ALTERNATIVE_BROWSER_NAME" />.</translation>
 <translation id="5195863934285556588"><ph name="BEGIN_PARAGRAPH1" />Google услуга локације користи изворе као што су WiFi мреже, мобилне мреже и сензори да би одредила приближну локацију овог уређаја.<ph name="END_PARAGRAPH1" />
     <ph name="BEGIN_PARAGRAPH2" />Можете да искључите Android локацију на овом уређају у било ком тренутку ако одете у Подешавања &gt; Апликације &gt; Google Play продавница &gt; Управљајте Android подешавањима &gt; Безбедност и локација &gt; Локација. Ако искључите Google прецизност локације у истом менију, можете и да искључите коришћење WiFi мрежа, мобилних мрежа и сензора за Android локацију.<ph name="END_PARAGRAPH2" /></translation>
+<translation id="5197150086680615104">Предлоге за групу картица можете да потражите у сваком тренутку</translation>
 <translation id="5197255632782567636">Интернет</translation>
 <translation id="5198430103906431024">Шаљите податке о коришћењу и дијагностичке податке. Овај уређај тренутно аутоматски шаље податке о дијагностици, уређају и коришћењу апликација Google-у. То доприноси одржавању стабилности система и апликације и другим подешавањима. Неки обједињени подаци ће такође помоћи Google апликацијама и партнерима, попут Android програмера. Ако укључите подешавање додатне активности на вебу и у апликацијама, ти подаци ће се можда чувати на Google налогу.</translation>
 <translation id="5199729219167945352">Експерименти</translation>
@@ -7211,6 +7231,7 @@
 <translation id="6341850831632289108">Откривање ваше физичке локације</translation>
 <translation id="6342069812937806050">Малопре</translation>
 <translation id="6343003829431264373">Само странице са парним бројевима</translation>
+<translation id="6343981313228733146">Прозор је померен нагоре и надесно</translation>
 <translation id="6344170822609224263">Приступ листи мрежних веза</translation>
 <translation id="6344576354370880196">Сачувани штампачи</translation>
 <translation id="6344608411615208519">Родитељ <ph name="BEGIN_LINK" />управља прегледачем<ph name="END_LINK" /></translation>
@@ -7795,6 +7816,7 @@
 <translation id="6798780071646309401">caps lock је укључен</translation>
 <translation id="6798954102094737107">Додатна компонента: <ph name="PLUGIN_NAME" /></translation>
 <translation id="679905836499387150">Скривена дугмад на траци с алаткама</translation>
+<translation id="6800623240347398745">Не постоји група за ту картицу, али погледајте ове групе</translation>
 <translation id="6800893479155997609">Најбоље апликације за <ph name="DEVICE_TYPE" /></translation>
 <translation id="6801308659697002152">{NUM_EXTENSIONS,plural, =1{Одаберите да ли овај додатак може да чита и мења овај сајт}one{Одаберите да ли ови додаци могу да читају или мењају овај сајт}few{Одаберите да ли ови додаци могу да читају или мењају овај сајт}other{Одаберите да ли ови додаци могу да читају или мењају овај сајт}}</translation>
 <translation id="6801435275744557998">Калибрација додирног екрана</translation>
@@ -7836,6 +7858,7 @@
 <translation id="6818920801736417483">Желите да сачувате лозинке?</translation>
 <translation id="6820079682647046800">Kerberos потврда идентитета није успела</translation>
 <translation id="6821439254917412979">Откачите <ph name="EXTENSION_NAME" /></translation>
+<translation id="6823097506504975234">Када претражујете историју прегледања, термини за претрагу историје, садржај странице са најбољим подударањима и генерисани резултати модела се шаљу Google-у и могу их видети људи који прегледају да би побољшали ову функцију.</translation>
 <translation id="6823174134746916417">Додирни за клик на тачпеду</translation>
 <translation id="6823561724060793716">На траци за адресу можете да отворите информације о страници да бисте видели додатне информације о страници коју посећујете</translation>
 <translation id="6824564591481349393">Копирај имејл адресу</translation>
@@ -8867,6 +8890,7 @@
 <translation id="761530003705945209">Правите резервне копије на Google диску. Лако вратите податке или пређите на други уређај у било ком тренутку. Резервна копија обухвата податке апликација. Резервне копије се отпремају на Google и шифрују помоћу лозинке за Google налог.</translation>
 <translation id="7615365294369022248">Дошло је до грешке при додавању налога</translation>
 <translation id="7616214729753637086">Уређај се региструје...</translation>
+<translation id="7616964248951412133">Сајтови користе ову функцију за снимање и коришћење уноса мишем, на пример, за игре или апликације за удаљене рачунаре</translation>
 <translation id="7617263010641145920">Укључите Play продавницу</translation>
 <translation id="7617648809369507487">Користи ненаметљиву размену порука</translation>
 <translation id="7619937211696316184">Одржавање је завршено</translation>
@@ -9370,6 +9394,7 @@
 <translation id="7959665254555683862">Нова картица без архивирања</translation>
 <translation id="7961015016161918242">Никад</translation>
 <translation id="7963001036288347286">Убрзавање тачпеда</translation>
+<translation id="7963513503134856713">Прозор је померен надесно</translation>
 <translation id="7963608432878156675">Ово име је видљиво другим уређајима за Bluetooth и мрежне везе</translation>
 <translation id="7963826112438303517">Помоћник користи те снимке и гласовне захтеве да би направио и ажурирао гласовни модел, који се чува само на оним уређајима на којима сте укључили Voice Match. Избришите или поново увежбајте гласовне активности у подешавањима Помоћника.</translation>
 <translation id="7964458523224581615">Тамнозелена</translation>
@@ -10023,6 +10048,7 @@
 <translation id="8428271547607112339">Додајте школски налог</translation>
 <translation id="8428634594422941299">Важи</translation>
 <translation id="84297032718407999">Одјавићете се за <ph name="LOGOUT_TIME_LEFT" /></translation>
+<translation id="8429928917752180743">Још опција за: <ph name="EXTENSION_NAME" /></translation>
 <translation id="8431190899827883166">Приказ додира</translation>
 <translation id="843173223122814223">Правите позадине помоћу вештачке интелигенције</translation>
 <translation id="8433186206711564395">Мрежна подешавања</translation>
@@ -10113,6 +10139,7 @@
 <translation id="8498214519255567734">Омогућава да лакше прегледате садржај екрана или да читате при пригушеном светлу</translation>
 <translation id="8499083585497694743">Укључи звук микрофона</translation>
 <translation id="8500044868721690197">Овом сајту је онемогућено да контролише и репрограмира MIDI уређаје</translation>
+<translation id="8500123638242682652">Прозор је померен нагоре</translation>
 <translation id="8502536196501630039">Да бисте користили апликације са Google Play-а, прво морате да вратите апликације. Неки подаци су можда изгубљени.</translation>
 <translation id="8503813439785031346">Корисничко име</translation>
 <translation id="850382998924680137">Погледано данас</translation>
@@ -10212,6 +10239,7 @@
 <translation id="8577052309681449949">Аутоматски кликови, величина курсора, боја курсора и друго</translation>
 <translation id="8578639784464423491">Дозвољено је највише 99 знакова</translation>
 <translation id="8581809080475256101">Притисните да бисте ишли унапред или отворите контекстуални мени да бисте видели историју</translation>
+<translation id="8583122761178401199">Не дозвољавај сајтовима да снимају и користе унос са тастатуре</translation>
 <translation id="8584280235376696778">&amp;Отвори видео снимак на новој картици</translation>
 <translation id="858451212965845553">Пошаљи на уређаје</translation>
 <translation id="8584843865238667486">HID уређаји са коришћењем <ph name="USAGE" /> са странице о коришћењу <ph name="USAGE_PAGE" /></translation>
@@ -10227,6 +10255,7 @@
 <translation id="859246725979739260">Овом сајту је забрањено да приступа локацији.</translation>
 <translation id="8593450223647418235">Нећете моћи да отварате фајлове у Microsoft-у 365 док се подешавање не заврши.</translation>
 <translation id="8593686980889923154">Апликација <ph name="APP_NAME" /> је блокирана на уређају <ph name="DEVICE_TYPE" /></translation>
+<translation id="8596400097994526901">Још радњи за <ph name="SEARCH_ENGINE_NAME" /></translation>
 <translation id="8596540852772265699">Прилагођене датотеке</translation>
 <translation id="8597845839771543242">Формат својства:</translation>
 <translation id="8598249292448297523">штампај</translation>
@@ -10312,6 +10341,7 @@
 <translation id="8657393004602556571">Желите да одбаците повратне информације?</translation>
 <translation id="8657542881463614516">Користите покрет превлачења да бисте се кретали између страница</translation>
 <translation id="8659608856364348875">Kонтакти за <ph name="FEATURE_NAME" /></translation>
+<translation id="8659609431223166673">Прозор је померен надоле</translation>
 <translation id="8661290697478713397">Отвори линк у прозору за пре&amp;гледање без архивирања</translation>
 <translation id="8662474268934425487">Пријавите се на <ph name="SITE_ETLD_PLUS_ONE" /></translation>
 <translation id="8662671328352114214">Придружите се <ph name="TYPE" /> мрежи</translation>
@@ -10358,6 +10388,7 @@
 <translation id="8682730193597992579">Штампач <ph name="PRINTER_NAME" /> је повезан и спреман</translation>
 <translation id="8684471948980641888">Дозволи синхронизацију на мрежама са ограничењем</translation>
 <translation id="8685540043423825702">Chrome профил</translation>
+<translation id="8685882652128627032">Кликните да бисте отворили дијалог Додајте претрагу сајта</translation>
 <translation id="8686142379631285985">Пријављени сте као <ph name="BEGIN_BOLD" /><ph name="DRIVE_ACCOUNT_EMAIL" /><ph name="END_BOLD" /></translation>
 <translation id="8687103160920393343">Откажите фајл <ph name="FILE_NAME" /></translation>
 <translation id="8687527282898211955">Подесите PIN</translation>
@@ -10548,6 +10579,7 @@
 <translation id="881799181680267069">Сакриј друге</translation>
 <translation id="8818152010000655963">Позадина</translation>
 <translation id="8818958672113348984">Потврди помоћу телефона</translation>
+<translation id="8818988764764862764">Прозор је померен улево</translation>
 <translation id="8819510664278523111">EID уређаја је <ph name="EID_NUMBER" />, IMEI уређаја је <ph name="IMEI_NUMBER" />, а серијски број уређаја је <ph name="SERIAL_NUMBER" />. Ове бројеве можете да користите да бисте активирали услугу.</translation>
 <translation id="8820817407110198400">Обележивачи</translation>
 <translation id="8821045908425223359">Аутоматски конфигуриши IP адресу</translation>
@@ -10626,6 +10658,7 @@
 <translation id="8872506776304248286">Отвори у апликацији</translation>
 <translation id="8872774989979382243">Звук је искључен. Укључите звук.</translation>
 <translation id="887292602123626481">Сазнајте више о подразумеваним претраживачима</translation>
+<translation id="8873075098103007382">Останите организовани помоћу група картица</translation>
 <translation id="8874341931345877644">Пребацујте на уређај:</translation>
 <translation id="8874790741333031443">Пробајте привремено да дозволите колачиће треће стране, што значи слабију заштиту прегледања, али већу вероватноћу да ће функције сајта радити на очекивани начин.</translation>
 <translation id="8875520811099717934">Надоградња Linux-а</translation>
@@ -10758,6 +10791,7 @@
 <translation id="8973557916016709913">Уклони ниво зумирања</translation>
 <translation id="8973596347849323817">Можете да прилагодите овај уређај према потребама. Те функције приступачности можете касније да промените у Подешавањима.</translation>
 <translation id="897414447285476047">Одредишна датотека је непотпуна због проблема са везом.</translation>
+<translation id="8974261761101622391">Пронађите алтернативу за: <ph name="EXTENSION_NAME" /></translation>
 <translation id="897525204902889653">Услуга карантина</translation>
 <translation id="8975396729541388937">Опозовите пријаву у било ком тренутку тако што ћете кликнути на линк у имејловима које добијате.</translation>
 <translation id="8975562453115131273">{NUM_OTHER_TABS,plural, =0{„<ph name="TAB_TITLE" />“}=1{„<ph name="TAB_TITLE" />“ и још 1 картица}one{„<ph name="TAB_TITLE" />“ и још # картица}few{„<ph name="TAB_TITLE" />“ и још # картице}other{„<ph name="TAB_TITLE" />“ и још # картица}}</translation>
diff --git a/chrome/app/resources/generated_resources_sw.xtb b/chrome/app/resources/generated_resources_sw.xtb
index 74c68fc4..5b79d26f 100644
--- a/chrome/app/resources/generated_resources_sw.xtb
+++ b/chrome/app/resources/generated_resources_sw.xtb
@@ -970,6 +970,7 @@
 <translation id="1697150536837697295">Sanaa</translation>
 <translation id="1697686431566694143">Badilisha faili</translation>
 <translation id="1698796500103229697">Njia za Kulipa</translation>
+<translation id="1698899521169711967">Kuvinjari kwa kutumia kibodi</translation>
 <translation id="1699807488537653303">Rekebisha hitilafu ya nenosiri</translation>
 <translation id="1700201317341192482">Ondoa kadi pepe yako</translation>
 <translation id="1700517974991662022">Lililotembelewa</translation>
@@ -2480,6 +2481,7 @@
 <translation id="2771816809568414714">Jibini</translation>
 <translation id="2772936498786524345">Mjanja</translation>
 <translation id="2773288106548584039">Uwezo wa Kutumia Kivinjari Kilichopitwa na Wakati</translation>
+<translation id="2773621783913034737">Fanya Vichupo Visitumike</translation>
 <translation id="2773802008104670137">Faili ya aina hii inaweza kudhuru kompyuta yako.</translation>
 <translation id="2775104091073479743">Badilisha Alama za Vidole</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{Kiendelezi cha "<ph name="EXTENSION" />" kilikuwa kikifikia vifaa}=1{Kiendelezi cha "<ph name="EXTENSION" />" kinafikia kifaa {0}}other{Kiendelezi cha "<ph name="EXTENSION" />" kinafikia vifaa {0}}}</translation>
@@ -2560,6 +2562,7 @@
 <translation id="2830528677948328648">Kudhibiti akaunti yako ya Google</translation>
 <translation id="2831430281393059038">Kifaa kinachoweza kutumika</translation>
 <translation id="2832124733806557606">Mtoto wako anaweza kutumia PIN kuingia katika akaunti kwenye kifaa au kukifungua.</translation>
+<translation id="2833144527504272627">Sogeza ukitumia kiteuzi cha maandishi</translation>
 <translation id="2835177225987815960">Mipangilio yako ya sasa ya kuchanganua itawekwa upya, ikijumuisha swichi zozote ulizoteua na mapendeleo ya kasi ya kuchanganua kiotomatiki.</translation>
 <translation id="2835547721736623118">Huduma ya utambuzi wa matamshi</translation>
 <translation id="2835761321523638096">Soma na ubadilishe vipengee kwenye orodha ya kusoma</translation>
@@ -4116,6 +4119,7 @@
 <translation id="3978325380690188371">Vitufe vinavyonata havipatikani wakati ChromeVox imewashwa</translation>
 <translation id="3979395879372752341">Kiendelezi kipya kimeongezwa (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326">Washa <ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">Ficha vichupo hivi</translation>
 <translation id="3981058120448670012">Kinaonekana kwa vifaa vilivyo karibu kama <ph name="DEVICE_NAME" /> kwa <ph name="REMAINING_TIME" />...</translation>
 <translation id="3981760180856053153">Aina batili ya kuhifadhi imeingizwa.</translation>
 <translation id="3982375475032951137">Weka mipangilio ya kivinjari chako kwa hatua chache rahisi</translation>
@@ -6306,6 +6310,7 @@
 <translation id="5642508497713047">Kitia Sahihi cha CRL</translation>
 <translation id="5643191124441701136">Msimbo wako wa usalama unapatikana mbele ya kadi yako</translation>
 <translation id="5643321261065707929">Mtandao unaopima data</translation>
+<translation id="5643717184207603910">Ongeza kasi ya utendaji</translation>
 <translation id="5646376287012673985">Mahali</translation>
 <translation id="5646558797914161501">Mfanyabiashara</translation>
 <translation id="5648021990716966815">Pini ya maikrofoni</translation>
@@ -6410,6 +6415,7 @@
 <translation id="5733109311583381874">Weka maneno yako mwenyewe kwenye kamusi ya mtumiaji ili uweke mapendeleo ya vipengee vya kubadilisha.</translation>
 <translation id="5734362860645681824">Mawasiliano</translation>
 <translation id="5734697361979786483">Ongeza faili ya kushiriki</translation>
+<translation id="5735513236153491131">Boresha Sasa</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{Data hii au kifaa chako hakitimizi baadhi ya sera za usalama. Wasiliana na msimamizi wako ili ufahamu unachotakiwa kurekebisha.}=1{Faili hii au kifaa chako hakitimizi baadhi ya sera za usalama za shirika lako. Wasiliana na msimamizi wako ili ufahamu unachotakiwa kurekebisha.}other{Faili hizi hazitimizi baadhi ya sera za usalama za shirika lako. Wasiliana na msimamizi wako ili ufahamu unachotakiwa kurekebisha.}}</translation>
 <translation id="5738093759615225354">Unahitaji nenosiri hili ili uingie katika akaunti kwenye kompyuta yako</translation>
 <translation id="5739017626473506901">Ingia katika akaunti ili umsaidie <ph name="USER_NAME" /> aweke akaunti ya shuleni</translation>
@@ -8221,6 +8227,7 @@
 <translation id="7114054701490058191">Nenosiri halilingani</translation>
 <translation id="7114648273807173152">Ili utumie Smart Lock kuingia katika Akaunti yako ya Google, nenda kwenye Mipangilio &gt; Vifaa vilivyounganishwa &gt; Simu yako &gt; Smart Lock.</translation>
 <translation id="7115361495406486998">Hakuna anwani zinazoweza kufikiwa</translation>
+<translation id="7115731767122970828">Boresha sasa</translation>
 <translation id="7116554090938189816">Muda wa kutumia cheti cha SSL cha printa umekwisha. Zima kisha uwashe printa na ujaribu tena.</translation>
 <translation id="7117228822971127758">Tafadhali jaribu tena baadaye</translation>
 <translation id="7118268675952955085">picha ya skrini</translation>
@@ -8376,6 +8383,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Bora)</translation>
 <translation id="7246230585855757313">Weka tena ufunguo wako wa usalama kisha ujaribu tena</translation>
 <translation id="724835896049478274">Akaunti zinazopatikana kwa ajili ya programu za Android</translation>
+<translation id="7248802599439396696">Fanya vichupo visitumike</translation>
 <translation id="7249197363678284330">Unaweza kubadilisha mipangilio hii katika sehemu ya anwani.</translation>
 <translation id="7249764475759804559">Jumuisha programu hii iwe kama chaguo wakati wa kufungua faili</translation>
 <translation id="7250616558727237648">Kifaa unachoshiriki nacho hakijakubali. Tafadhali jaribu tena.</translation>
@@ -9972,6 +9980,7 @@
 <translation id="8390392581097975659">Inaweka programu ya kichanganuzi kwenye kifaa</translation>
 <translation id="8390449457866780408">Seva haipatikani.</translation>
 <translation id="8391218455464584335">Ngozi ya plastiki</translation>
+<translation id="8391918125842702622">Tahadhari ya tatizo la utendaji</translation>
 <translation id="8392726714909453725">Mipangilio ya Chagua ili Izungumze</translation>
 <translation id="8393511274964623038">Simamisha programu jalizi</translation>
 <translation id="839363317075970734">Maelezo ya kifaa chenye Bluetooth</translation>
@@ -10072,6 +10081,7 @@
 <translation id="8466052016039127321">Imeshindwa kuendelea na kipindi kilichotangulia</translation>
 <translation id="8467326454809944210">Chagua lugha nyingine</translation>
 <translation id="8468087214092422866">Hazijaruhusiwa kutafuta vifaa vyenye Bluetooth</translation>
+<translation id="8469863130477774813">Kipengele cha kuboresha utendaji kinapatikana</translation>
 <translation id="8470513973197838199">Manenosiri yaliyohifadhiwa ya <ph name="ORIGIN" /></translation>
 <translation id="8471525937465764768">Tovuti huunganisha kwenye vifaa vya USB kwa ajili ya vipengele kama vile kuchapisha hati au kuweka faili kwenye kifaa cha kuhifadhi</translation>
 <translation id="8471959340398751476">Kipengele cha punguzo kimezimwa. Unaweza kukiwasha kwenye menyu ya kuweka mapendeleo</translation>
diff --git a/chrome/app/resources/generated_resources_uz.xtb b/chrome/app/resources/generated_resources_uz.xtb
index 30c88f5d..a0119cf4 100644
--- a/chrome/app/resources/generated_resources_uz.xtb
+++ b/chrome/app/resources/generated_resources_uz.xtb
@@ -409,6 +409,7 @@
 <translation id="1293556467332435079">Fayllar</translation>
 <translation id="1294807885394205587">Bu jarayon bir necha daqiqa vaqt olishi mumkin. Konteynerlar menejeri ishga tushirilmoqda.</translation>
 <translation id="12951065153783848">Hisobingiz tashkilot boshqaruvida</translation>
+<translation id="1296410481664942178">Google Taqvim chiqmasin</translation>
 <translation id="1296911687402551044">Tanlangan varaqni mahkamlash</translation>
 <translation id="1297175357211070620">Printer</translation>
 <translation id="129770436432446029"><ph name="EXPERIMENT_NAME" /> ilovasi haqida fikr-mulohaza yuborish</translation>
@@ -447,6 +448,7 @@
 <translation id="1327495825214193325">ADB tuzatish vositalarini yoqish uchun <ph name="DEVICE_TYPE" /> qurilmasini oʻchirib yoqish zarur. ADB vositasini oʻchirish uchun qurilmani zavod sozlamalariga qaytarish kerak.</translation>
 <translation id="1327527584824210101">Kalit ishlatish</translation>
 <translation id="1327794256477341646">Joylashuvga ruxsat talab qiladigan funksiyalar ishlamaydi</translation>
+<translation id="1328364753167940710"><ph name="NUM_HR" /> soat ichida</translation>
 <translation id="1329466763986822896">Bu hotspotning maxfiylik darajasini oshiring</translation>
 <translation id="1331977651797684645">Bu men</translation>
 <translation id="1333489022424033687">Qurilmangizda boshqa saytlar tomonidan saqlangan maʼlumotlar tozalanmaguncha ayrim <ph name="ORIGIN" /> funksiyalari yaxshi ishlamasligi mumkin</translation>
@@ -994,6 +996,7 @@
 <translation id="1709762881904163296">Tarmoq sozlamalari</translation>
 <translation id="1709916727352927457">Kodni oʻchirish</translation>
 <translation id="1709972045049031556">Yuborilmadi</translation>
+<translation id="1712143791363119140">Bajarilmoqda</translation>
 <translation id="1714644264617423774">Qurilmani yanada qulayroq qilish uchun maxsus imkoniyatlarni yoqing. <ph name="LINK_BEGIN" />Batafsil<ph name="LINK_END" /></translation>
 <translation id="1716034099915639464"><ph name="SITE_NAME" /> maʼlumotlari, ruxsatlari va oʻrnatilgan ilovalar oʻchirilsinmi?</translation>
 <translation id="171826447717908393">Izolyatsiyalangan veb-ilovalar (beta)</translation>
@@ -1398,6 +1401,7 @@
 <translation id="200928901437634269">Farzandingizning Google yoki maktab hisobidan foydalaning. Ota-ona nazoratini ham oʻrnatish mumkin.</translation>
 <translation id="2009590708342941694">Emoji vositasi</translation>
 <translation id="2010501376126504057">Mos qurilmalar</translation>
+<translation id="2010636492623189611">Tanlandi.</translation>
 <translation id="201217432804812273">"Guruhni saqlash" funksiyasini yoqing</translation>
 <translation id="2012935757369720523">Faylni oʻchirish</translation>
 <translation id="2013550551806600826">Sinang. Bu sozlamadan foydalanish uchun sensorli panel sinov maydonida ikki barmoq bilan varaqlang. Buni keyinroq Sozlamalar &gt; Qurilma &gt; Sichqoncha va sensorli panel orqali moslash mumkin.</translation>
@@ -1993,6 +1997,7 @@
 <translation id="2435248616906486374">Tarmoqqa ulanish yo‘q</translation>
 <translation id="2435457462613246316">Parolni ko‘rsatish</translation>
 <translation id="2436385001956947090">Havolani nusxalash</translation>
+<translation id="2437561292559037753">Maʼlumotlarni ulashish</translation>
 <translation id="2438853563451647815">Printerga ulanmagan</translation>
 <translation id="2439152382014731627"><ph name="DEVICE_TYPE" /> parolini almashtirish</translation>
 <translation id="2439626940657133600"><ph name="WINDOW_TITLE" /> yuklanmoqda</translation>
@@ -2571,6 +2576,7 @@
 <translation id="2843698124892775282"><ph name="MEMORY_SAVINGS" /> boʻshatildi</translation>
 <translation id="2844169650293029770">USB-C qurilma (chap tomondagi old port)</translation>
 <translation id="2844809857160214557">Chop etish vazifalarini koʻrish va boshqarish</translation>
+<translation id="2845276301195220700">Google Taqvim uchun boshqa amallar</translation>
 <translation id="2845382757467349449">Xatcho‘plar panelini har doim ko‘rsatish</translation>
 <translation id="2845751331501453107">Internetni kezish davomida chiqadigan reklama shu sozlama, <ph name="BEGIN_LINK1" />Saytlar taklif qiladigan reklama<ph name="LINK_END1" />, <ph name="BEGIN_LINK2" />cookie sozlamalari<ph name="LINK_END2" /> hamda ochilgan saytda reklamani moslashtirish mumkinligi asosida moslashtiriladi</translation>
 <translation id="284581348330507117">Unikal parollar yarating</translation>
@@ -3683,6 +3689,7 @@
 <translation id="3694590407685276748">Matn kursorini ajratib belgilash</translation>
 <translation id="369489984217678710">Parollar va boshqa kirish ma’lumotlari</translation>
 <translation id="369522892592566391">{NUM_FILES,plural, =0{Xavfsizlik tekshuvlari yakunlandi. Maʼlumotlaringiz yuklanadi.}=1{Xavfsizlik tekshuvlari yakunlandi. Faylingiz yuklanadi.}other{Xavfsizlik tekshuvlari yakunlandi. Fayllaringiz yuklanadi.}}</translation>
+<translation id="3695339288331169103">Manba: <ph name="BEGIN_LINK" /><ph name="DISPLAY_REFERRER_URL" /><ph name="END_LINK" /></translation>
 <translation id="369736917241079046">launcher + chapga strelka</translation>
 <translation id="3697716475445175867">oxirgi marta ochilgan</translation>
 <translation id="3697732362672163692">{NUM_SITES,plural, =1{Bu sayt kelgusida bildirishnoma yuborishini toʻxtatish mumkin.}other{Bu saytlar kelgusida bildirishnoma yuborishini toʻxtatish mumkin.}}</translation>
@@ -4984,6 +4991,7 @@
 <translation id="4650591383426000695">Telefoningizni <ph name="DEVICE_TYPE" /> qurilmasidan uzing</translation>
 <translation id="4651484272688821107">Demo rejim manbalari bilan onlayn komponent yuklanmadi.</translation>
 <translation id="4651921906638302153">Bu hisob orqali kirilmadi</translation>
+<translation id="4652921642122345344">Ovoz tezligi: <ph name="RATE" />x</translation>
 <translation id="4652935475563630866">Kamera sozlamasi oʻzgarishi uchun Parallels Desktopni qaytadan ishga tushiring. Davom etish uchun Parallels Desktopni qayta ishga tushiring.</translation>
 <translation id="4653116291358041820">Kichik soya</translation>
 <translation id="4653405415038586100">Linux tizimini sozlashda xatolik</translation>
@@ -5182,6 +5190,7 @@
 <translation id="4809927044794281115">Kunduzgi mavzu</translation>
 <translation id="4811212958317149293">Switch access yordamida klaviaturalarni avtomatik skanerlash</translation>
 <translation id="4811503964269049987">Belgilangan varaqni guruhlash</translation>
+<translation id="4812073856515324252"><ph name="APP_NAME" /> uchun kalitingiz qayerda saqlanishini tanlang</translation>
 <translation id="4813512666221746211">Tarmoq xatoligi</translation>
 <translation id="4814114628197290459">IBAN raqamini oʻchirish</translation>
 <translation id="4814327014588285482">Tashlab ketish va keyinroq eslatish</translation>
@@ -5472,6 +5481,7 @@
 <translation id="5032430150487044192">QR kod yaratilmadi</translation>
 <translation id="5033137252639132982">Harakat sensorlaridan foydalanish taqiqlangan</translation>
 <translation id="5033266061063942743">Geometrik shakllar</translation>
+<translation id="503441068567788948">Google Parollar menejeri uchun yangi PIN kod yarating</translation>
 <translation id="5035846135112863536"><ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE" /> orqali batafsil axborot olish uchun "Batafsil" bandini tanlang.</translation>
 <translation id="5037676449506322593">Hammasini belgilash</translation>
 <translation id="5038818366306248416">Avvalroq <ph name="ORIGIN" /> saytidagi barcha kengaytmalarga ruxsat bermaslikni tanlagansiz</translation>
@@ -5499,6 +5509,7 @@
 <translation id="5057110919553308744">Kengaytma bosilganda</translation>
 <translation id="5057127674016624293">Skanerlash kutilganidan uzoqroq vaqt olmoqda</translation>
 <translation id="5057480703570202545">Yuklanmalar tarixi</translation>
+<translation id="5058771692413403640"><ph name="SITE" /> shaxsingizni tasdiqlamoqchi</translation>
 <translation id="5059241099014281248">Kirishni taqiqlash</translation>
 <translation id="5059429103770496207">Displey uslubi</translation>
 <translation id="5059526285558225588">Nimani ulashishni tanlang</translation>
@@ -5647,6 +5658,7 @@
 <translation id="5160634252433617617">Tashqi klaviatura</translation>
 <translation id="5160857336552977725"><ph name="DEVICE_TYPE" /> hisobingizga kiring</translation>
 <translation id="5161251470972801814"><ph name="VENDOR_NAME" /> ishlab chiqargan USB qurilmalar</translation>
+<translation id="5161442190864186925">Majlisga kirish</translation>
 <translation id="5161827038979306924">Chrome brauzer tarixi va qidiruv tarixi nima bilan farq qiladi?</translation>
 <translation id="5162905305237671850"><ph name="DEVICE_TYPE" /> bloklandi</translation>
 <translation id="5163910114647549394">Varaq panelning oxiriga olindi</translation>
@@ -5940,6 +5952,7 @@
 <translation id="5390112241331447203">Fikr-mulohaza hisobotlarida system_logs.txt fayli ham yuborilsin.</translation>
 <translation id="5390677308841849479">Toʻq qizil va sabzirang</translation>
 <translation id="5392192690789334093">Bildirishnomalar yuborishga ruxsat berilgan</translation>
+<translation id="5393330235977997602">PIN parametrlari</translation>
 <translation id="5393761864111565424">{COUNT,plural, =1{Havola}other{# ta havola}}</translation>
 <translation id="5394529681046491727">WiFi Direct</translation>
 <translation id="5395498824851198390">Birlamchi shrift</translation>
@@ -6675,6 +6688,7 @@
 <translation id="5935158534896975820">Sertifikatni imzolash talabi tayyorlanmoqda (server javobi kutilmoqda)</translation>
 <translation id="5935656526031444304">Saytlarni xavfsiz kezish rejimini boshqarish</translation>
 <translation id="5936065461722368675">Toʻliq sahifani tarjima qilish</translation>
+<translation id="5937347877659196749">Keyin esa, barcha kalitlarni zaxiraviy PIN kod bilan himoyalang</translation>
 <translation id="5937977334791924341"><ph name="APP" /> logotipi</translation>
 <translation id="5938002010494270685">Xavfsizlikka oid yangilanish mavjud</translation>
 <translation id="5939518447894949180">Asliga qaytarish</translation>
@@ -7952,6 +7966,7 @@
 <translation id="6912007319859991306">SIM karta PIN kodi</translation>
 <translation id="6912380255120084882">Boshqa qurilmada urining</translation>
 <translation id="691289340230098384">Taglavha sozlamalari</translation>
+<translation id="6913051485529944333">Endi bu sahifada Google Taqvim chiqmaydi</translation>
 <translation id="6914812290245989348">Xavfsiz saytlarga kirish haqida ogohlantirishlar koʻrsatilmasin</translation>
 <translation id="6916590542764765824">Kengaytmalarni boshqarish</translation>
 <translation id="6918677045355889289">ChromeOS tizimini yangilash zarur</translation>
@@ -8121,6 +8136,7 @@
 <translation id="7033616203784997570">Maksimal 62 ta belgi kiritish mumkin</translation>
 <translation id="7034692021407794547">Hisob-kitobni boshqarish vakolatiga ega administrator avval Administrator konsoli orqali Google Meet qurilmalari boʻlimida Google Meet qurilmalari xizmat shartlarini qabul qilishi lozim.</translation>
 <translation id="7036706669646341689">Linux uchun <ph name="DISK_SIZE" /> joy tavsiya etiladi. Boʻsh joyni koʻpaytirish uchun qurilma xotirasidan fayllarni oʻchiring.</translation>
+<translation id="7037157058268992880">PIN kodni unutdim</translation>
 <translation id="7037509989619051237">Ovoz namunasi</translation>
 <translation id="7038632520572155338">Switch Access</translation>
 <translation id="7038710352229712897"><ph name="USER_NAME" /> uchun boshqa Google hisobini kiritish</translation>
@@ -9154,6 +9170,7 @@
 <translation id="7810202088502699111">Qalqib chiquvchi oynalar bloklandi.</translation>
 <translation id="7810367892333449285">Xatosiz formatda kiritilishi zarur <ph name="LPA_0" />$<ph name="LPA_1" />SM-DP+ manzil<ph name="LPA_2" />$<ph name="LPA_3" />ixtiyoriy mos id<ph name="LPA_4" /></translation>
 <translation id="7811263553491007091">Qaytadan urining yoki quyida avval yaratilgan mavzulardan birini tanlang.</translation>
+<translation id="7812170317334653156">Google Taqvim berkitilgan</translation>
 <translation id="7814090115158024843">Bu saytlarda hech qachon yozishda yordam taklif qilinmasin</translation>
 <translation id="7814458197256864873">&amp;Nuxsa olish</translation>
 <translation id="7814857791038398352">Microsoft OneDrive</translation>
@@ -9212,6 +9229,7 @@
 <translation id="7853747251428735">Qo‘shimcha &amp;vositalar</translation>
 <translation id="7853999103056713222">Xavfsiz parol ishlatish</translation>
 <translation id="7855678561139483478">Varaqni yangi oynaga olish</translation>
+<translation id="7856117067008941054">Google Taqvimni berkitish</translation>
 <translation id="7857004848504343806">Kompyuteringizda himoya moduli mavjud. Undan ChromeOS Flex platformasida ko‘plab jiddiy xavfsizlik funksiyalarini amalga oshirishda foydalaniladi. Batafsil ma’lumotni Chromebook yordam markazidan olishingiz mumkin: https://support.google.com/chromebook/?p=sm</translation>
 <translation id="7857093393627376423">Matn takliflari</translation>
 <translation id="7858120906780498731">ChromeOS ulangan kiritish qurilmalari</translation>
@@ -9220,6 +9238,7 @@
 <translation id="786073089922909430">Xizmat: <ph name="ARC_PROCESS_NAME" /></translation>
 <translation id="7861215335140947162">&amp;Yuklanishlar</translation>
 <translation id="7861846108263890455">Google hisobi tili</translation>
+<translation id="7864114920800968141"><ph name="NUM_MIN" /> daqiqa ichida</translation>
 <translation id="7864539943188674973">Bluetooth funksiyasini o‘chirish</translation>
 <translation id="7864825798076155402">Google hisobingizda saqlansinmi?</translation>
 <translation id="7865127013871431856">Tarjima parametrlari</translation>
@@ -9534,6 +9553,7 @@
 <translation id="8084429490152575036">Mobil APN sozlamalari</translation>
 <translation id="8084510406207562688">Barcha varaqlarni tiklash</translation>
 <translation id="8084628902026812045">Bu sayt xavfsiz ulanishdan foydalanmayapti va fayl oʻzgartirilgan boʻlishi mumkin</translation>
+<translation id="8085701268329068646">Google Parollar menejeri uchun PIN kodni kiriting</translation>
 <translation id="8086015605808120405"><ph name="PRINTER_NAME" /> sozlanmoqda...</translation>
 <translation id="8086121155774250556">Bu varaq ekraningizni uzatmoqda</translation>
 <translation id="8086610718778464681">Linux ilovalari va fayllari zaxiralanmadi</translation>
@@ -11063,6 +11083,7 @@
 <translation id="920045321358709304"><ph name="SEARCH_ENGINE" /> orqali qidirish</translation>
 <translation id="9201117361710210082">Avval koʻrilgan</translation>
 <translation id="9201220332032049474">Ekran qulfi parametrlari</translation>
+<translation id="9201762611758697018">Zaxiraviy PIN kod yordamida istalgan qurilmada saqlangan kalitlarni ochish mumkin</translation>
 <translation id="9201842707396338580">Nimadir xato ketdi. Qurilma egasi yoki administratorga murojaat qiling. Xatolik kodi: <ph name="ERROR_CODE" />.</translation>
 <translation id="9203296457393252944">Qizil-yashil, yashilni yaxshi koʻrmaslik (Deyteranomaliya)</translation>
 <translation id="9203398526606335860">&amp;Ma’lumotlarni yig‘ish yoniq</translation>
diff --git a/chrome/app/resources/generated_resources_vi.xtb b/chrome/app/resources/generated_resources_vi.xtb
index 9cd6f53..be8559e9 100644
--- a/chrome/app/resources/generated_resources_vi.xtb
+++ b/chrome/app/resources/generated_resources_vi.xtb
@@ -975,6 +975,7 @@
 <translation id="1697150536837697295">Nghệ thuật</translation>
 <translation id="1697686431566694143">Chỉnh sửa tệp</translation>
 <translation id="1698796500103229697">&amp;Phương thức thanh toán</translation>
+<translation id="1698899521169711967">Duyệt web bằng con nháy</translation>
 <translation id="1699807488537653303">Khắc phục lỗi về mật khẩu</translation>
 <translation id="1700201317341192482">Xoá thẻ ảo</translation>
 <translation id="1700517974991662022">Đã truy cập</translation>
@@ -2488,6 +2489,7 @@
 <translation id="2771816809568414714">Pho mát</translation>
 <translation id="2772936498786524345">Lén lút</translation>
 <translation id="2773288106548584039">Hỗ trợ trình duyệt cũ</translation>
+<translation id="2773621783913034737">Dừng hoạt động của thẻ</translation>
 <translation id="2773802008104670137">Loại tệp này có thể gây hại cho máy tính của bạn.</translation>
 <translation id="2775104091073479743">Chỉnh sửa vân tay</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{Tiện ích "<ph name="EXTENSION" />" đã truy cập vào các thiết bị}=1{Tiện ích "<ph name="EXTENSION" />" đang truy cập vào {0} thiết bị}other{Tiện ích "<ph name="EXTENSION" />" đang truy cập vào {0} thiết bị}}</translation>
@@ -2568,6 +2570,7 @@
 <translation id="2830528677948328648">Quản lý &amp;Tài khoản Google của bạn</translation>
 <translation id="2831430281393059038">Thiết bị được hỗ trợ</translation>
 <translation id="2832124733806557606">Con bạn có thể dùng mã PIN để đăng nhập hoặc mở khóa thiết bị này.</translation>
+<translation id="2833144527504272627">Điều hướng bằng con trỏ văn bản</translation>
 <translation id="2835177225987815960">Chế độ quét hiện tại của bạn sẽ được đặt lại, bao gồm cả mọi công tắc đã chỉ định và ưu tiên về tốc độ quét.</translation>
 <translation id="2835547721736623118">Dịch vụ nhận dạng lời nói</translation>
 <translation id="2835761321523638096">Đọc và thay đổi các mục trong danh sách đọc</translation>
@@ -4126,6 +4129,7 @@
 <translation id="3978325380690188371">Bạn không thể sử dụng phím cố định khi đang bật ChromeVox</translation>
 <translation id="3979395879372752341">Đã thêm tiện ích mới (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326">Bật <ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">Ẩn các thẻ này</translation>
 <translation id="3981058120448670012">Hiển thị với các thiết bị ở gần dưới tên <ph name="DEVICE_NAME" /> trong <ph name="REMAINING_TIME" />...</translation>
 <translation id="3981760180856053153">Loại lưu không hợp lệ được nhập.</translation>
 <translation id="3982375475032951137">Thiết lập trình duyệt qua một số bước đơn giản</translation>
@@ -6321,6 +6325,7 @@
 <translation id="5642508497713047">Trình ký CRL</translation>
 <translation id="5643191124441701136">Mã bảo mật nằm ở mặt trước của thẻ</translation>
 <translation id="5643321261065707929">Mạng có đo lượng dữ liệu</translation>
+<translation id="5643717184207603910">Tăng tốc hiệu suất</translation>
 <translation id="5646376287012673985">Vị trí</translation>
 <translation id="5646558797914161501">Doanh nhân</translation>
 <translation id="5648021990716966815">Giắc cắm micrô</translation>
@@ -6425,6 +6430,7 @@
 <translation id="5733109311583381874">Thêm từ của chính bạn vào từ điển người dùng để tuỳ chỉnh các đề xuất chuyển đổi.</translation>
 <translation id="5734362860645681824">Truyền thông</translation>
 <translation id="5734697361979786483">Thêm mục chia sẻ tệp</translation>
+<translation id="5735513236153491131">Tăng tốc ngay</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{Dữ liệu này hoặc thiết bị của bạn không đáp ứng một số chính sách bảo mật của tổ chức. Hãy trao đổi với quản trị viên của bạn để biết những vấn đề cần khắc phục.}=1{Tệp này hoặc thiết bị của bạn không đáp ứng một số chính sách bảo mật của tổ chức. Hãy trao đổi với quản trị viên của bạn để biết những vấn đề cần khắc phục.}other{Những tệp này không đáp ứng một số chính sách bảo mật của tổ chức. Hãy trao đổi với quản trị viên của bạn để biết những vấn đề cần khắc phục.}}</translation>
 <translation id="5738093759615225354">Bạn cần khoá đăng nhập này để đăng nhập vào máy tính của mình</translation>
 <translation id="5739017626473506901">Đăng nhập để giúp <ph name="USER_NAME" /> thêm tài khoản trường học</translation>
@@ -8239,6 +8245,7 @@
 <translation id="7114054701490058191">Mật khẩu không khớp</translation>
 <translation id="7114648273807173152">Để đăng nhập vào Tài khoản Google bằng Smart Lock, hãy chuyển đến mục Cài đặt &gt; Thiết bị đã kết nối &gt; Điện thoại của bạn &gt; Smart Lock.</translation>
 <translation id="7115361495406486998">Không có người liên hệ nào có thể chia sẻ</translation>
+<translation id="7115731767122970828">Tăng tốc ngay</translation>
 <translation id="7116554090938189816">Chứng chỉ SSL của máy in đã hết hạn. Khởi động lại máy in rồi thử lại.</translation>
 <translation id="7117228822971127758">Vui lòng thử lại sau</translation>
 <translation id="7118268675952955085">ảnh chụp màn hình</translation>
@@ -8394,6 +8401,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Tốt nhất)</translation>
 <translation id="7246230585855757313">Cắm lại khóa bảo mật rồi thử lại lần nữa</translation>
 <translation id="724835896049478274">Tài khoản hiện có để sử dụng cho các ứng dụng Android</translation>
+<translation id="7248802599439396696">Dừng hoạt động của thẻ</translation>
 <translation id="7249197363678284330">Thay đổi chế độ cài đặt này trong thanh địa chỉ.</translation>
 <translation id="7249764475759804559">Thêm ứng dụng này làm một tuỳ chọn để mở tệp</translation>
 <translation id="7250616558727237648">Thiết bị mà bạn đang chia sẻ tệp không phản hồi. Vui lòng thử lại.</translation>
@@ -9992,6 +10000,7 @@
 <translation id="8390392581097975659">Đang cài đặt phần mềm của máy quét</translation>
 <translation id="8390449457866780408">Máy chủ không khả dụng.</translation>
 <translation id="8391218455464584335">Vinyl</translation>
+<translation id="8391918125842702622">Cảnh báo vấn đề về hiệu suất</translation>
 <translation id="8392726714909453725">Cài đặt Chọn để nói</translation>
 <translation id="8393511274964623038">Ngừng plugin</translation>
 <translation id="839363317075970734">Thông tin chi tiết về thiết bị Bluetooth</translation>
@@ -10092,6 +10101,7 @@
 <translation id="8466052016039127321">Không thể tiếp tục phiên trước đó</translation>
 <translation id="8467326454809944210">Chọn ngôn ngữ khác</translation>
 <translation id="8468087214092422866">Không được phép tìm thiết bị Bluetooth</translation>
+<translation id="8469863130477774813">Có thể tăng tốc hiệu suất</translation>
 <translation id="8470513973197838199">Đã lưu mật khẩu cho <ph name="ORIGIN" /></translation>
 <translation id="8471525937465764768">Các trang web thường kết nối với thiết bị USB để áp dụng những tính năng như in tài liệu hoặc lưu vào thiết bị lưu trữ</translation>
 <translation id="8471959340398751476">Tính năng nhận chiết khấu đang tắt. Bạn có thể bật tính năng này trong trình đơn tùy chỉnh</translation>
diff --git a/chrome/app/resources/generated_resources_zh-HK.xtb b/chrome/app/resources/generated_resources_zh-HK.xtb
index e0c6f24..f86e4e1 100644
--- a/chrome/app/resources/generated_resources_zh-HK.xtb
+++ b/chrome/app/resources/generated_resources_zh-HK.xtb
@@ -973,6 +973,7 @@
 <translation id="1697150536837697295">藝術</translation>
 <translation id="1697686431566694143">編輯檔案</translation>
 <translation id="1698796500103229697">付款方法(&amp;P)</translation>
+<translation id="1698899521169711967">鍵盤瀏覽</translation>
 <translation id="1699807488537653303">修正密碼錯誤</translation>
 <translation id="1700201317341192482">移除虛擬卡</translation>
 <translation id="1700517974991662022">己經去過</translation>
@@ -2482,6 +2483,7 @@
 <translation id="2771816809568414714">芝士</translation>
 <translation id="2772936498786524345">忍者</translation>
 <translation id="2773288106548584039">舊版瀏覽器支援</translation>
+<translation id="2773621783913034737">設定為閒置分頁</translation>
 <translation id="2773802008104670137">此類檔案可能會損害您的電腦。</translation>
 <translation id="2775104091073479743">編輯指紋</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{擴充程式「<ph name="EXTENSION" />」當時正在存取裝置}=1{擴充程式「<ph name="EXTENSION" />」正在存取 {0} 部裝置}other{擴充程式「<ph name="EXTENSION" />」正在存取 {0} 部裝置}}</translation>
@@ -2562,6 +2564,7 @@
 <translation id="2830528677948328648">管理 Google 帳戶(&amp;G)</translation>
 <translation id="2831430281393059038">支援裝置</translation>
 <translation id="2832124733806557606">子女可使用 PIN 來登入裝置或裝置解鎖。</translation>
+<translation id="2833144527504272627">使用文字游標瀏覽</translation>
 <translation id="2835177225987815960">系統將會重設目前的掃瞄設定,包括任何已指派的按鈕裝置和自動掃瞄速度偏好設定。</translation>
 <translation id="2835547721736623118">語音識別服務</translation>
 <translation id="2835761321523638096">讀取及變更閱讀清單中的項目</translation>
@@ -4114,6 +4117,7 @@
 <translation id="3978325380690188371">ChromeVox 開啟時,相黏鍵將無法使用</translation>
 <translation id="3979395879372752341">已新增以下擴充功能:<ph name="EXTENSION_NAME" /></translation>
 <translation id="3979748722126423326">啟用 <ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">隱藏這些分頁</translation>
 <translation id="3981058120448670012">以「<ph name="DEVICE_NAME" />」向附近的裝置顯示 <ph name="REMAINING_TIME" />…</translation>
 <translation id="3981760180856053153">輸入的儲存類型無效。</translation>
 <translation id="3982375475032951137">只需幾個簡單步驟,便可以完成瀏覽器設定</translation>
@@ -6298,6 +6302,7 @@
 <translation id="5642508497713047">CRL 簽署者</translation>
 <translation id="5643191124441701136">安全碼在付款卡正面</translation>
 <translation id="5643321261065707929">按用量收費的網絡</translation>
+<translation id="5643717184207603910">維持快速效能</translation>
 <translation id="5646376287012673985">位置</translation>
 <translation id="5646558797914161501">商人</translation>
 <translation id="5648021990716966815">麥克風插孔</translation>
@@ -6402,6 +6407,7 @@
 <translation id="5733109311583381874">將您的字詞增至用戶字典,以便自訂轉換候選字詞。</translation>
 <translation id="5734362860645681824">通訊工具</translation>
 <translation id="5734697361979786483">新增檔案共用</translation>
+<translation id="5735513236153491131">立即提升</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{此項資料或您的裝置不符合您機構的部分安全政策規定。請向您的管理員查詢,瞭解需要修正的項目。}=1{此檔案或您的裝置不符合您機構的部分安全政策規定。請向您的管理員查詢,瞭解需要修正的項目。}other{這些檔案不符合您機構的部分安全政策規定。請向您的管理員查詢,瞭解需要修正的項目。}}</translation>
 <translation id="5738093759615225354">您需要使用此密鑰,才能在電腦上登入帳戶</translation>
 <translation id="5739017626473506901">需要登入才能為 <ph name="USER_NAME" /> 新增學校帳戶</translation>
@@ -8213,6 +8219,7 @@
 <translation id="7114054701490058191">密碼不符</translation>
 <translation id="7114648273807173152">如要使用 Smart Lock 登入 Google 帳戶,請前往 [設定] &gt; [已連接的裝置] &gt; [您的手機] &gt; [Smart Lock]。</translation>
 <translation id="7115361495406486998">沒有可用的聯絡人</translation>
+<translation id="7115731767122970828">立即提升</translation>
 <translation id="7116554090938189816">打印機 SSL 憑證已過期。請重新啟動打印機,並再試一次。</translation>
 <translation id="7117228822971127758">請稍後再試</translation>
 <translation id="7118268675952955085">螢幕截圖</translation>
@@ -8368,6 +8375,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (最佳)</translation>
 <translation id="7246230585855757313">請重新插入安全密鑰,然後再試一次</translation>
 <translation id="724835896049478274">適用於 Android 應用程式的帳戶</translation>
+<translation id="7248802599439396696">設定為閒置分頁</translation>
 <translation id="7249197363678284330">在網址列中變更此設定。</translation>
 <translation id="7249764475759804559">將此應用程式納入為檔案開啟方式選項</translation>
 <translation id="7250616558727237648">您要分享檔案的目標裝置沒有回應,請再試一次。</translation>
@@ -9962,6 +9970,7 @@
 <translation id="8390392581097975659">正在安裝掃瞄器軟件</translation>
 <translation id="8390449457866780408">無法與伺服器連線。</translation>
 <translation id="8391218455464584335">黑膠唱片</translation>
+<translation id="8391918125842702622">效能問題快訊</translation>
 <translation id="8392726714909453725">揀選朗讀內容設定</translation>
 <translation id="8393511274964623038">停止外掛程式</translation>
 <translation id="839363317075970734">藍牙裝置詳情</translation>
@@ -10062,6 +10071,7 @@
 <translation id="8466052016039127321">無法恢復上一個工作階段</translation>
 <translation id="8467326454809944210">選擇其他語言</translation>
 <translation id="8468087214092422866">不允許尋找藍牙裝置</translation>
+<translation id="8469863130477774813">有可用的效能提升方式</translation>
 <translation id="8470513973197838199">已儲存 <ph name="ORIGIN" /> 的密碼</translation>
 <translation id="8471525937465764768">網站通常會連接 USB 裝置,以提供列印文件或儲存至儲存裝置等功能</translation>
 <translation id="8471959340398751476">折扣搜尋功能已關閉。您可在自訂選單中開啟此功能</translation>
diff --git a/chrome/app/resources/generated_resources_zu.xtb b/chrome/app/resources/generated_resources_zu.xtb
index 30bbde9..e885dfd6 100644
--- a/chrome/app/resources/generated_resources_zu.xtb
+++ b/chrome/app/resources/generated_resources_zu.xtb
@@ -972,6 +972,7 @@
 <translation id="1697150536837697295">Ubuciko</translation>
 <translation id="1697686431566694143">Hlela ifayela</translation>
 <translation id="1698796500103229697">&amp;Izindlela Zokukhokha</translation>
+<translation id="1698899521169711967">Ukuphequlula kwecaret</translation>
 <translation id="1699807488537653303">Lungisa iphutha lephasiwedi</translation>
 <translation id="1700201317341192482">Susa ikhadi lakho le-virtual</translation>
 <translation id="1700517974991662022">Uvakashe</translation>
@@ -2484,6 +2485,7 @@
 <translation id="2771816809568414714">Ushizi</translation>
 <translation id="2772936498786524345">Iyanyonyoba</translation>
 <translation id="2773288106548584039">Usekelo lwesiphequluli sefa</translation>
+<translation id="2773621783913034737">Yenza Amathebhu Angasebenzi</translation>
 <translation id="2773802008104670137">Lolu hlobo lwefayela lungalimaza ikhompuyutha yakho.</translation>
 <translation id="2775104091073479743">Hlela izingxivizo zeminwe</translation>
 <translation id="2775420101802644975">{NUM_CONNECTION,plural, =0{Isandiso se-"<ph name="EXTENSION" />" besifinyelela amadivayisi}=1{Isandiso se-"<ph name="EXTENSION" />" sifinyelela idivayisi e-{0}}one{Isandiso se-"<ph name="EXTENSION" />" sifinyelela amadivayisi angu-{0}}other{Isandiso se-"<ph name="EXTENSION" />" sifinyelela amadivayisi angu-{0}}}</translation>
@@ -2564,6 +2566,7 @@
 <translation id="2830528677948328648">Phatha &amp;i-Google account yakho</translation>
 <translation id="2831430281393059038">Idivayisi iyasekelwa</translation>
 <translation id="2832124733806557606">Ingane yakho ingasebenzisa Iphinikhodi ukungena ngemvume noma ukuvula idivayisi.</translation>
+<translation id="2833144527504272627">Funa ngecursor yombhalo</translation>
 <translation id="2835177225987815960">Isethaphu yakho yamanje yokuskena izosethwa kabusha, okuhlanganisa noma yikuphi ukushintsha okwabelwe nokuncanyelwayo kwejubane lokuskena ngokuzenzekelayo.</translation>
 <translation id="2835547721736623118">Isevisi yokubonwa kwengxoxo</translation>
 <translation id="2835761321523638096">Funda futhi ushintshe okufakiwe ohlwini lokufunda</translation>
@@ -4119,6 +4122,7 @@
 <translation id="3978325380690188371">Okhiye abanamathelayo abatholakali uma i-ChromeVox ivuliwe</translation>
 <translation id="3979395879372752341">Kungezwe kusandiso esisha (<ph name="EXTENSION_NAME" />)</translation>
 <translation id="3979748722126423326">Nika amandla i-<ph name="NETWORKDEVICE" /></translation>
+<translation id="398095528354975981">Fihla lawa mathebhu</translation>
 <translation id="3981058120448670012">Kubonakala kumadivayisi aseduze njenge-<ph name="DEVICE_NAME" /> kokungu-<ph name="REMAINING_TIME" />...</translation>
 <translation id="3981760180856053153">Kufakwe uhlobo olungavumelekile lokulondoloza.</translation>
 <translation id="3982375475032951137">Setha isiphequluli sakho ngezinyathelo ezilula ezimbalwa</translation>
@@ -6312,6 +6316,7 @@
 <translation id="5642508497713047">Isisayini se-CRL</translation>
 <translation id="5643191124441701136">Ikhodi yakho yokuphepha ephambili ekhadini lakho</translation>
 <translation id="5643321261065707929">Inethiwekhi eyenziwe imitha</translation>
+<translation id="5643717184207603910">Gcina ukusebenza kunejubane</translation>
 <translation id="5646376287012673985">Indawo</translation>
 <translation id="5646558797914161501">Usomabhizinisi</translation>
 <translation id="5648021990716966815">Umgodi we-earphone</translation>
@@ -6416,6 +6421,7 @@
 <translation id="5733109311583381874">Engeza amagama wakho kuzichazamazwi zomsebenzisi ukuze wenze ngezifiso ukuguqulwa kwamakhandidethi.</translation>
 <translation id="5734362860645681824">Ezokuxhumana</translation>
 <translation id="5734697361979786483">Engeza ukwabelana kwefayela</translation>
+<translation id="5735513236153491131">Yenza iBoost Manje</translation>
 <translation id="5736092224453113618">{NUM_FILES,plural, =0{Le datha noma idivayisi yakho akuhlangabezani nezinye izinqubomgomo zokuvikeleka zenhlangano yakho. Hlola nomphathi wakho mayelana nalokho okudingeka ukuthi kulungiswe.}=1{Leli fayela noma idivayisi yakho akuhlangabezani nezinye izinqubomgomo zokuvikeleka zenhlangano yakho. Hlola nomphathi wakho mayelana nalokho okudingeka ukuthi kulungiswe.}one{Lamafayela awahlangabezani nezinye izinqubomgomo zokuvikeleka zenhlangano yakho. Hlola nomphathi wakho mayelana nalokho okudingeka ukuthi kulungiswe.}other{Lamafayela awahlangabezani nezinye izinqubomgomo zokuvikeleka zenhlangano yakho. Hlola nomphathi wakho mayelana nalokho okudingeka ukuthi kulungiswe.}}</translation>
 <translation id="5738093759615225354">Udinga lo khiye wokungena ukuze ungene ngemvume kwikhompyutha yakho</translation>
 <translation id="5739017626473506901">Ngena ngemvume ukuze usize u-<ph name="USER_NAME" /> angeze i-akhawunti yesikole</translation>
@@ -8228,6 +8234,7 @@
 <translation id="7114054701490058191">Amaphasiwedi awafani</translation>
 <translation id="7114648273807173152">Ukuze usebenzise i-Smart Lock ukuze ungene ngemvume ku-akhawunti yakho ye-Google, hamba Kuzilungiselelo &gt; Amadivayisi axhunyiwe &gt; Ifoni yakho &gt; I-Smart Lock.</translation>
 <translation id="7115361495406486998">Abekho oxhumana nabo abafinyelelekayo</translation>
+<translation id="7115731767122970828">Yenza iboost manje</translation>
 <translation id="7116554090938189816">Isitifiketi se-SSL yephrinta siphelelwe yisikhathi. Qala kabusha iphrinta bese uyazama futhi.</translation>
 <translation id="7117228822971127758">Uyacelwa uphinde uzame futhi ekuhambeni kwesikhathi</translation>
 <translation id="7118268675952955085">isithombe-skrini</translation>
@@ -8383,6 +8390,7 @@
 <translation id="7245628041916450754"><ph name="WIDTH" /> x <ph name="HEIGHT" /> (Okuhamba phambili)</translation>
 <translation id="7246230585855757313">Faka kabusha ukhiye wakho wokuqinisekisa ubunikazi bes uyazama futhi</translation>
 <translation id="724835896049478274">Ama-akhawunti atholakalela ama-app e-Android</translation>
+<translation id="7248802599439396696">Yenza amathebhu angasebenzi</translation>
 <translation id="7249197363678284330">Shintsha leli sethingi kubha yekheli.</translation>
 <translation id="7249764475759804559">Faka phakathi le app njengenketho lapho uvula amafayela</translation>
 <translation id="7250616558727237648">Idivayisi owabelana nayo ayisabelanga. Sicela uzame futhi.</translation>
@@ -9976,6 +9984,7 @@
 <translation id="8390392581097975659">Ifaka isofthiwe yeskena</translation>
 <translation id="8390449457866780408">Iseva ayitholakali.</translation>
 <translation id="8391218455464584335">Ivayinali</translation>
+<translation id="8391918125842702622">Isexwayiso sokusebenza koshicilelo</translation>
 <translation id="8392726714909453725">Amasethingi okuthi Khetha ukuze ukhulume</translation>
 <translation id="8393511274964623038">Misa i-plugin</translation>
 <translation id="839363317075970734">Imininingwane yedivayisi ye-Bluetooth</translation>
@@ -10076,6 +10085,7 @@
 <translation id="8466052016039127321">Ayikwazi ukuqhubeka ngeseshini yangaphambilini</translation>
 <translation id="8467326454809944210">Khetha olunye ulimi</translation>
 <translation id="8468087214092422866">Ayivunyelwe ukubheka amadivayisi e-Bluetooth</translation>
+<translation id="8469863130477774813">Iboost yokusebenza iyatholakala</translation>
 <translation id="8470513973197838199">Amaphasiwedi alondoloziwe e-<ph name="ORIGIN" /></translation>
 <translation id="8471525937465764768">Amasayithi avamise ukuxhuma amadivayisi e-USB kuzici ezifana nokuphrinta idokhumenti noma ukulondoloza kudivayisi yesitoreji</translation>
 <translation id="8471959340398751476">Izaphulelo zivaliwe. Ungazivula kumenyu engokwezifiso</translation>
diff --git a/chrome/app/resources/google_chrome_strings_am.xtb b/chrome/app/resources/google_chrome_strings_am.xtb
index c4330b8f..ca62e2f 100644
--- a/chrome/app/resources/google_chrome_strings_am.xtb
+++ b/chrome/app/resources/google_chrome_strings_am.xtb
@@ -254,6 +254,7 @@
 <translation id="4561051373932531560">Google Chrome ድር ላይ ያለ ስልክ ቁጥር ጠቅ እንዲያደርጉት እና በSkype እንዲደውሉለት ያስችልዎታል!</translation>
 <translation id="4567424176335768812">እንደ <ph name="USER_EMAIL_ADDRESS" /> ሆነው ገብተዋል። አሁን የእርስዎን ዕልባቶች፣ ታሪክ እና ሌሎች ቅንብሮች በመለያ በገቡ ሁሉም መሣሪያዎችዎ ላይ መድረስ ይችላሉ።</translation>
 <translation id="4571503333518166079">ወደ Chrome ማሳወቂያ ቅንብሮች ይሂዱ</translation>
+<translation id="4575717501879784448">Chrome የአሰሳ ተሞክሮዎን ለማሻሻል እና ንብረቶችን ቦታ ለማስለቀቅ እነዚህን ትሮች ገቢር እንዳይሆኑ ሊያደርጋቸው ይችላል።</translation>
 <translation id="459622048091363950">አንዴ Chrome መዳረሻ ከኖረው በኋላ ድር ጣቢያዎች እርስዎን መዳረሻ መጠየቅ ይችላሉ።</translation>
 <translation id="4600710005438004015">Chrome ወደ የቅርብ ጊዜው ስሪት ሊዘመን አልቻለም፣ ስለዚህ አዲስ ባህሪያት እና የደህንነት ማስተካከያዎች እያመለጠዎት ነው።</translation>
 <translation id="4624065194742029982">Chrome ማንነት የማያሳውቅ</translation>
@@ -285,6 +286,7 @@
 <translation id="4970761609246024540">ወደ Chrome መገለጫዎች እንኳን በደህና መጡ</translation>
 <translation id="4970880042055371251">የChromeOS ስሪት</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Chrome የአሰሳ ተሞክሮዎን ለማሻሻል እና ነገሮች ፍጥነት ኖሯቸው ለማቆየት እነዚህን ትሮች ሊያቦዝናቸው ይችላል።</translation>
 <translation id="5003967926796347400">«Google የይለፍ ቃል አስተዳዳሪ» ላይ ጠቅ ያድርጉ</translation>
 <translation id="5120334927898581447">ወደ ሌሎች የGoogle አገልግሎቶች ሲገቡ ወደ Chrome ይግቡ</translation>
 <translation id="5126049312684316860">እርስዎ የመጎብኘት ዕድልዎ ከፍተኛ የሆኑባቸው ተጨማሪ ገጾች ሲጎበኟቸው ይበልጥ በፍጥነት እንዲጫኑ Chrome በቅድሚያ ይጭናቸዋል</translation>
@@ -349,6 +351,7 @@
 <translation id="608006075545470555">የስራ መገለጫ ወደዚህ አሳሽ ያክሉ</translation>
 <translation id="6097822892606850415">በAI እርዳታ አማካኝነት በበለጠ በራስ መተማመን ይጻፉ</translation>
 <translation id="6113794647360055231">Chrome አሁን ይበልጥ ተሻሽሏል</translation>
+<translation id="6135456723633883042">እነዚህ ትሮች ተጨማሪ ንብረቶችን እየተጠቀሙ ነው። አፈፃፀምዎን ለማሻሻል Chrome እንዲያቦዝናቸው ይፍቀዱ።</translation>
 <translation id="6145313976051292476">PDFዎችን በChrome ውስጥ ክፈት</translation>
 <translation id="6157638032135951407">ድርጅትዎ የChrome ውሂብን ለ<ph name="TIMEOUT_DURATION" /> ያህል ሥራ ላይ ሳይውል ይሰርዘዋል። ይህ ታሪክን፣ ራስ-ሙላን እና ውርዶችን ሊያካትት ይችላል።</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_bn.xtb b/chrome/app/resources/google_chrome_strings_bn.xtb
index 5129ed5e..d389fe0b 100644
--- a/chrome/app/resources/google_chrome_strings_bn.xtb
+++ b/chrome/app/resources/google_chrome_strings_bn.xtb
@@ -253,6 +253,7 @@
 <translation id="4561051373932531560">Google Chrome আপনাকে ওয়েবে কোনো ফোন নম্বরে ক্লিক করতে এবং Skype-এর মাধ্যমে সেটিতে কল করতে দেয়!</translation>
 <translation id="4567424176335768812">আপনি <ph name="USER_EMAIL_ADDRESS" /> হিসেবে সাইন-ইন করেছেন৷ এখন আপনি আপনার সমস্ত সাইন-ইন করা ডিভাইসে আপনার বুকমার্ক, ইতিহাস এবং অন্যান্য সেটিংস অ্যাক্সেস করতে পারেন৷</translation>
 <translation id="4571503333518166079">Chrome বিজ্ঞপ্তি সেটিংসে যান</translation>
+<translation id="4575717501879784448">আপনার ব্রাউজ করার অভিজ্ঞতা উন্নত করার জন্য Chrome এইসব ট্যাব বন্ধ করে দিতে পারে, এর ফলে রিসোর্স কম ব্যবহার হবে।</translation>
 <translation id="459622048091363950">Chrome অ্যাক্সেস পেলেই, ওয়েবসাইটগুলি আপনাকে অ্যাক্সেসের অনুরোধ করতে পারবে।</translation>
 <translation id="4600710005438004015">Chrom লেটেস্ট ভার্সনে আপডেট করা যাচ্ছে না, তাই আপনি নতুন বৈশিষ্ট্য এবং সুরক্ষা সমাধানগুলি পাচ্ছেন না।</translation>
 <translation id="4624065194742029982">Chrome-এর 'ছদ্মবেশী' মোড</translation>
@@ -284,6 +285,7 @@
 <translation id="4970761609246024540">Chrome প্রোফাইলে স্বাগতম</translation>
 <translation id="4970880042055371251">ChromeOS ভার্সন</translation>
 <translation id="4990567037958725628">Google Chrome  ক্যানারি</translation>
+<translation id="4997044641749333913">আপনার ব্রাউজ করার অভিজ্ঞতা উন্নত এবং দ্রুত করার জন্য Chrome এইসব ট্যাব বন্ধ করে দিতে পারে।</translation>
 <translation id="5003967926796347400">“Google Password Manager”-এ ক্লিক করুন</translation>
 <translation id="5120334927898581447">অন্যান্য Google পরিষেবায় সাইন-ইন করার সময় Chrome-এ সাইন-ইন করুন</translation>
 <translation id="5126049312684316860">আপনি ভিজিট করতে পারেন এমন আরও বেশি সংখ্যক পৃষ্ঠা Chrome প্রিলোড করে, যাতে সেই ভিজিট করার সময় সেই পৃষ্ঠাগুলি আরও দ্রুত লোড হয়</translation>
@@ -346,6 +348,7 @@
 <translation id="608006075545470555">এই ব্রাউজারে অফিস প্রোফাইল যোগ করুন</translation>
 <translation id="6097822892606850415">AI-এর সাহায্যে আরও আত্মবিশ্বাসের সাথে লিখুন</translation>
 <translation id="6113794647360055231">Chrome আরও ভাল হয়ে উঠেছে</translation>
+<translation id="6135456723633883042">এইসব ট্যাব অতিরিক্ত রিসোর্স ব্যবহার করছে। আপনার পারফর্ম্যান্স উন্নত করতে, Chrome-কে এগুলি বন্ধ করতে দিন।</translation>
 <translation id="6145313976051292476">Chrome-এ পিডিএফ ফাইল খুলুন</translation>
 <translation id="6157638032135951407"><ph name="TIMEOUT_DURATION" /> ধরে ব্যবহার করা না হলে, আপনার সংস্থা Chrome ডেটা মুছে দেয়। এর মধ্যে ইতিহাস, অটোফিল এবং ডাউনলোড সংক্রান্ত ডেটা থাকতে পারে।</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_cy.xtb b/chrome/app/resources/google_chrome_strings_cy.xtb
index 27ed85be..0e20c27a 100644
--- a/chrome/app/resources/google_chrome_strings_cy.xtb
+++ b/chrome/app/resources/google_chrome_strings_cy.xtb
@@ -255,6 +255,7 @@
 <translation id="4561051373932531560">Mae Google Chrome yn gadael i chi glicio rhif ffôn ar y we a'i ffonio gyda Skype!</translation>
 <translation id="4567424176335768812">Rydych wedi'ch mewngofnodi ar hyn o bryd fel <ph name="USER_EMAIL_ADDRESS" />. Gallwch bellach gael mynediad at eich nodau tudalen, eich hanes, a'ch gosodiadau eraill ar eich holl ddyfeisiau sydd wedi'u mewngofnodi.</translation>
 <translation id="4571503333518166079">Ewch i osodiadau hysbysu Chrome</translation>
+<translation id="4575717501879784448">Gall Chrome wneud y tabiau hyn yn anweithredol i wella eich profiad pori a rhyddhau adnoddau.</translation>
 <translation id="459622048091363950">Ar ôl rhoi mynediad i Chrome, bydd modd i wefannau ofyn i chi am fynediad.</translation>
 <translation id="4600710005438004015">Ni allai Chrome ddiweddaru i'r fersiwn diweddaraf, felly rydych yn colli'r cyfle i fanteisio ar nodweddion newydd a gwelliannau diogelwch.</translation>
 <translation id="4624065194742029982">Chrome Anhysbys</translation>
@@ -286,6 +287,7 @@
 <translation id="4970761609246024540">Croeso i broffiliau Chrome</translation>
 <translation id="4970880042055371251">Fersiwn ChromeOS</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Gall Chrome wneud y tabiau hyn yn anweithredol i wella'ch profiad pori a chadw pethau'n gyflym.</translation>
 <translation id="5003967926796347400">Cliciwch 'Rheolwr Cyfrineiriau Google'</translation>
 <translation id="5120334927898581447">Mewngofnodwch i Chrome pan fyddwch yn mewngofnodi i wasanaethau Google eraill</translation>
 <translation id="5126049312684316860">Mae Chrome yn rhaglwytho hyd yn oed mwy o dudalennau rydych yn debygol o ymweld â nhw, fel eu bod yn llwytho yn gyflymach pan rydych yn gwneud hynny</translation>
@@ -350,6 +352,7 @@
 <translation id="608006075545470555">Ychwanegu Proffil Gwaith i'r porwr hwn</translation>
 <translation id="6097822892606850415">Ysgrifennwch gyda mwy o hyder gyda help gan AI</translation>
 <translation id="6113794647360055231">Gwnaeth Chrome wella</translation>
+<translation id="6135456723633883042">Mae'r tabiau hyn yn defnyddio adnoddau ychwanegol. Er mwyn gwella eich perfformiad, gadewch i Chrome eu gwneud yn anweithredol.</translation>
 <translation id="6145313976051292476">Agor ffeiliau PDF yn Chrome</translation>
 <translation id="6157638032135951407">Mae eich sefydliad yn dileu data Chrome pan na chaiff ei ddefnyddio am <ph name="TIMEOUT_DURATION" />. Gallai hyn gynnwys hanes, awtolenwi, a lawrlwythiadau.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_da.xtb b/chrome/app/resources/google_chrome_strings_da.xtb
index 4af6b95..8d76f69b 100644
--- a/chrome/app/resources/google_chrome_strings_da.xtb
+++ b/chrome/app/resources/google_chrome_strings_da.xtb
@@ -251,6 +251,7 @@
 <translation id="4561051373932531560">Med Google Chrome kan du klikke på et telefonnummer på nettet og ringe op til det via Skype!</translation>
 <translation id="4567424176335768812">Du er logget ind som <ph name="USER_EMAIL_ADDRESS" />. Nu kan du få adgang til dine bogmærker, din historik og andre indstillinger på alle de enheder, hvor du er logget ind.</translation>
 <translation id="4571503333518166079">Gå til indstillinger for Chrome-notifikationer</translation>
+<translation id="4575717501879784448">Chrome kan gøre disse faner inaktive for at forbedre din browseroplevelse og frigøre ressourcer.</translation>
 <translation id="459622048091363950">Når Chrome har adgang, kan websites bede dig om adgang.</translation>
 <translation id="4600710005438004015">Chrome kunne ikke opdateres til den nyeste version, så du går glip af nye funktioner og sikkerhedsrettelser.</translation>
 <translation id="4624065194742029982">Inkognitotilstand i Chrome</translation>
@@ -282,6 +283,7 @@
 <translation id="4970761609246024540">Velkommen til Chrome-profiler</translation>
 <translation id="4970880042055371251">ChromeOS-version</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Chrome kan gøre disse faner inaktive for at forbedre din browseroplevelse og give dig hurtigere indlæsning.</translation>
 <translation id="5003967926796347400">Klik på "Google Adgangs­kode­admin­istrator"</translation>
 <translation id="5120334927898581447">Log ind i Chrome, når du logger ind i andre Google-tjenester</translation>
 <translation id="5126049312684316860">Chrome forudindlæser endnu flere sider, som du sandsynligvis vil besøge, så de indlæses hurtigere, når du besøger dem</translation>
@@ -342,6 +344,7 @@
 <translation id="608006075545470555">Føj arbejdsprofilen til denne browser</translation>
 <translation id="6097822892606850415">Skriv mere selvsikkert med hjælp fra AI</translation>
 <translation id="6113794647360055231">Chrome er blevet bedre</translation>
+<translation id="6135456723633883042">Disse faner bruger ekstra ressourcer. Du kan forbedre ydeevnen ved at give Chrome tilladelse til at gøre dem inaktive.</translation>
 <translation id="6145313976051292476">Åbn PDF-filer i Chrome</translation>
 <translation id="6157638032135951407">Din organisation sletter Chrome-data, når de ikke har været i brug i <ph name="TIMEOUT_DURATION" />. Disse data kan omfatte historik, Autofyld og downloads.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> – Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_en-GB.xtb b/chrome/app/resources/google_chrome_strings_en-GB.xtb
index 17e2fbd..b8213b5 100644
--- a/chrome/app/resources/google_chrome_strings_en-GB.xtb
+++ b/chrome/app/resources/google_chrome_strings_en-GB.xtb
@@ -254,6 +254,7 @@
 <translation id="4561051373932531560">Google Chrome lets you click a phone number on the web and call it with Skype!</translation>
 <translation id="4567424176335768812">You're signed in as <ph name="USER_EMAIL_ADDRESS" />. Now you can access your bookmarks, history and other settings on all your signed in devices.</translation>
 <translation id="4571503333518166079">Go to Chrome notification settings</translation>
+<translation id="4575717501879784448">Chrome can make these tabs inactive to improve your browsing experience and free up resources.</translation>
 <translation id="459622048091363950">Once Chrome has access, websites will be able to ask you for access.</translation>
 <translation id="4600710005438004015">Chrome couldn't update to the latest version, so you're missing out on new features and security fixes.</translation>
 <translation id="4624065194742029982">Chrome Incognito</translation>
@@ -285,6 +286,7 @@
 <translation id="4970761609246024540">Welcome to Chrome profiles</translation>
 <translation id="4970880042055371251">Chrome OS version</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Chrome can make these tabs inactive to improve your browsing experience and keep things fast.</translation>
 <translation id="5003967926796347400">Click 'Google Password Manager'</translation>
 <translation id="5120334927898581447">Sign in to Chrome when you sign in to other Google services</translation>
 <translation id="5126049312684316860">Chrome preloads even more pages that you're likely to visit, so that they load more quickly when you visit them.</translation>
@@ -349,6 +351,7 @@
 <translation id="608006075545470555">Add work profile to this browser</translation>
 <translation id="6097822892606850415">Write with more confidence with help from AI</translation>
 <translation id="6113794647360055231">Chrome just got better</translation>
+<translation id="6135456723633883042">These tabs are using extra resources. To improve your performance, let Chrome make them inactive.</translation>
 <translation id="6145313976051292476">Open PDFs in Chrome</translation>
 <translation id="6157638032135951407">Your organisation deletes Chrome data when it isn't used for <ph name="TIMEOUT_DURATION" />. This could include history, autofill and downloads.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_es.xtb b/chrome/app/resources/google_chrome_strings_es.xtb
index 7c8cdfb..7785db8 100644
--- a/chrome/app/resources/google_chrome_strings_es.xtb
+++ b/chrome/app/resources/google_chrome_strings_es.xtb
@@ -255,6 +255,7 @@
 <translation id="4561051373932531560">Google Chrome te permite hacer clic en un número de teléfono en la Web y llamar mediante Skype.</translation>
 <translation id="4567424176335768812">Has iniciado sesión como <ph name="USER_EMAIL_ADDRESS" />. Ahora puedes acceder a tus marcadores, a tu historial y a otras opciones en todos los dispositivos en los que hayas iniciado sesión.</translation>
 <translation id="4571503333518166079">Ir a los ajustes de notificaciones de Chrome</translation>
+<translation id="4575717501879784448">Chrome puede inactivar estas pestañas para mejorar tu experiencia de navegación y liberar recursos.</translation>
 <translation id="459622048091363950">Una vez que Chrome tenga acceso, los sitios web podrán solicitarlo también.</translation>
 <translation id="4600710005438004015">No se ha podido actualizar Chrome a la versión más reciente, por lo que no disfrutas de las últimas funciones y correcciones de seguridad.</translation>
 <translation id="4624065194742029982">Chrome en Incógnito</translation>
@@ -286,6 +287,7 @@
 <translation id="4970761609246024540">Te damos la bienvenida a los perfiles de Chrome</translation>
 <translation id="4970880042055371251">Versión de ChromeOS</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Chrome puede inactivar estas pestañas para mejorar y agilizar tu experiencia de navegación.</translation>
 <translation id="5003967926796347400">Haz clic en Gestor de contraseñas de Google</translation>
 <translation id="5120334927898581447">Iniciar sesión en Chrome al iniciar sesión en otros servicios de Google</translation>
 <translation id="5126049312684316860">Chrome precarga más páginas de las que probablemente visites para que se carguen más rápido si accedes a ellas</translation>
@@ -350,6 +352,7 @@
 <translation id="608006075545470555">Añadir perfil de trabajo a este navegador</translation>
 <translation id="6097822892606850415">Escribe con más confianza con la ayuda de la IA</translation>
 <translation id="6113794647360055231">Chrome mejor que nunca</translation>
+<translation id="6135456723633883042">Estas pestañas están usando recursos adicionales. Para mejorar tu rendimiento, permite que Chrome las inactive.</translation>
 <translation id="6145313976051292476">Abrir archivos PDF en Chrome</translation>
 <translation id="6157638032135951407">Tu organización elimina los datos de Chrome cuando lleva <ph name="TIMEOUT_DURATION" /> sin usarse. Entre estos datos, podrían incluirse el historial, la función Autocompletar y las descargas.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_eu.xtb b/chrome/app/resources/google_chrome_strings_eu.xtb
index 8f17c276..4c5046b 100644
--- a/chrome/app/resources/google_chrome_strings_eu.xtb
+++ b/chrome/app/resources/google_chrome_strings_eu.xtb
@@ -254,6 +254,7 @@
 <translation id="4561051373932531560">Google Chrome-rekin, telefono-zenbakietan klik egin dezakezu Skype bidez horietara deitzeko!</translation>
 <translation id="4567424176335768812"><ph name="USER_EMAIL_ADDRESS" /> gisa hasi duzu saioa. Laster-markak, historia eta bestelako ezarpenak atzi ditzakezu saioa hasita daukaten gailu guztien bidez.</translation>
 <translation id="4571503333518166079">Joan Chrome-ren jakinarazpen-ezarpenetara</translation>
+<translation id="4575717501879784448">Chrome-k inaktibo ezar ditzake fitxa hauek, arakatzea hobetzeko eta baliabideak libratzeko.</translation>
 <translation id="459622048091363950">Chrome-k sarbidea duenean, webguneek sarbidea eskatuko dizute.</translation>
 <translation id="4600710005438004015">Ezin izan da eguneratu Chrome azken bertsiora; beraz, ez dituzu erabilgarri eginbide berriak eta segurtasun-konponketak.</translation>
 <translation id="4624065194742029982">Chrome-ren ezkutuko modua</translation>
@@ -285,6 +286,7 @@
 <translation id="4970761609246024540">Ongi etorri Chrome-ko profiletara</translation>
 <translation id="4970880042055371251">Chrome OS-ren bertsioa</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Chrome-k inaktibo ezar ditzake fitxa hauek, arakatzea hobetzeko eta bizkortzeko.</translation>
 <translation id="5003967926796347400">Sakatu Google-ren Pasahitz-kudeatzailea</translation>
 <translation id="5120334927898581447">Hasi saioa Chrome-n Google-ren beste zerbitzuetan saioa hasten duzunean</translation>
 <translation id="5126049312684316860">Ziurrenik bisitatuko dituzun are orri gehiago aurrez kargatzen ditu Chrome-k, bisitatzen dituzunean bizkorrago karga daitezen</translation>
@@ -349,6 +351,7 @@
 <translation id="608006075545470555">Gehitu laneko profila arakatzaile honetan</translation>
 <translation id="6097822892606850415">Idatzi ziurtasun handiagoarekin AAren laguntzaz</translation>
 <translation id="6113794647360055231">Chrome hobetu egin dugu</translation>
+<translation id="6135456723633883042">Fitxa hauek baliabide gehigarriak erabiltzen dituzte. Errendimendua hobetzeko, eman fitxa horiek inaktibo ezartzeko baimena Chrome-ri.</translation>
 <translation id="6145313976051292476">Ireki PDFak Chrome-n</translation>
 <translation id="6157638032135951407">Erakundeak Chrome-ko datuak ezabatzen ditu <ph name="TIMEOUT_DURATION" />z erabiltzen ez denean. Arakatze-datuen barnean daude historia, automatikoki betetako datuak eta deskargak.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_fa.xtb b/chrome/app/resources/google_chrome_strings_fa.xtb
index f4a176d..117a9874 100644
--- a/chrome/app/resources/google_chrome_strings_fa.xtb
+++ b/chrome/app/resources/google_chrome_strings_fa.xtb
@@ -253,6 +253,7 @@
 <translation id="4561051373932531560">‏Google Chrome به شما اجازه می‌دهد بر روی شماره تلفن روی وب کلیک کرده و از طریق Skype تماس بگیرید!</translation>
 <translation id="4567424176335768812">با حساب <ph name="USER_EMAIL_ADDRESS" /> وارد سیستم شده‌اید. اکنون در همه دستگاه‌هایی که با آنها به سیستم وارد شده‌اید می‌توانید به نشانک‌ها، سابقه و دیگر تنظیماتتان دسترسی داشته باشید.</translation>
 <translation id="4571503333518166079">‏رفتن به تنظیمات اعلان Chrome</translation>
+<translation id="4575717501879784448">‏‫Chrome می‌تواند این برگه‌ها را غیرفعال کند تا تجربه مرور شما را بهبود بخشد و منابع را آزاد کند.</translation>
 <translation id="459622048091363950">‏وقتی Chrome دسترسی داشته باشد، وب‌سایت‌ها می‌توانند مجوز دسترسی درخواست کنند.</translation>
 <translation id="4600710005438004015">‏Chrome به جدیدترین نسخه به‌روزرسانی نشد، بنابراین قابلیت‌های جدید و رفع اشکال‌های امنیتی را ندارید.</translation>
 <translation id="4624065194742029982">‏حالت ناشناس Chrome</translation>
@@ -284,6 +285,7 @@
 <translation id="4970761609246024540">‏به نمایه‌های Chrome خوش‌آمدید</translation>
 <translation id="4970880042055371251">‏نسخه ChromeOS</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">‏‫Chrome می‌تواند این برگه‌ها را غیرفعال کند تا تجربه مرور شما را بهبود بخشد و سرعت بالا را حفظ کند.</translation>
 <translation id="5003967926796347400">‏روی «مدیر گذرواژه Google» کلیک کنید</translation>
 <translation id="5120334927898581447">‏ورود به سیستم Chrome هنگام وارد شدن به سیستم دیگر سرویس‌های Google</translation>
 <translation id="5126049312684316860">‏Chrome صفحه‌های بیشتری را که احتمالاً از آن‌ها بازدید خواهید کرد پیش‌بارگیری می‌کند تا وقتی از آن‌ها بازدید می‌کنید سریع‌تر بار شوند</translation>
@@ -344,6 +346,7 @@
 <translation id="608006075545470555">افزودن نمایه کاری به این مرورگر</translation>
 <translation id="6097822892606850415">با کمک هوش مصنوعی، با اعتماد به‌نفس بیشتری بنویسید</translation>
 <translation id="6113794647360055231">‏Chrome اکنون بهتر شده است</translation>
+<translation id="6135456723633883042">‏این برگه‌ها از منابع بیشتری استفاده می‌کنند. برای بهبود عملکرد، اجازه دهید Chrome آن‌ها را غیرفعال کند.</translation>
 <translation id="6145313976051292476">‏بازکردن فایل‌های PDF در Chrome</translation>
 <translation id="6157638032135951407">‏اگر <ph name="TIMEOUT_DURATION" /> از Chrome استفاده نشود، سازمانتان داده‌های آن را حذف می‌کند. این داده‌ها می‌تواند شامل سابقه، تکمیل خودکار، و بارگیری‌ها شود.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_fil.xtb b/chrome/app/resources/google_chrome_strings_fil.xtb
index 90172f6..85936b30 100644
--- a/chrome/app/resources/google_chrome_strings_fil.xtb
+++ b/chrome/app/resources/google_chrome_strings_fil.xtb
@@ -255,6 +255,7 @@
 <translation id="4561051373932531560">Pinapayagan ka ng Google Chrome na mag-click sa isang numero ng telepono sa web at tawagan ito gamit ang Skype!</translation>
 <translation id="4567424176335768812">Naka-sign in ka bilang <ph name="USER_EMAIL_ADDRESS" />. Maaari mo na ngayong i-access ang iyong mga bookmark, kasaysayan, at iba pang setting sa lahat ng iyong device na naka-sign in.</translation>
 <translation id="4571503333518166079">Pumunta sa mga setting ng notification ng Chrome</translation>
+<translation id="4575717501879784448">Magagawa ng Chrome na gawing hindi aktibo ang mga tab na ito para pagandahin ang iyong experience sa pag-browse at bakantehin ang mga resource.</translation>
 <translation id="459622048091363950">Kapag mayroon nang access ang Chrome, makakahingi na ang mga website ng access sa iyo.</translation>
 <translation id="4600710005438004015">Hindi ma-update ang Chrome sa pinakabagong bersyon, kaya hindi mo magagamit ang mga bagong feature at pag-aayos sa seguridad.</translation>
 <translation id="4624065194742029982">Incognito sa Chrome</translation>
@@ -286,6 +287,7 @@
 <translation id="4970761609246024540">Welcome sa mga profile sa Chrome</translation>
 <translation id="4970880042055371251">Bersyon ng ChromeOS</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Magagawa ng Chrome na gawing hindi aktibo ang mga tab na ito para pagandahin ang iyong experience sa pag-browse at panatilihing mabilis ang mga bagay.</translation>
 <translation id="5003967926796347400">I-click ang “Google Password Manager”</translation>
 <translation id="5120334927898581447">Mag-sign in sa Chrome kapag nag-sign in ka sa iba pang serbisyo ng Google</translation>
 <translation id="5126049312684316860">Nagpi-preload ang Chrome ng mas marami pang page na malamang na bibisitahin mo, para mas mabilis na mag-load ang mga ito kapag binisita mo</translation>
@@ -350,6 +352,7 @@
 <translation id="608006075545470555">Magdagdag ng Profile sa Trabaho sa browser na ito</translation>
 <translation id="6097822892606850415">Magsulat nang may higit pang kumpiyansa sa tulong ng AI</translation>
 <translation id="6113794647360055231">Mas mahusay na ang Chrome</translation>
+<translation id="6135456723633883042">Gumagamit ang mga tab na ito ng mga karagdagang resource. Para pahusayin ang iyong performance, hayaan ang Chrome na gawing hindi aktibo ang mga ito.</translation>
 <translation id="6145313976051292476">Magbukas ng mga PDF sa Chrome</translation>
 <translation id="6157638032135951407">Nagde-delete ang iyong organisasyon ng data ng Chrome kapag hindi ito ginagamit sa loob ng <ph name="TIMEOUT_DURATION" />. Posibleng kasama rito ang history, autofill, at mga download.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_fr-CA.xtb b/chrome/app/resources/google_chrome_strings_fr-CA.xtb
index f4edbd92..ba73c5e 100644
--- a/chrome/app/resources/google_chrome_strings_fr-CA.xtb
+++ b/chrome/app/resources/google_chrome_strings_fr-CA.xtb
@@ -254,6 +254,7 @@
 <translation id="4561051373932531560">Google Chrome vous permet de cliquer sur un numéro de téléphone dans une page Web pour faire un appel avec Skype!</translation>
 <translation id="4567424176335768812">Vous êtes connecté avec l'adresse de courriel <ph name="USER_EMAIL_ADDRESS" />. Vous pouvez maintenant accéder à vos favoris, à votre historique et à vos paramètres sur tous les appareils sur lesquels vous êtes connecté.</translation>
 <translation id="4571503333518166079">Accéder aux paramètres de notification Chrome</translation>
+<translation id="4575717501879784448">Chrome peut rendre ces onglets inactifs pour améliorer votre expérience de navigation et libérer des ressources.</translation>
 <translation id="459622048091363950">Lorsque Chrome y aura accès, les sites Web pourront vous demander l'accès.</translation>
 <translation id="4600710005438004015">Google Chrome n'a pas pu installer la nouvelle version, vous ne pouvez donc pas profiter des nouvelles fonctionnalités ni des correctifs relatifs à la sécurité.</translation>
 <translation id="4624065194742029982">Navigation privée de Chrome</translation>
@@ -285,6 +286,7 @@
 <translation id="4970761609246024540">Bienvenue dans les profils Chrome</translation>
 <translation id="4970880042055371251">Version de Chrome OS</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Chrome peut rendre ces onglets inactifs pour améliorer votre expérience de navigation et garantir un fonctionnement rapide.</translation>
 <translation id="5003967926796347400">Cliquez sur « Gestionnaire de mots de passe Google »</translation>
 <translation id="5120334927898581447">Vous connecter à Chrome lorsque vous vous connectez à d'autres services Google</translation>
 <translation id="5126049312684316860">Chrome précharge encore plus de pages que vous êtes susceptible de visiter, afin qu'elles se chargent plus rapidement lorsque vous le faites.</translation>
@@ -349,6 +351,7 @@
 <translation id="608006075545470555">Ajouter le profil professionnel à ce navigateur</translation>
 <translation id="6097822892606850415">Rédigez avec plus d'assurance grâce à l'IA</translation>
 <translation id="6113794647360055231">Google Chrome vient de s'améliorer</translation>
+<translation id="6135456723633883042">Ces onglets utilisent des ressources supplémentaires. Pour améliorer vos performances, laissez Chrome les rendre inactifs.</translation>
 <translation id="6145313976051292476">Ouvrir les PDF dans Chrome</translation>
 <translation id="6157638032135951407">Votre organisation supprime les données Chrome lorsqu'elles ne sont pas utilisées pour <ph name="TIMEOUT_DURATION" />. Cela peut inclure l'historique, le remplissage automatique et les téléchargements.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> — Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_hi.xtb b/chrome/app/resources/google_chrome_strings_hi.xtb
index 3e8b38d..a99d782f 100644
--- a/chrome/app/resources/google_chrome_strings_hi.xtb
+++ b/chrome/app/resources/google_chrome_strings_hi.xtb
@@ -251,6 +251,7 @@
 <translation id="4561051373932531560">Google Chrome आपको वेब पर फ़ोन नंबर क्लिक करने और उसके ज़रिए Skype से कॉल करने की सुविधा देता है!</translation>
 <translation id="4567424176335768812">आपने <ph name="USER_EMAIL_ADDRESS" /> के रूप में साइन इन किया हुआ है. अब आप अपने सभी साइन इन किए हुए डिवाइस पर अपने बुकमार्क, इतिहास, और दूसरी सेटिंग को एक्सेस कर सकते हैं.</translation>
 <translation id="4571503333518166079">Chrome की सूचना सेटिंग पर जाएं</translation>
+<translation id="4575717501879784448">Chrome आपके ब्राउज़िंग अनुभव को बेहतर बनाने और संसाधनों को कम करने के लिए, इन टैब को बंद कर सकता है.</translation>
 <translation id="459622048091363950">Chrome को ऐक्सेस मिलने के बाद, वेबसाइटें आपसे ऐक्सेस मांग सकेंगी.</translation>
 <translation id="4600710005438004015">Chrome सबसे नए वर्शन में अपडेट नहीं कर सका, इसलिए आपको नई सुविधाएं और सुरक्षा सुधार नहीं मिल रहे हैं.</translation>
 <translation id="4624065194742029982">Chrome का गुप्त मोड</translation>
@@ -282,6 +283,7 @@
 <translation id="4970761609246024540">Chrome प्रोफ़ाइलों में आपका स्वागत है</translation>
 <translation id="4970880042055371251">ChromeOS वर्शन</translation>
 <translation id="4990567037958725628">Google Chrome कैनरी</translation>
+<translation id="4997044641749333913">Chrome आपके ब्राउज़िंग अनुभव को बेहतर बनाने और चीज़ों को आसान बनाए रखने के लिए, इन टैब को बंद कर सकता है.</translation>
 <translation id="5003967926796347400">“Google Password Manager” पर क्लिक करें</translation>
 <translation id="5120334927898581447">Google की अन्य सेवाओं में साइन इन करते समय, Chrome में साइन इन करें</translation>
 <translation id="5126049312684316860">Chrome ऐसे कई और पेजों को पहले से लोड करके रखता है जिन पर आपके जाने की संभावना होती है, ताकि जब आप उन पेजों पर जाएं, तो वे ज़्यादा तेज़ी से खुल जाएं</translation>
@@ -346,6 +348,7 @@
 <translation id="608006075545470555">इस ब्राउज़र में वर्क प्रोफ़ाइल जोड़ें</translation>
 <translation id="6097822892606850415">एआई की मदद से पूरे आत्मविश्वास के साथ लिखें</translation>
 <translation id="6113794647360055231">Chrome पहले से बेहतर हो गया है</translation>
+<translation id="6135456723633883042">ये टैब ज़्यादा संसाधनों का इस्तेमाल कर रहे हैं. परफ़ॉर्मेंस को बेहतर बनाने के लिए, Chrome को इन्हें बंद करने की अनुमति दें.</translation>
 <translation id="6145313976051292476">Chrome में पीडीएफ़ खोलें</translation>
 <translation id="6157638032135951407"><ph name="TIMEOUT_DURATION" /> तक Chrome का इस्तेमाल न करने पर, आपका संगठन इसका डेटा मिटा देता है. इसमें ब्राउज़िंग का इतिहास, ऑटोमैटिक भरी जाने वाली जानकारी, और डाउनलोड की गई फ़ाइलें शामिल हो सकती हैं.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_hy.xtb b/chrome/app/resources/google_chrome_strings_hy.xtb
index d85fb0a..b74111af 100644
--- a/chrome/app/resources/google_chrome_strings_hy.xtb
+++ b/chrome/app/resources/google_chrome_strings_hy.xtb
@@ -171,6 +171,7 @@
 <translation id="3261565993776444564">Անհատականացրեք ձեր դիտարկիչը նոր գույնով</translation>
 <translation id="3282568296779691940">Մուտք գործել Chrome</translation>
 <translation id="3286538390144397061">Վերագործարկել հիմա</translation>
+<translation id="3292333338048274092">Այնուհետև անհրաժեշտ կլինի վերագործարկել Chrome-ը։</translation>
 <translation id="3360895254066713204">Chrome Helper</translation>
 <translation id="3379938682270551431">{0,plural, =0{Chrome-ը հիմա կվերագործարկվի}=1{Chrome-ը կվերագործարկվի 1 վայրկյանից}one{Chrome-ը կվերագործարկվի # վայրկյանից}other{Chrome-ը կվերագործարկվի # վայրկյանից}}</translation>
 <translation id="3396977131400919238">Տեղադրման ժամանակ օպերացիոն համակարգի սխալ տեղի ունեցավ: Նորից ներբեռնեք Google Chrome-ը:</translation>
@@ -215,6 +216,7 @@
 <translation id="4035053306113201399">Թարմացումը կիրառելու համար հարկավոր է վերագործարկել ChromeOS-ը։</translation>
 <translation id="4050175100176540509">Վերջին տարբերակում առկա են անվտանգության կարևոր բարելավումներ և նոր գործառույթներ:</translation>
 <translation id="4053720452172726777">Հարմարեցնել և վերահսկել Google Chrome-ը</translation>
+<translation id="4084404300720192944">Ձեր պատուհանով կիսվելու համար Համակարգի կարգավորումներում թույլատրեք էկրանի տեսագրումը Chrome-ի համար։</translation>
 <translation id="4106587138345390261">Chrome-ն ուսումնասիրում է նոր գործառույթները, որոնք կայքերին թույլ են տալիս տրամադրել դիտարկման նույն հնարավորությունները՝ ձեր մասին ավելի քիչ տեղեկություններ օգտագործելով։</translation>
 <translation id="4110895483821904099">Կարգավորեք Chrome-ի ձեր նոր պրոֆիլը</translation>
 <translation id="4111566860456076004">Chrome-ը չի կարող ստուգել այս ընդլայնման ծագումը, ուստի այն կարող է վտանգավոր լինել։ Հեռացրեք ընդլայնումը Chrome-ից, որպեսզի այն այլևս չկարողանա տեսնել և փոփոխել ձեր տվյալները, այդ թվում՝ անձնական տեղեկությունները, ձեր այցելած կայքերում։</translation>
@@ -353,6 +355,7 @@
 <translation id="6173637689840186878"><ph name="PAGE_TITLE" /> – Google Chrome բետա</translation>
 <translation id="6182736845697986886">Չհաջողվեց տեղադրել հավելվածը թարմացումն իրականացնող սերվերի ներքին սխալի պատճառով։</translation>
 <translation id="6200139057479872438">Դուք վաղուց չեք այցելել կայք։ Chrome-ը հեռացրել է «<ph name="PERMISSION_1" />» և «<ph name="PERMISSION_2" />» թույլտվությունները։</translation>
+<translation id="621585339844629864">Ձեր էկրանով կիսվելու համար Համակարգի կարգավորումներում թույլատրեք էկրանի տեսագրումը Chrome-ի համար։</translation>
 <translation id="6235018212288296708">Թույլատրել Google Chrome-ում մուտքային հոսքի փոխանցումը mDNS հաղորդակարգով:</translation>
 <translation id="624230925347970731">Chrome-ը շուտով կփակվի</translation>
 <translation id="6247557882553405851">Google գաղտնաբառերի կառավարիչ</translation>
diff --git a/chrome/app/resources/google_chrome_strings_id.xtb b/chrome/app/resources/google_chrome_strings_id.xtb
index 8d574e0..2c721386 100644
--- a/chrome/app/resources/google_chrome_strings_id.xtb
+++ b/chrome/app/resources/google_chrome_strings_id.xtb
@@ -251,6 +251,7 @@
 <translation id="4561051373932531560">Google Chrome memungkinkan Anda mengklik nomor telepon pada web dan menghubunginya melalui Skype!</translation>
 <translation id="4567424176335768812">Anda login sebagai <ph name="USER_EMAIL_ADDRESS" />. Kini Anda dapat mengakses bookmark, histori, dan setelan lainnya pada seluruh perangkat yang Anda masuki.</translation>
 <translation id="4571503333518166079">Buka setelan notifikasi Chrome</translation>
+<translation id="4575717501879784448">Chrome dapat menonaktifkan tab ini untuk meningkatkan pengalaman penjelajahan dan mengosongkan resource.</translation>
 <translation id="459622048091363950">Setelah Chrome memiliki akses, situs dapat meminta akses dari Anda.</translation>
 <translation id="4600710005438004015">Chrome tidak dapat diupdate ke versi terbaru, sehingga Anda tidak mendapatkan perbaikan keamanan dan fitur baru.</translation>
 <translation id="4624065194742029982">Mode Samaran Chrome</translation>
@@ -282,6 +283,7 @@
 <translation id="4970761609246024540">Selamat datang di profil Chrome</translation>
 <translation id="4970880042055371251">Versi ChromeOS</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Chrome dapat menonaktifkan tab ini untuk meningkatkan pengalaman penjelajahan dan menjaga agar performanya tetap cepat.</translation>
 <translation id="5003967926796347400">Klik “Pengelola Sandi Google”</translation>
 <translation id="5120334927898581447">Login ke Chrome saat Anda login ke layanan Google lainnya</translation>
 <translation id="5126049312684316860">Chrome melakukan pramuat lebih banyak halaman yang mungkin akan Anda buka, agar halaman tersebut dimuat lebih cepat saat Anda membukanya</translation>
@@ -342,6 +344,7 @@
 <translation id="608006075545470555">Tambahkan Profil Kerja ke browser ini</translation>
 <translation id="6097822892606850415">Menulis dengan penuh percaya diri dengan bantuan AI</translation>
 <translation id="6113794647360055231">Chrome menjadi lebih baik</translation>
+<translation id="6135456723633883042">Tab ini menggunakan lebih banyak resource. Untuk meningkatkan performa Anda, izinkan Chrome menonaktifkannya.</translation>
 <translation id="6145313976051292476">Buka PDF di Chrome</translation>
 <translation id="6157638032135951407">Organisasi Anda akan menghapus data Chrome jika tidak digunakan selama <ph name="TIMEOUT_DURATION" />. Data ini dapat mencakup histori, isi otomatis, dan download.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_is.xtb b/chrome/app/resources/google_chrome_strings_is.xtb
index 40a6ad4..92a83be 100644
--- a/chrome/app/resources/google_chrome_strings_is.xtb
+++ b/chrome/app/resources/google_chrome_strings_is.xtb
@@ -254,6 +254,7 @@
 <translation id="4561051373932531560">Google Chrome gerir þér kleift að smella á símanúmer á vefnum og hringja í það í gegnum Skype!</translation>
 <translation id="4567424176335768812">Þú ert skráð(ur) inn sem <ph name="USER_EMAIL_ADDRESS" />. Nú hefur þú aðgang að bókamerkjunum þínum, vefferlinum þínum og öðrum stillingum í öllum tækjum sem þú ert skráð(ur) inn á.</translation>
 <translation id="4571503333518166079">Opna tilkynningastillingar Chrome</translation>
+<translation id="4575717501879784448">Chrome getur óvirkjað þessa flipa til að bæta upplifunina þína í vafranum og losa um gögn.</translation>
 <translation id="459622048091363950">Þegar Chrome hefur aðgang munu vefsvæði geta beðið þig um aðgang.</translation>
 <translation id="4600710005438004015">Ekki var hægt að uppfæra Chrome í nýjustu útgáfu og þú ferð því á mis við nýja eiginleika og öryggislagfæringar.</translation>
 <translation id="4624065194742029982">Huliðsstilling Chrome</translation>
@@ -285,6 +286,7 @@
 <translation id="4970761609246024540">Velkomin(n) í Chrome prófíla</translation>
 <translation id="4970880042055371251">Útgáfa ChromeOS</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Chrome getur óvirkjað þessa flipa til að bæta upplifunina þína í vafranum og halda hraða.</translation>
 <translation id="5003967926796347400">Smelltu á „Google-aðgangsorðastjórnun“</translation>
 <translation id="5120334927898581447">Skráðu þig inn í Chrome þegar þú skráir þig inn í aðrar Google-þjónustur</translation>
 <translation id="5126049312684316860">Chrome forhleður fleiri síðum sem er líklegt að þú munir skoða svo þær hlaðist fyrr þegar þú opnar þær</translation>
@@ -349,6 +351,7 @@
 <translation id="608006075545470555">Bæta vinnusniði við þennan vafra</translation>
 <translation id="6097822892606850415">Skrifaðu af meira öryggi með hjálp frá gervigreind</translation>
 <translation id="6113794647360055231">Chrome er nú enn betra</translation>
+<translation id="6135456723633883042">Þessir flipar nota aukagögn. Leyfðu Chrome að óvirkja þá til að bæta afköstin.</translation>
 <translation id="6145313976051292476">Opna PDF-skjöl í Chrome</translation>
 <translation id="6157638032135951407">Fyrirtækið þitt eyðir Chrome-gögnum þegar þau eru ekki notuð í <ph name="TIMEOUT_DURATION" />. Þetta getur falið í sér feril, sjálfvirka útfyllingu og niðurhal.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> – Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_iw.xtb b/chrome/app/resources/google_chrome_strings_iw.xtb
index 29e0b49..7aa2d75 100644
--- a/chrome/app/resources/google_chrome_strings_iw.xtb
+++ b/chrome/app/resources/google_chrome_strings_iw.xtb
@@ -51,6 +51,7 @@
 <translation id="1682634494516646069">‏Google Chrome אינו יכול לקרוא ולכתוב בספריית הנתונים שלו: <ph name="USER_DATA_DIRECTORY" /></translation>
 <translation id="1698376642261615901">‏Google Chrome הוא דפדפן אינטרנט המפעיל דפי אינטרנט ואפליקציות במהירות הבזק. זהו דפדפן מהיר, יציב וקל לשימוש. הגלישה באינטרנט בטוחה יותר הודות להגנה מפני תוכנות זדוניות ופישינג, המובנית ב-Google Chrome.</translation>
 <translation id="1713301662689114961">{0,plural, =1{‏Chrome יופעל מחדש בעוד שעה}one{‏Chrome יופעל מחדש בעוד # שעות}two{‏Chrome יופעל מחדש בעוד # שעות}other{‏Chrome יופעל מחדש בעוד # שעות}}</translation>
+<translation id="1722488837206509557">כך תהיה לך אפשרות לבחור מבין המכשירים הזמינים ולהציג בהם תוכן.</translation>
 <translation id="1734234790201236882">‏הסיסמה הזאת תישמר על ידי Chrome בחשבון Google. אין צורך לזכור אותה.</translation>
 <translation id="1786003790898721085">‏יש לוודא שנכנסת ל-Chrome ב-<ph name="TARGET_DEVICE_NAME" /> ולשלוח שוב.</translation>
 <translation id="1786044937610313874">‏קיצורי דרך ייפתחו ב-Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ja.xtb b/chrome/app/resources/google_chrome_strings_ja.xtb
index d7b4354e..da93862 100644
--- a/chrome/app/resources/google_chrome_strings_ja.xtb
+++ b/chrome/app/resources/google_chrome_strings_ja.xtb
@@ -250,6 +250,7 @@
 <translation id="4561051373932531560">Google Chrome では、ウェブサイト上の電話番号をクリックするだけで Skype で通話を発信できます。</translation>
 <translation id="4567424176335768812"><ph name="USER_EMAIL_ADDRESS" /> としてログインしています。ログインしているすべてのデバイスで、ブックマーク、履歴、その他の設定にアクセスできます。</translation>
 <translation id="4571503333518166079">Chrome の通知設定に移動</translation>
+<translation id="4575717501879784448">Chrome では、これらのタブを非アクティブにして、ブラウジング環境を改善し、リソースを解放できます。</translation>
 <translation id="459622048091363950">Chrome にアクセスを許可すると、ウェブサイトからアクセスをリクエストできるようになります。</translation>
 <translation id="4600710005438004015">Chrome を最新版に更新できませんでした。新しい機能とセキュリティ修正は適用されていません。</translation>
 <translation id="4624065194742029982">Chrome のシークレット モード</translation>
@@ -281,6 +282,7 @@
 <translation id="4970761609246024540">Chrome プロフィールへようこそ</translation>
 <translation id="4970880042055371251">Chrome OS のバージョン</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Chrome では、これらのタブを非アクティブにして、ブラウジング環境を改善し、処理を高速に保つことができます。</translation>
 <translation id="5003967926796347400">[Google パスワード マネージャー] をクリックします</translation>
 <translation id="5120334927898581447">他の Google サービスにログインしたときに Chrome にログインする</translation>
 <translation id="5126049312684316860">アクセスする可能性の高いページがさらに多くプリロードされ、該当のページにアクセスしたときにページの読み込み速度が向上します</translation>
@@ -341,6 +343,7 @@
 <translation id="608006075545470555">このブラウザに仕事用プロファイルを追加</translation>
 <translation id="6097822892606850415">AI のサポートで文書を作成できます</translation>
 <translation id="6113794647360055231">進化する Chrome</translation>
+<translation id="6135456723633883042">これらのタブでは追加のリソースが使用されています。パフォーマンスを改善するには、Chrome でこれらのタブを非アクティブにしてください。</translation>
 <translation id="6145313976051292476">Chrome で PDF を開く</translation>
 <translation id="6157638032135951407"><ph name="TIMEOUT_DURATION" /> 使用しなかったため、Chrome のデータは組織によって削除されます。これには、履歴、自動入力、ダウンロードが含まれます。</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ko.xtb b/chrome/app/resources/google_chrome_strings_ko.xtb
index 39d2b88..7468cd3 100644
--- a/chrome/app/resources/google_chrome_strings_ko.xtb
+++ b/chrome/app/resources/google_chrome_strings_ko.xtb
@@ -255,6 +255,7 @@
 <translation id="4561051373932531560">Chrome을 사용하면 웹에서 전화번호를 클릭하여 Skype로 통화할 수 있습니다.</translation>
 <translation id="4567424176335768812"><ph name="USER_EMAIL_ADDRESS" />(으)로 로그인되어 있습니다. 이제 로그인한 모든 기기에서 북마크, 방문 기록 및 기타 설정에 액세스할 수 있습니다.</translation>
 <translation id="4571503333518166079">Chrome 알림 설정으로 이동</translation>
+<translation id="4575717501879784448">Chrome은 이러한 탭을 비활성화하여 탐색 환경을 개선하고 리소스를 확보할 수 있습니다.</translation>
 <translation id="459622048091363950">Chrome에 액세스 권한을 부여하면 웹사이트에서 액세스 권한을 요청할 수 있게 됩니다.</translation>
 <translation id="4600710005438004015">Chrome을 최신 버전으로 업데이트하지 못했기 때문에 새로운 기능과 보안 수정 사항이 적용되지 않았습니다.</translation>
 <translation id="4624065194742029982">Chrome 시크릿 모드</translation>
@@ -286,6 +287,7 @@
 <translation id="4970761609246024540">Chrome 프로필에 오신 것을 환영합니다</translation>
 <translation id="4970880042055371251">ChromeOS 버전</translation>
 <translation id="4990567037958725628">Chrome Canary</translation>
+<translation id="4997044641749333913">Chrome은 이러한 탭을 비활성화하여 탐색 환경을 개선하고 빠른 속도를 유지할 수 있습니다.</translation>
 <translation id="5003967926796347400">'Google 비밀번호 관리자'를 클릭합니다</translation>
 <translation id="5120334927898581447">다른 Google 서비스에 로그인할 때 Chrome에 로그인</translation>
 <translation id="5126049312684316860">Chrome은 사용자가 방문할 가능성이 높은 페이지를 미리 로드하여 사용자가 방문할 때 페이지가 더 빠르게 로드됩니다.</translation>
@@ -350,6 +352,7 @@
 <translation id="608006075545470555">이 브라우저에 직장 프로필 추가</translation>
 <translation id="6097822892606850415">AI의 도움으로 더욱 자신 있게 글을 작성하세요.</translation>
 <translation id="6113794647360055231">더욱 업그레이드된 Chrome</translation>
+<translation id="6135456723633883042">이러한 탭은 추가 리소스를 사용하고 있습니다. 성능을 개선하려면 Chrome에서 이러한 탭을 비활성화하도록 허용하세요.</translation>
 <translation id="6145313976051292476">Chrome에서 PDF 열기</translation>
 <translation id="6157638032135951407"><ph name="TIMEOUT_DURATION" /> 동안 사용하지 않으면 조직에서 Chrome 데이터를 삭제합니다. 여기에는 방문 기록, 자동 완성, 다운로드가 포함될 수 있습니다.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_lo.xtb b/chrome/app/resources/google_chrome_strings_lo.xtb
index 7d1801c..664586b 100644
--- a/chrome/app/resources/google_chrome_strings_lo.xtb
+++ b/chrome/app/resources/google_chrome_strings_lo.xtb
@@ -255,6 +255,7 @@
 <translation id="4561051373932531560">Google Chrome ໃຫ້ທ່ານຄລິກໃສ່ເບີໂທລະສັບຢູ່ໃນເວັບ ແລະໂທມັນດ້ວຍ Skype!</translation>
 <translation id="4567424176335768812">ທ່ານລົງຊື່ເຂົ້າ​ໃຊ້ເປັນ <ph name="USER_EMAIL_ADDRESS" />. ດຽວນີ້ທ່ານສາມາດເຂົ້າຫາບຸກມາກສ໌, ປະຫວັດ, ແລະການຕັ້ງຄ່າອື່ນຢູ່ໃນທຸກອຸປະກອນທີ່ລົງຊື່ເຂົ້າ​ໃຊ້ຂອງທ່ານ.</translation>
 <translation id="4571503333518166079">ໄປຫາການຕັ້ງຄ່າການແຈ້ງເຕືອນຂອງ Chrome</translation>
+<translation id="4575717501879784448">Chrome ສາມາດເຮັດໃຫ້ແຖບເຫຼົ່ານີ້ບໍ່ເຮັດວຽກເພື່ອປັບປຸງປະສົບການໃນການເລືອກເບິ່ງຂອງທ່ານ ແລະ ຊ່ວຍປະຢັດຊັບພະຍາກອນ.</translation>
 <translation id="459622048091363950">ເມື່ອ Chrome ມີການເຂົ້າເຖິງ, ເວັບໄຊຈະສາມາດຮ້ອງຂໍການເຂົ້າເຖິງນຳທ່ານ.</translation>
 <translation id="4600710005438004015">Chrome ບໍ່ສາມາດອັບເດດເປັນເວີຊັນຫຼ້າສຸດໄດ້, ສະນັ້ນທ່ານກຳລັງພາດຄຸນສົມບັດ ແລະ ການແກ້ໄຂດ້ານຄວາມປອດໄພໃໝ່ໆຢູ່.</translation>
 <translation id="4624065194742029982">ໂໝດບໍ່ເປີດເຜີຍຕົວຕົນໃນ Chrome</translation>
@@ -286,6 +287,7 @@
 <translation id="4970761609246024540">ຍິນດີຕ້ອນຮັບສູ່ໂປຣໄຟລ໌ Chrome</translation>
 <translation id="4970880042055371251">ເວີຊັນ ChromeOS</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Chrome ສາມາດເຮັດໃຫ້ແຖບເຫຼົ່ານີ້ບໍ່ເຮັດວຽກເພື່ອປັບປຸງປະສົບການໃນການເລືອກເບິ່ງຂອງທ່ານ ແລະ ເຮັດໃຫ້ສິ່ງຕ່າງໆເຮັດວຽກໄດ້ໄວຂຶ້ນ.</translation>
 <translation id="5003967926796347400">ຄລິກ “ຕົວຈັດການລະຫັດຜ່ານ Google”</translation>
 <translation id="5120334927898581447">ເຂົ້າສູ່ລະບົບ Chrome ເມື່ອທ່ານເຂົ້າສູ່ລະບົບບໍລິການອື່ນໆຂອງ Google</translation>
 <translation id="5126049312684316860">Chrome ໂຫຼດໜ້າເວັບໄວ້ກ່ອນລ່ວງໜ້າເພີ່ມຫຼາຍຂຶ້ນສຳລັບໜ້າທີ່ທ່ານອາດຈະເຂົ້າເບິ່ງ, ເພື່ອໃຫ້ພວກມັນໂຫຼດໄວຂຶ້ນເມື່ອທ່ານເຂົ້າເບິ່ງ</translation>
@@ -350,6 +352,7 @@
 <translation id="608006075545470555">ເພີ່ມໂປຣໄຟລ໌ບ່ອນເຮັດວຽກໃສ່ໂປຣແກຣມທ່ອງເວັບນີ້</translation>
 <translation id="6097822892606850415">ຂຽນຢ່າງໝັ້ນໃຈຫຼາຍຂຶ້ນດ້ວຍຄວາມຊ່ວຍເຫຼືອຈາກ AI</translation>
 <translation id="6113794647360055231">Chrome ​ດີກ​ວ່າແລ້ວ</translation>
+<translation id="6135456723633883042">ແຖບເຫຼົ່ານີ້ໃຊ້ຊັບພະຍາກອນຫຼາຍເປັນພິເສດ. ເພື່ອປັບປຸງປະສິດທິພາບຂອງທ່ານ, ກະລຸນາໃຫ້ Chrome ຊ່ວຍປິດນຳໃຊ້ແຖບເຫຼົ່ານີ້.</translation>
 <translation id="6145313976051292476">ເປີດ PDF ໃນ Chrome</translation>
 <translation id="6157638032135951407">ອົງກອນຂອງທ່ານລຶບຂໍ້ມູນຂອງ Chrome ອອກເມື່ອມັນບໍ່ໄດ້ຖືກນຳໃຊ້ເປັນເວລາ <ph name="TIMEOUT_DURATION" />. ເຊິ່ງຮວມເຖິງປະຫວັດ, ການຕື່ມຂໍ້ມູນອັດຕະໂນມັດ ແລະ ການດາວໂຫຼດ.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_mn.xtb b/chrome/app/resources/google_chrome_strings_mn.xtb
index d4fe8ae..ac79476f 100644
--- a/chrome/app/resources/google_chrome_strings_mn.xtb
+++ b/chrome/app/resources/google_chrome_strings_mn.xtb
@@ -255,6 +255,7 @@
 <translation id="4561051373932531560">Google Chrome нь танд веб дээр утасны дугаараа хийж Skype-аар дуудлага хийх боломжийг олгоно.</translation>
 <translation id="4567424176335768812">Та <ph name="USER_EMAIL_ADDRESS" /> ингэж нэвтэрсэн байна. Одоо та өөрийн нэвтэрсэн бүх төхөөрөмжүүд дээрээ хайлтын жагсаалт, түүх болон бусад тохиргоонууд руугаа нэвтэрч болно.</translation>
 <translation id="4571503333518166079">Chrome-н мэдэгдлийн тохиргоо хэсэгт очих</translation>
+<translation id="4575717501879784448">Chrome таны үзэх хэрэглээг сайжруулж, нөөцүүдийг чөлөөлөхийн тулд эдгээр табыг идэвхгүй болгох боломжтой.</translation>
 <translation id="459622048091363950">Chrome-д хандалт олгосны дараа веб сайтууд таны хандалтыг асуух боломжтой болно.</translation>
 <translation id="4600710005438004015">Chrome-г хамгийн сүүлийн хувилбарт шинэчлээгүй тул та шинэ онцлог болон аюулгүй байдлын засвар авах боломжгүй байна.</translation>
 <translation id="4624065194742029982">Chrome-н нууцлалын горим</translation>
@@ -286,6 +287,7 @@
 <translation id="4970761609246024540">Chrome профайлд тавтай морилно уу</translation>
 <translation id="4970880042055371251">ChromeOS-н хувилбар</translation>
 <translation id="4990567037958725628">Google Chrome цайвар шаргал өнгө</translation>
+<translation id="4997044641749333913">Chrome таны үзэх хэрэглээг сайжруулж, зүйлсийг хурдан байлгахын тулд эдгээр табыг идэвхгүй болгох боломжтой.</translation>
 <translation id="5003967926796347400">“Google Password Manager”-г товшино уу</translation>
 <translation id="5120334927898581447">Та Google-н бусад үйлчилгээнд нэвтрэх үедээ Chrome-д нэвтэрнэ үү</translation>
 <translation id="5126049312684316860">Chrome таны зочлох магадлалтай илүү олон хуудсыг урьдчилан ачаалах бөгөөд ингэснээр тэдгээр нь таныг зочлох үед илүү хурдан ачаална</translation>
@@ -350,6 +352,7 @@
 <translation id="608006075545470555">Энэ хөтчид ажлын профайл нэмэх</translation>
 <translation id="6097822892606850415">ХОУ-ы тусламжтайгаар илүү итгэлтэй бичээрэй</translation>
 <translation id="6113794647360055231">Chrome илүү сайн боллоо</translation>
+<translation id="6135456723633883042">Эдгээр таб нэмэлт нөөцүүдийг ашиглаж байна. Гүйцэтгэлээ сайжруулахын тулд Chrome-д тэдгээр табыг идэвхгүй болгохыг зөвшөөрнө үү.</translation>
 <translation id="6145313976051292476">PDF-г Chrome-д нээх</translation>
 <translation id="6157638032135951407">Танай байгууллага Chrome-г <ph name="TIMEOUT_DURATION" />-н турш ашиглаагүй үед өгөгдлийг нь устгадаг. Үүнд түүх, автоматаар бөглөх хэсэг болон татаж авсан файлууд багтаж болно.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_mr.xtb b/chrome/app/resources/google_chrome_strings_mr.xtb
index 2645a5e4..4a7ee8b2 100644
--- a/chrome/app/resources/google_chrome_strings_mr.xtb
+++ b/chrome/app/resources/google_chrome_strings_mr.xtb
@@ -173,6 +173,7 @@
 <translation id="3261565993776444564">तुमचा ब्राउझर कस्टमाइझ करण्यासाठी नवीन रंग वापरून पहा</translation>
 <translation id="3282568296779691940">Chrome वर साइन इन करा</translation>
 <translation id="3286538390144397061">त्वरित रीस्टार्ट करा</translation>
+<translation id="3292333338048274092">तुम्हाला त्यानंतर Chrome रीस्टार्ट करावे लागले.</translation>
 <translation id="3360895254066713204">Chrome मदतनीस</translation>
 <translation id="3379938682270551431">{0,plural, =0{Chrome आता पुन्हा लॉंच होईल}=1{Chrome एका सेकंदामध्ये पुन्हा लॉंच होईल}other{Chrome # सेकंदांमध्ये पुन्हा लॉंच होईल}}</translation>
 <translation id="3396977131400919238">स्थापनेदरम्यान एक ऑपरेटिंग सिस्टम‍ एरर आली. कृपया Google Chrome पुन्हा डाउनलोड करा.</translation>
@@ -217,6 +218,7 @@
 <translation id="4035053306113201399">अपडेट लागू करण्यासाठी ChromeOS रीस्टार्ट करणे आवश्यक आहे.</translation>
 <translation id="4050175100176540509">नवीनतम आवृत्तीमध्‍ये महत्त्वाच्या सुरक्षितता सुधारणा आणि नवीन वैशिष्ट्ये उपलब्‍ध आहेत.</translation>
 <translation id="4053720452172726777">Google Chrome कस्टमाइझ करा आणि नियंत्रित करा</translation>
+<translation id="4084404300720192944">तुमची विंडो शेअर करण्यासाठी, सिस्टीम प्राधान्ये यांमध्ये Chrome साठी स्क्रीन रेकॉर्डिंगला अनुमती द्या.</translation>
 <translation id="4106587138345390261">Chrome नवीन वैशिष्‍ट्ये एक्सप्लोर करत आहे, ज्यामुळे साइटना तुमची कमी माहिती वापरून समान ब्राउझिंग अनुभव देता येतो</translation>
 <translation id="4110895483821904099">तुमची नवीन Chrome प्रोफाइल सेट करा</translation>
 <translation id="4111566860456076004">हे एक्स्टेंशन कुठून आले आणि ते सुरक्षित आहे का याची Chrome ला पडताळणी करता आली नाही. ते Chrome वरून काढून टाका, जेणेकरून ते वैयक्तिक माहितीच्या समावेशासह तुम्ही भेट देत असलेल्या साइटवरील तुमचा डेटा आता पाहू आणि बदलू शकणार नाही.</translation>
@@ -254,6 +256,7 @@
 <translation id="4561051373932531560">Google Chrome तुम्हाला वेबवरील फोन नंबर क्लिक करू देते आणि त्या नंबरवर Skype द्वारा कॉल करू देते!</translation>
 <translation id="4567424176335768812">तुम्ही <ph name="USER_EMAIL_ADDRESS" /> म्हणून साइन इन केले आहे. आता तुम्ही तुमच्या सर्व साइन इन केलेल्या डिव्हाइसवरील तुमच्या बुकमार्क, इतिहास आणि अन्य सेटिंग्ज ॲक्सेस करू शकता.</translation>
 <translation id="4571503333518166079">Chrome सूचना सेटिंग्जवर जा</translation>
+<translation id="4575717501879784448">तुमच्या ब्राउझिंग अनुभवामध्ये सुधारणा करण्यासाठी आणि स्रोत रिक्त करण्यासाठी Chrome हे टॅब इनॅक्टिव्ह करू शकते.</translation>
 <translation id="459622048091363950">एकदा का Chrome ला ॲक्सेस मिळाला की, वेबसाइट तुम्हाला ॲक्सेससाठी विचारतील.</translation>
 <translation id="4600710005438004015">Chrome नवीनतम आवृत्तीवर अपडेट होऊ शकले नाही, त्यामुळे तुम्ही नवीन वैशिष्ट्ये आणि सुरक्षितता निराकरणे गमावत आहात.</translation>
 <translation id="4624065194742029982">Chrome चा गुप्त मोड</translation>
@@ -285,6 +288,7 @@
 <translation id="4970761609246024540">Chrome प्रोफाइलमध्ये स्वागत आहे</translation>
 <translation id="4970880042055371251">ChromeOS ची आवृत्ती</translation>
 <translation id="4990567037958725628">Google Chrome कॅनरी</translation>
+<translation id="4997044641749333913">तुमच्या ब्राउझिंग अनुभवामध्ये सुधारणा करण्यासाठी आणि जलद काम करण्यासाठी Chrome हे टॅब इनॅक्टिव्ह करू शकते.</translation>
 <translation id="5003967926796347400">“Google Password Manager” वर क्लिक करा</translation>
 <translation id="5120334927898581447">तुम्ही इतर Google सेवांमध्ये साइन इन करता, तेव्हा Chrome मध्ये साइन इन करा</translation>
 <translation id="5126049312684316860">Chrome तुम्ही भेट देण्याची शक्यता असलेली आणखी पेज प्रीलोड करते, जेणेकरून तुम्ही त्यांना भेट देता, तेव्हा ती अधिक जलद लोड होतात</translation>
@@ -348,12 +352,14 @@
 <translation id="608006075545470555">या ब्राउझरवर कार्य प्रोफाइल जोडा</translation>
 <translation id="6097822892606850415">AI ची मदत घेऊन अधिक आत्मविश्वासाने लिहा</translation>
 <translation id="6113794647360055231">Chrome आता उत्कृष्ट झाले आहे</translation>
+<translation id="6135456723633883042">हे टॅब अतिरिक्त स्रोत वापरत आहेत. तुमच्या परफॉर्मन्समध्ये सुधारणा करण्यासाठी, Chrome ला ते इनॅक्टिव्ह करू द्या.</translation>
 <translation id="6145313976051292476">Chrome मध्ये PDF उघडा</translation>
 <translation id="6157638032135951407"><ph name="TIMEOUT_DURATION" /> कालावधीसाठी Chrome डेटा वापरला जात नाही, तेव्हा तुमची संस्था तो हटवते. यात इतिहास, ऑटोफिल आणि डाउनलोड यांचा समावेश असू शकतो.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> – Google Chrome</translation>
 <translation id="6173637689840186878"><ph name="PAGE_TITLE" /> - Google Chrome बीटा</translation>
 <translation id="6182736845697986886">अपडेट सर्व्हरच्या अंतर्गत एररमुळे इंस्टॉलेशन यशस्वी झाले नाही.</translation>
 <translation id="6200139057479872438">तुम्ही अलीकडे भेट दिलेली नाही. Chrome ने <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> परवानग्या काढून टाकल्या</translation>
+<translation id="621585339844629864">तुमची स्क्रीन शेअर करण्यासाठी, सिस्टीम प्राधान्ये यांमध्ये Chrome साठी स्क्रीन रेकॉर्डिंगला अनुमती द्या.</translation>
 <translation id="6235018212288296708">mDNS रहदारीस अनुमती देण्यासाठी Google Chrome साठी अंतर्गामी नियम.</translation>
 <translation id="624230925347970731">Chrome लवकरच बंद होईल</translation>
 <translation id="6247557882553405851">Google Password Manager</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ms.xtb b/chrome/app/resources/google_chrome_strings_ms.xtb
index 5839e626..cc72520 100644
--- a/chrome/app/resources/google_chrome_strings_ms.xtb
+++ b/chrome/app/resources/google_chrome_strings_ms.xtb
@@ -170,6 +170,7 @@
 <translation id="3261565993776444564">Cuba warna baharu untuk menyesuaikan penyemak imbas anda</translation>
 <translation id="3282568296779691940">Log masuk ke Chrome</translation>
 <translation id="3286538390144397061">Mulakan Semula Sekarang</translation>
+<translation id="3292333338048274092">Kemudian, anda perlu memulakan semula Chrome.</translation>
 <translation id="3360895254066713204">Chrome Helper</translation>
 <translation id="3379938682270551431">{0,plural, =0{Chrome akan dilancarkan semula sekarang}=1{Chrome akan dilancarkan semula dalam masa sesaat}other{Chrome akan dilancarkan semula dalam masa # saat}}</translation>
 <translation id="3396977131400919238">Ralat sistem pengendalian berlaku semasa pemasangan. Sila muat turun Google Chrome semula.</translation>
@@ -214,6 +215,7 @@
 <translation id="4035053306113201399">Chrome OS perlu dimulakan semula untuk melaksanakan kemaskinian.</translation>
 <translation id="4050175100176540509">Peningkatan keselamatan penting dan ciri baharu tersedia dalam versi terkini.</translation>
 <translation id="4053720452172726777">Sesuaikan dan kawal Google Chrome</translation>
+<translation id="4084404300720192944">Untuk berkongsi tetingkap anda, benarkan rakaman skrin untuk Chrome dalam Pilihan Sistem.</translation>
 <translation id="4106587138345390261">Chrome sedang meneroka ciri baharu yang membolehkan laman menyampaikan pengalaman penyemakan imbas yang sama menggunakan kurang maklumat anda</translation>
 <translation id="4110895483821904099">Sediakan profil Chrome baharu anda</translation>
 <translation id="4111566860456076004">Chrome tidak dapat mengesahkan tempat asal sambungan ini, maka tindakan ini mungkin tidak selamat. Alih keluar sambungan ini daripada Chrome supaya sambungan ini tidak dapat melihat dan mengubah data anda pada laman yang anda lawati lagi, termasuk maklumat peribadi.</translation>
@@ -351,6 +353,7 @@
 <translation id="6173637689840186878"><ph name="PAGE_TITLE" /> - Google Chrome Beta</translation>
 <translation id="6182736845697986886">Pemasangan gagal akibat ralat dalaman pelayan kemaskinian.</translation>
 <translation id="6200139057479872438">Anda belum melawati laman web ini baru-baru ini. Chrome mengalih keluar <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /></translation>
+<translation id="621585339844629864">Untuk berkongsi skrin anda, benarkan rakaman skrin untuk Chrome dalam Pilihan Sistem.</translation>
 <translation id="6235018212288296708">Peraturan masuk bagi Google Chrome untuk membenarkan trafik mDNS.</translation>
 <translation id="624230925347970731">Chrome akan ditutup sebentar lagi</translation>
 <translation id="6247557882553405851">Google Password Manager</translation>
diff --git a/chrome/app/resources/google_chrome_strings_my.xtb b/chrome/app/resources/google_chrome_strings_my.xtb
index 9840fc88..bbc6e9a 100644
--- a/chrome/app/resources/google_chrome_strings_my.xtb
+++ b/chrome/app/resources/google_chrome_strings_my.xtb
@@ -255,6 +255,7 @@
 <translation id="4561051373932531560">Google Chrome က ဝဘ် ပေါ်က ဖုန်း နံပါတ်ကို ကလစ်လျက် ၎င်းကို Skype ဖြင့် ခေါ်ဆိုပေးနိုင်သည်!</translation>
 <translation id="4567424176335768812">သင်သည် <ph name="USER_EMAIL_ADDRESS" /> အဖြစ် လက်မှတ်ထိုး ဝင်ထားသည်။ သင်သည် ယခုတော့ သင် လက်မှတ်ထိုး ဝင်ထားသည့် ကိရိယာ အားလုံးတို့မှာ သင်၏ စာညှပ်များ၊ မှတ်တမ်း၊ နှင့် အခြား ဆက်တင်များကို ရယူသုံးနိုင်ပါပြီ။</translation>
 <translation id="4571503333518166079">Chrome အကြောင်းကြားချက် ဆက်တင်များသို့ သွားရန်</translation>
+<translation id="4575717501879784448">သင်၏ဘရောက်စ်လုပ်ခြင်း ပိုကောင်းစေရန်နှင့် ရင်းမြစ်များတွင် နေရာလွတ် ပြုလုပ်ရန် Chrome က ဤတဘ်များကို ပိတ်စေနိုင်သည်။</translation>
 <translation id="459622048091363950">Chrome အသုံးပြုခွင့်ရှိသည်နှင့် ဝဘ်ဆိုက်များသည် သင့်ထံခွင့်ပြုချက်တောင်းပါမည်။</translation>
 <translation id="4600710005438004015">Chrome ကို နောက်ဆုံးဗားရှင်းသို့ အပ်ဒိတ်လုပ်၍မရသောကြောင့် ဝန်ဆောင်မှုအသစ်များနှင့် လုံခြုံရေး ပြင်ဆင်မွမ်းမံချက်များကို သင်ရရှိမည် မဟုတ်ပါ။</translation>
 <translation id="4624065194742029982">Chrome ရုပ်ဖျက်မုဒ်</translation>
@@ -286,6 +287,7 @@
 <translation id="4970761609246024540">Chrome ပရိုဖိုင်များမှ ကြိုဆိုပါသည်</translation>
 <translation id="4970880042055371251">ChromeOS ဗားရှင်း</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">သင်၏ဘရောက်စ်လုပ်ခြင်း ပိုကောင်းစေရန်နှင့် အရာရာကို မြန်ဆန်စေရန် Chrome က ဤတဘ်များကို ပိတ်စေနိုင်သည်။</translation>
 <translation id="5003967926796347400">“Google Password Manager” ကို နှိပ်ပါ</translation>
 <translation id="5120334927898581447">အခြား Google ဝန်ဆောင်မှုများသို့ လက်မှတ်ထိုးဝင်သောအခါ Chrome သို့ လက်မှတ်ထိုးဝင်ပါ</translation>
 <translation id="5126049312684316860">သင်ဝင်ကြည့်နိုင်ဖွယ်ရှိသည့် စာမျက်နှာများသို့ ဝင်ကြည့်သောအခါ ပိုမိုလျင်မြန်စွာ ပွင့်စေရန် Chrome သည် စာမျက်နှာတစ်ခုထက်ပို၍ ကြိုဖွင့်သည်</translation>
@@ -350,6 +352,7 @@
 <translation id="608006075545470555">ဤဘရောင်ဇာတွင် အလုပ်ပရိုဖိုင်ထည့်ခြင်း</translation>
 <translation id="6097822892606850415">AI အကူအညီဖြင့် ပိုမိုယုံကြည်မှုရှိစွာ ရေးသားပါ</translation>
 <translation id="6113794647360055231">Chrome သည် ပိုလို့ကို ကောင်းလာပါပြီ</translation>
+<translation id="6135456723633883042">ဤတဘ်များသည် အပိုဆောင်းရင်းမြစ်များကို သုံးနေသည်။ သင့်စွမ်းဆောင်ရည် ပိုကောင်းစေရန် ၎င်းတို့ကို Chrome အား ပိတ်ခွင့်ပြုပါ။</translation>
 <translation id="6145313976051292476">Chrome တွင် PDF များ ဖွင့်ရန်</translation>
 <translation id="6157638032135951407">Chrome ဒေတာကို <ph name="TIMEOUT_DURATION" /> ကြာ အသုံးမပြုဘဲထားပါက သင့်အဖွဲ့အစည်းသည် ၎င်းကို ဖျက်ပါသည်။ ၎င်းတွင် မှတ်တမ်း၊ အော်တိုဖြည့်နှင့် ဒေါင်းလုဒ်များ ပါဝင်နိုင်သည်။</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ne.xtb b/chrome/app/resources/google_chrome_strings_ne.xtb
index 1332163..f05b275 100644
--- a/chrome/app/resources/google_chrome_strings_ne.xtb
+++ b/chrome/app/resources/google_chrome_strings_ne.xtb
@@ -255,6 +255,7 @@
 <translation id="4561051373932531560">Google Chrome ले तपाइँलाई वेबमा एउटा फोन नम्बरमा क्लिक गर्न दिन्छ र Skype बाट त्यसलाई कल गर्न दिन्छ!</translation>
 <translation id="4567424176335768812">तपाइँ <ph name="USER_EMAIL_ADDRESS" /> को रूपमा साइन इन हुनुभएको छ। अब तपाइँले तपाइँका सबै साइन इन भएका यन्त्रहरूमा तपाइँका पृष्ठमञ्जूषाहरू, इतिहास, र अन्य सेटिङहरू पहुँच गर्न सक्नुहुन्छ।</translation>
 <translation id="4571503333518166079">Chrome को सूचनासम्बन्धी सेटिङहरूमा जानुहोस्</translation>
+<translation id="4575717501879784448">तपाईंलाई अझ राम्रो ब्राउजिङ सुविधा प्रदान गर्न र स्रोतहरू खाली पार्न Chrome ले यी ट्याब निष्क्रिय बनाउन सक्छ।</translation>
 <translation id="459622048091363950">Chrome ले पहुँच प्राप्त गरेपछि, वेबसाइटहरू तपाईंसँग पहुँच माग्न सक्ने छन्।</translation>
 <translation id="4600710005438004015">Chrome लाई नवीनतम संस्करणमा अद्यावधिक गर्न सकिएन, जसका कारण तपाईं नयाँ सुविधाहरू तथा सुरक्षासम्बन्धी समाधानहरू चलाउनबाट वञ्चित भइराख्नुभएको छ।</translation>
 <translation id="4624065194742029982">Chrome को इन्कोग्निटो मोड</translation>
@@ -286,6 +287,7 @@
 <translation id="4970761609246024540">Chrome का प्रोफाइलमा तपाईंलाई स्वागत छ</translation>
 <translation id="4970880042055371251">ChromeOS को संस्करण</translation>
 <translation id="4990567037958725628">Google Chrome क्यानरी</translation>
+<translation id="4997044641749333913">तपाईंलाई अझ राम्रो ब्राउजिङ सुविधा प्रदान गर्न र साइटहरू छिटो खुल्ने बनाउन Chrome ले यी ट्याब निष्क्रिय बनाउन सक्छ।</translation>
 <translation id="5003967926796347400">“Google पासवर्ड म्यानेजर” मा क्लिक गर्नुहोस्</translation>
 <translation id="5120334927898581447">तपाईंले Google का अन्य सेवामा साइन इन गर्दा Chrome मा साइन इन गर्नुहोस्</translation>
 <translation id="5126049312684316860">Chrome ले तपाईंले खोल्न सक्ने अझ धेरै पेजहरू प्रिलोड गर्छ। तपाईंले ती पेज खोल्दा ती पेजहरू अझ छिटो लोड होऊन् भन्नाका लागि Chrome ले यसो गर्छ</translation>
@@ -348,6 +350,7 @@
 <translation id="608006075545470555">यो ब्राउजरमा कार्य प्रोफाइल हाल्नुहोस्</translation>
 <translation id="6097822892606850415">AI का सहायताले थप आत्मविश्वासका साथ लेख्नुहोस्</translation>
 <translation id="6113794647360055231">Chrome अझ राम्रो भएको छ</translation>
+<translation id="6135456723633883042">यी ट्याबले अतिरिक्त स्रोतहरू प्रयोग गरिरहेका छन्। पर्फर्मेन्स अझ राम्रो बनाउन Chrome लाई यी ट्याब निष्क्रिय बनाउन दिनुहोस्।</translation>
 <translation id="6145313976051292476">PDF फाइलहरू Chrome मा खोलियोस्</translation>
 <translation id="6157638032135951407">तपाईंको सङ्गठनले तोकेको नियमअनुसार तपाईंले <ph name="TIMEOUT_DURATION" /> सम्म Chrome प्रयोग गर्नुभएन भने त्यसको डेटा स्वतः मेटिने छ। यसअन्तर्गत हिस्ट्री, अटोफिल तथा डाउनलोड समावेश हुन सक्छन्।</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_nl.xtb b/chrome/app/resources/google_chrome_strings_nl.xtb
index bcca7ad..7324a65 100644
--- a/chrome/app/resources/google_chrome_strings_nl.xtb
+++ b/chrome/app/resources/google_chrome_strings_nl.xtb
@@ -173,6 +173,7 @@
 <translation id="3261565993776444564">Pas je browser aan met een nieuwe kleur</translation>
 <translation id="3282568296779691940">Inloggen bij Chrome</translation>
 <translation id="3286538390144397061">Nu herstarten</translation>
+<translation id="3292333338048274092">Start Chrome daarna opnieuw op.</translation>
 <translation id="3360895254066713204">Chrome Helper</translation>
 <translation id="3379938682270551431">{0,plural, =0{Chrome wordt nu opnieuw gestart}=1{Chrome wordt over één seconde opnieuw gestart}other{Chrome wordt over # seconden opnieuw gestart}}</translation>
 <translation id="3396977131400919238">Er is tijdens de installatie een probleem opgetreden met het besturingssysteem. Download Google Chrome opnieuw.</translation>
@@ -217,6 +218,7 @@
 <translation id="4035053306113201399">Chrome OS moet opnieuw worden gestart om de update uit te voeren.</translation>
 <translation id="4050175100176540509">Er zijn belangrijke beveiligingsverbeteringen en nieuwe functies beschikbaar in de nieuwste versie.</translation>
 <translation id="4053720452172726777">Google Chrome aanpassen en beheren</translation>
+<translation id="4084404300720192944">Als je je venster wilt delen, sta je schermopname voor Chrome toe in Systeemvoorkeuren.</translation>
 <translation id="4106587138345390261">Chrome bevat nieuwe experimentele functies waarmee sites dezelfde browsefunctionaliteit kunnen leveren terwijl er minder van je gegevens worden gebruikt</translation>
 <translation id="4110895483821904099">Je nieuwe Chrome-profiel instellen</translation>
 <translation id="4111566860456076004">Chrome kan niet verifiëren waar deze extensie vandaan komt en de extensie is misschien onveilig. Verwijder de extensie uit Chrome zodat deze je gegevens (waaronder je persoonlijke informatie) niet meer kan bekijken en wijzigen op sites die je bezoekt.</translation>
@@ -356,6 +358,7 @@
 <translation id="6173637689840186878"><ph name="PAGE_TITLE" /> - Google Chrome Bèta</translation>
 <translation id="6182736845697986886">De installatie is mislukt vanwege een interne fout met de updateserver.</translation>
 <translation id="6200139057479872438">Je bent hier niet recent geweest. Chrome heeft <ph name="PERMISSION_1" /> en <ph name="PERMISSION_2" /> verwijderd</translation>
+<translation id="621585339844629864">Als je je scherm wilt delen, sta je schermopname voor Chrome toe in Systeemvoorkeuren.</translation>
 <translation id="6235018212288296708">Inkomende regel zodat Google Chrome mDNS-verkeer toestaat.</translation>
 <translation id="624230925347970731">Chrome wordt zo meteen gesloten</translation>
 <translation id="6247557882553405851">Google Wachtwoordmanager</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ro.xtb b/chrome/app/resources/google_chrome_strings_ro.xtb
index 2afcd96..860964ee 100644
--- a/chrome/app/resources/google_chrome_strings_ro.xtb
+++ b/chrome/app/resources/google_chrome_strings_ro.xtb
@@ -250,6 +250,7 @@
 <translation id="4561051373932531560">Cu Google Chrome, poți să dai clic pe un număr de telefon de pe web pentru a-l apela cu Skype!</translation>
 <translation id="4567424176335768812">V-ați conectat ca <ph name="USER_EMAIL_ADDRESS" />. Acum vă puteți accesa marcajele, istoricul și alte setări de pe toate dispozitivele pe care v-ați conectat.</translation>
 <translation id="4571503333518166079">Accesează setările pentru notificări Chrome</translation>
+<translation id="4575717501879784448">Chrome poate dezactiva aceste file pentru a-ți îmbunătăți experiența de navigare și pentru a elibera resurse.</translation>
 <translation id="459622048091363950">Odată ce Chrome are acces, site-urile web îți vor putea solicita accesul.</translation>
 <translation id="4600710005438004015">Chrome nu s-a putut actualiza la cea mai recentă versiune. Astfel, pierzi noi funcții și remedieri de securitate.</translation>
 <translation id="4624065194742029982">Modul incognito din Chrome</translation>
@@ -281,6 +282,7 @@
 <translation id="4970761609246024540">Bun venit la profilurile Chrome</translation>
 <translation id="4970880042055371251">Versiunea sistemului de operare Chrome</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Chrome poate dezactiva aceste file pentru a-ți îmbunătăți experiența de navigare și pentru a menține viteza ridicată.</translation>
 <translation id="5003967926796347400">Dă clic pe Managerul de parole Google</translation>
 <translation id="5120334927898581447">Conectează-te la Chrome când te conectezi la alte servicii Google</translation>
 <translation id="5126049312684316860">Chrome preîncarcă și mai multe pagini pe care este posibil să le accesezi, astfel încât să se încarce mai rapid când le accesezi</translation>
@@ -341,6 +343,7 @@
 <translation id="608006075545470555">Adaugă un profil de serviciu în acest browser</translation>
 <translation id="6097822892606850415">Scrie cu mai multă încredere cu ajutorul AI</translation>
 <translation id="6113794647360055231">Chrome a devenit și mai bun</translation>
+<translation id="6135456723633883042">Aceste file folosesc resurse suplimentare. Pentru a-ți îmbunătăți performanța, permite-i browserului Chrome să le dezactiveze.</translation>
 <translation id="6145313976051292476">Deschide fișierele PDF în Chrome</translation>
 <translation id="6157638032135951407">Organizația ta șterge datele Chrome dacă nu sunt folosite timp de <ph name="TIMEOUT_DURATION" />. Aici pot fi incluse istoricul, completările automate și descărcările.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> – Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ru.xtb b/chrome/app/resources/google_chrome_strings_ru.xtb
index 098d1af..31c271c 100644
--- a/chrome/app/resources/google_chrome_strings_ru.xtb
+++ b/chrome/app/resources/google_chrome_strings_ru.xtb
@@ -250,6 +250,7 @@
 <translation id="4561051373932531560">В Google Chrome вы можете нажать на любой номер телефона и позвонить на него через Skype!</translation>
 <translation id="4567424176335768812">Вы вошли с помощью аккаунта <ph name="USER_EMAIL_ADDRESS" />. Ваши закладки, история и другие настройки теперь доступны на всех устройствах, где вы используете этот аккаунт.</translation>
 <translation id="4571503333518166079">Открыть настройки уведомлений Chrome</translation>
+<translation id="4575717501879784448">Чтобы повысить производительность браузера Chrome и удобство работы в нем, эти вкладки можно сделать неактивными.</translation>
 <translation id="459622048091363950">Когда вы предоставите доступ Chrome, веб-сайты также смогут запрашивать у вас доступ.</translation>
 <translation id="4600710005438004015">Не удалось установить последнюю версию Chrome, в которой добавлены новые функции и обновления системы безопасности.</translation>
 <translation id="4624065194742029982">Режим инкогнито в Chrome</translation>
@@ -281,6 +282,7 @@
 <translation id="4970761609246024540">Представляем профили Chrome</translation>
 <translation id="4970880042055371251">Версия Chrome OS</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Чтобы повысить скорость браузера Chrome и удобство работы в нем, эти вкладки можно сделать неактивными.</translation>
 <translation id="5003967926796347400">Выберите "Google Менеджер паролей".</translation>
 <translation id="5120334927898581447">Входить в Chrome при входе в другие сервисы Google</translation>
 <translation id="5126049312684316860">Chrome предварительно загружает ещё больше страниц, которые вы с большой вероятностью посетите, чтобы они открылись быстрее.</translation>
@@ -341,6 +343,7 @@
 <translation id="608006075545470555">Добавление рабочего профиля в браузер</translation>
 <translation id="6097822892606850415">Пишите тексты с помощью искусственного интеллекта.</translation>
 <translation id="6113794647360055231">Chrome становится все лучше</translation>
+<translation id="6135456723633883042">Чтобы поддерживать работу этих вкладок, используется оперативная память. Разрешите Chrome сделать их неактивными, и производительность повысится.</translation>
 <translation id="6145313976051292476">Открывать PDF-файлы в Chrome</translation>
 <translation id="6157638032135951407">Ваша организация удаляет данные Chrome, если они не используются в течение <ph name="TIMEOUT_DURATION" />. Они могут включать в себя историю, сведения для автозаполнения и скачанные файлы.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_sk.xtb b/chrome/app/resources/google_chrome_strings_sk.xtb
index be80aca..c7973553 100644
--- a/chrome/app/resources/google_chrome_strings_sk.xtb
+++ b/chrome/app/resources/google_chrome_strings_sk.xtb
@@ -253,6 +253,7 @@
 <translation id="4561051373932531560">Prehliadač Google Chrome vám umožňuje vybrať telefónne číslo na webe a zavolať naň pomocou aplikácie Skype.</translation>
 <translation id="4567424176335768812">Ste prihlásený/-á ako <ph name="USER_EMAIL_ADDRESS" />. Teraz môžete na všetkých zariadeniach, kde ste prihlásený/-á, pristupovať k svojim záložkám, histórii a ďalším nastaveniam.</translation>
 <translation id="4571503333518166079">Prejsť do nastavení upozornení Chromu</translation>
+<translation id="4575717501879784448">Chrome môže tieto karty deaktivovať, aby zlepšil prehliadanie a uvoľnil zdroje.</translation>
 <translation id="459622048091363950">Keď Chrome získa prístup, weby vás budú môcť žiadať o prístup.</translation>
 <translation id="4600710005438004015">Chrome sa nepodarilo aktualizovať na najnovšiu verziu. K dispozícii tak nie sú niektoré nové funkcie a bezpečnostné opravy.</translation>
 <translation id="4624065194742029982">Režim inkognito Chromu</translation>
@@ -284,6 +285,7 @@
 <translation id="4970761609246024540">Vitajte v profiloch Chromu</translation>
 <translation id="4970880042055371251">Verzia systému Chrome OS</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Chrome môže tieto karty deaktivovať, aby zlepšil prehliadanie a zachoval rýchlosť.</translation>
 <translation id="5003967926796347400">Kliknite na položku Správca hesiel Google</translation>
 <translation id="5120334927898581447">Prihláste sa do Chromu, keď sa prihlásite do ďalších služieb Googlu</translation>
 <translation id="5126049312684316860">Chrome prednačítava dokonca viac stránok, ako pravdepodobne navštívite, aby sa v prípade návštevy načítali rýchlejšie</translation>
@@ -348,6 +350,7 @@
 <translation id="608006075545470555">Pridanie pracovného profilu do tohto prehliadača</translation>
 <translation id="6097822892606850415">Píšte s väčšou istotou pomocou umelej inteligencie</translation>
 <translation id="6113794647360055231">Prehliadač Chrome bol práve vylepšený</translation>
+<translation id="6135456723633883042">Tieto karty spotrebúvajú dodatočné zdroje. Chrome ich môže deaktivovať, aby zlepšil výkon.</translation>
 <translation id="6145313976051292476">Otvoriť súbory PDF v Chrome</translation>
 <translation id="6157638032135951407">Ak sa údaje Chromu nebudú používať <ph name="TIMEOUT_DURATION" />, vaša organizácia ich odstráni. Môže to zahŕňať históriu, automatické dopĺňanie a stiahnuté súbory.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_sw.xtb b/chrome/app/resources/google_chrome_strings_sw.xtb
index 979063b..207034d 100644
--- a/chrome/app/resources/google_chrome_strings_sw.xtb
+++ b/chrome/app/resources/google_chrome_strings_sw.xtb
@@ -255,6 +255,7 @@
 <translation id="4561051373932531560">Google Chrome inakuwezesha kubofya namba ya simu kwenye wavuti na kuipigia simu kwa Skype!</translation>
 <translation id="4567424176335768812">Umeingia katika akaunti kama <ph name="USER_EMAIL_ADDRESS" />. Sasa unaweza kupata alamisho, historia, na mipangilio yako mingine kwenye vifaa vyako vyote vilivyoingia katika akaunti.</translation>
 <translation id="4571503333518166079">Nenda kwenye mipangilio ya arifa za Chrome</translation>
+<translation id="4575717501879784448">Chrome inaweza kufanya vichupo hivi visitumike ili kuboresha hali yako ya kuvinjari na kufuta data ili upate nyenzo.</translation>
 <translation id="459622048091363950">Chrome itakapopata idhini, tovuti zitaweza kukuomba idhini ya kufikia.</translation>
 <translation id="4600710005438004015">Imeshindwa kupata toleo jipya la Chrome, kwa hivyo hutapata masasisho ya usalama na vipengele vipya.</translation>
 <translation id="4624065194742029982">Hali fiche kwenye Chrome</translation>
@@ -286,6 +287,7 @@
 <translation id="4970761609246024540">Karibu kwenye kipengele cha wasifu kwenye Chrome</translation>
 <translation id="4970880042055371251">Toleo la Mfumo wa Uendeshaji wa Chrome</translation>
 <translation id="4990567037958725628">Kanari ya Google Chrome</translation>
+<translation id="4997044641749333913">Chrome inaweza kufanya vichupo hivi visitumike ili kuboresha hali yako ya kuvinjari na kutekeleza shughuli kwa haraka.</translation>
 <translation id="5003967926796347400">Bofya “Kidhibiti cha Manenosiri cha Google”</translation>
 <translation id="5120334927898581447">Ingia katika akaunti kwenye Chrome unapoingia kwenye akaunti za huduma nyingine za Google</translation>
 <translation id="5126049312684316860">Chrome hupakia mapema kurasa nyingi zaidi ambazo unaweza kutembelea, ili zipakie kwa haraka zaidi unapozitembelea</translation>
@@ -350,6 +352,7 @@
 <translation id="608006075545470555">Ongeza Wasifu wa Kazini kwenye kivinjari hiki</translation>
 <translation id="6097822892606850415">Andika kwa uhakika zaidi ukisaidiwa na AI</translation>
 <translation id="6113794647360055231">Chrome imeboreshwa zaidi</translation>
+<translation id="6135456723633883042">Vichupo hivi vinatumia nyenzo za ziada. Ruhusu Chrome ivifanye visitumike ili kuboresha utendaji wako.</translation>
 <translation id="6145313976051292476">Fungua PDF katika Chrome</translation>
 <translation id="6157638032135951407">Shirika lako hufuta data ya Chrome isipotumika kwa <ph name="TIMEOUT_DURATION" />. Data hii inaweza kujumuisha historia, maelezo yaliyojazwa kiotomatiki na vipakuliwa.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_uz.xtb b/chrome/app/resources/google_chrome_strings_uz.xtb
index e74b9bd..2b5470d 100644
--- a/chrome/app/resources/google_chrome_strings_uz.xtb
+++ b/chrome/app/resources/google_chrome_strings_uz.xtb
@@ -171,6 +171,7 @@
 <translation id="3261565993776444564">Brauzerni yangi rangda moslang va sinang</translation>
 <translation id="3282568296779691940">Chrome hisobiga kirish</translation>
 <translation id="3286538390144397061">Hozir qaytadan ishga tushirish</translation>
+<translation id="3292333338048274092">Keyin Chrome qayta ishga tushirilishi kerak.</translation>
 <translation id="3360895254066713204">Chrome Helper</translation>
 <translation id="3379938682270551431">{0,plural, =0{Chrome hozir qayta ishga tushadi}=1{Chrome 1 soniyadan keyin qayta ishga tushadi}other{Chrome # soniyadan keyin qayta ishga tushadi}}</translation>
 <translation id="3396977131400919238">O‘rnatish mobaynida operatsion tizim xatoligi yuz berdi. Google Chrome’ni qaytadan yuklab oling.</translation>
@@ -215,6 +216,7 @@
 <translation id="4035053306113201399">Yangilanishni oʻrnatish uchun ChromeOS qayta ishga tushirilishi kerak.</translation>
 <translation id="4050175100176540509">So‘nggi versiyada himoya devori yaxshilandi va yangi funksiyalar qo‘shildi.</translation>
 <translation id="4053720452172726777">Google Chrome’ni sozlash va boshqarish</translation>
+<translation id="4084404300720192944">Oynani ulashish uchun tizim sozlamalarida Chrome brauzeriga ekranni yozib olish uchun ruxsat bering.</translation>
 <translation id="4106587138345390261">Chrome saytlarga kamroq maʼlumotlaringiz bilan bir xil brauzer xizmatlarini taqdim etishiga imkon beruvchi yangi funksiyalarni oʻrganib chiqmoqda</translation>
 <translation id="4110895483821904099">Yangi Chrome profilini sozlang</translation>
 <translation id="4111566860456076004">Chrome bu kengaytma manbasini tekshira olmadi va u xavfli boʻlishi mumkin. Ochilgan saytlarda shaxsiy axborot kabi maʼlumotlarni koʻrishi va oʻzgartirishini tugatish uchun uni Chromedan olib tashlang.</translation>
@@ -356,6 +358,7 @@
 <translation id="6173637689840186878"><ph name="PAGE_TITLE" /> - Google Chrome Beta</translation>
 <translation id="6182736845697986886">Yangilanish serveridagi ichki xato sababli oʻrnatilmadi.</translation>
 <translation id="6200139057479872438">Yaqinda ochmagansiz. Chrome olib tashladi: <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /></translation>
+<translation id="621585339844629864">Ekranni ulashish uchun tizim sozlamalarida Chrome uchun ekranni yozib olishga ruxsat bering.</translation>
 <translation id="6235018212288296708">Google Chrome mDNS trafigiga ruxsat berishiga oid kiruvchi qoida.</translation>
 <translation id="624230925347970731">Chrome tez orada yopiladi.</translation>
 <translation id="6247557882553405851">Google Parollar menejeri</translation>
diff --git a/chrome/app/resources/google_chrome_strings_vi.xtb b/chrome/app/resources/google_chrome_strings_vi.xtb
index 74d872e..2e084a3 100644
--- a/chrome/app/resources/google_chrome_strings_vi.xtb
+++ b/chrome/app/resources/google_chrome_strings_vi.xtb
@@ -255,6 +255,7 @@
 <translation id="4561051373932531560">Google Chrome cho phép bạn nhấp vào số điện thoại trên web và gọi tới số đó bằng Skype!</translation>
 <translation id="4567424176335768812">Bạn đã đăng nhập với tên <ph name="USER_EMAIL_ADDRESS" />. Bây giờ, bạn có thể truy cập dấu trang, lịch sử và các cài đặt khác trên tất cả những thiết bị đã đăng nhập của bạn.</translation>
 <translation id="4571503333518166079">Chuyển đến cài đặt thông báo của Chrome</translation>
+<translation id="4575717501879784448">Chrome có thể dừng hoạt động của các thẻ này để cải thiện trải nghiệm duyệt web của bạn và giải phóng tài nguyên.</translation>
 <translation id="459622048091363950">Sau khi Chrome có quyền truy cập, các trang web sẽ có thể yêu cầu bạn cấp quyền truy cập.</translation>
 <translation id="4600710005438004015">Chrome không thể cập nhật lên phiên bản mới nhất nên bạn đang bỏ lỡ các tính năng và bản vá bảo mật mới.</translation>
 <translation id="4624065194742029982">Chế độ ẩn danh trên Chrome</translation>
@@ -286,6 +287,7 @@
 <translation id="4970761609246024540">Chào mừng bạn đến với hồ sơ trên Chrome</translation>
 <translation id="4970880042055371251">Phiên bản ChromeOS</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Chrome có thể dừng hoạt động của các thẻ này để cải thiện và tăng tốc trải nghiệm duyệt web của bạn.</translation>
 <translation id="5003967926796347400">Nhấp vào "Trình quản lý mật khẩu của Google"</translation>
 <translation id="5120334927898581447">Đăng nhập vào Chrome khi bạn đăng nhập vào các dịch vụ khác của Google</translation>
 <translation id="5126049312684316860">Chrome tải trước thêm nhiều trang mà bạn có thể sẽ truy cập để những trang đó tải nhanh hơn khi bạn truy cập</translation>
@@ -348,6 +350,7 @@
 <translation id="608006075545470555">Thêm Hồ sơ công việc vào trình duyệt này</translation>
 <translation id="6097822892606850415">Viết lách tự tin hơn nhờ sự trợ giúp của AI</translation>
 <translation id="6113794647360055231">Chrome được cải tiến hơn</translation>
+<translation id="6135456723633883042">Các thẻ này đang sử dụng thêm tài nguyên. Để cải thiện hiệu suất, hãy cho phép Chrome dừng hoạt động của các thẻ này.</translation>
 <translation id="6145313976051292476">Mở tệp PDF trong Chrome</translation>
 <translation id="6157638032135951407">Tổ chức của bạn sẽ xoá dữ liệu Chrome khi dữ liệu này không được dùng đến trong <ph name="TIMEOUT_DURATION" />. Dữ liệu này có thể bao gồm nhật ký, nội dung tự động điền và tệp đã tải xuống.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_zh-HK.xtb b/chrome/app/resources/google_chrome_strings_zh-HK.xtb
index b42da5c2..1cf3aba 100644
--- a/chrome/app/resources/google_chrome_strings_zh-HK.xtb
+++ b/chrome/app/resources/google_chrome_strings_zh-HK.xtb
@@ -254,6 +254,7 @@
 <translation id="4561051373932531560">Google Chrome 可讓您按一下網頁上的電話號碼,隨即透過 Skype 撥打電話!</translation>
 <translation id="4567424176335768812">您已使用 <ph name="USER_EMAIL_ADDRESS" /> 的身分登入,可以在所有登入的裝置上使用您的書籤、記錄和其他設定。</translation>
 <translation id="4571503333518166079">前往 Chrome 通知設定</translation>
+<translation id="4575717501879784448">Chrome 可讓這些分頁處於閒置狀態,改善瀏覽體驗並釋出資源。</translation>
 <translation id="459622048091363950">Chrome 獲得存取權後,網站便可向您要求存取權。</translation>
 <translation id="4600710005438004015">由於 Chrome 無法更新至最新版本,因此您無法使用最新功能和安全性修正。</translation>
 <translation id="4624065194742029982">Chrome 無痕模式</translation>
@@ -285,6 +286,7 @@
 <translation id="4970761609246024540">歡迎使用 Chrome 設定檔</translation>
 <translation id="4970880042055371251">Chrome OS 版本</translation>
 <translation id="4990567037958725628">Google Chrome Canary</translation>
+<translation id="4997044641749333913">Chrome 可讓這些分頁處於閒置狀態,改善瀏覽體驗並維持快速運作。</translation>
 <translation id="5003967926796347400">按一下 [Google 密碼管理工具]</translation>
 <translation id="5120334927898581447">在登入其他 Google 服務時登入 Chrome</translation>
 <translation id="5126049312684316860">Chrome 會預先載入更多你可能瀏覽的網頁,以便在你瀏覽時更快載入</translation>
@@ -349,6 +351,7 @@
 <translation id="608006075545470555">將工作設定檔新增至此瀏覽器</translation>
 <translation id="6097822892606850415">AI 可讓你在撰寫內容時更有自信</translation>
 <translation id="6113794647360055231">Chrome 變得更好用了</translation>
+<translation id="6135456723633883042">這些分頁正在使用額外的資源。為提升效能,請讓 Chrome 將其設定為閒置分頁。</translation>
 <translation id="6145313976051292476">在 Chrome 中開啟 PDF</translation>
 <translation id="6157638032135951407">您的機構會在 Chrome 閒置 <ph name="TIMEOUT_DURATION" />後刪除 Chrome 資料,當中可能包括記錄、自動填入資料和下載檔案。</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_zu.xtb b/chrome/app/resources/google_chrome_strings_zu.xtb
index ab80791b..1e4437f 100644
--- a/chrome/app/resources/google_chrome_strings_zu.xtb
+++ b/chrome/app/resources/google_chrome_strings_zu.xtb
@@ -255,6 +255,7 @@
 <translation id="4561051373932531560">I-Google Chrome ikuvumela ukuthi uchofoze inombolo yefoni kuwebhu bese wenza ikholi nge-Skype!</translation>
 <translation id="4567424176335768812">Ungene ngemvume njengo-<ph name="USER_EMAIL_ADDRESS" />. Manje ungakwazi ukufinyelela amabhukhimakhi, umlando, nezinye izilungiselelo kuwo wonke amadivayisi wakho ongene kuwo ngemvume.</translation>
 <translation id="4571503333518166079">Hamba kuzilungiselelo zesaziso se-Chrome</translation>
+<translation id="4575717501879784448">IChrome ingenza lawa mathebhu angasebenzi ukuthuthukisa okwenzekayo lapho ubhrawuza iphinde ikhulule izinsiza.</translation>
 <translation id="459622048091363950">Uma i-Chrome inokufinyelela, amawebhusayithi azokwazi ukukucela ukufinyelela.</translation>
 <translation id="4600710005438004015">I-Chrome ayikwazanga ukubuyekezela kwinguqulo yakamuva, ngakho-ke uyalahlekelwa kuzici ezintsha nokulungiswa kokuphepha.</translation>
 <translation id="4624065194742029982">I-Chrome Incognito</translation>
@@ -286,6 +287,7 @@
 <translation id="4970761609246024540">Siyakwamukela kumaphrofayela we-Chrome</translation>
 <translation id="4970880042055371251">Uhlobo lwe-ChromeOS</translation>
 <translation id="4990567037958725628">I-Canary ye-Google Chrome</translation>
+<translation id="4997044641749333913">IChrome ingenza lawa mathebhu angasebenzi ukuze ithuthukise okwenzekayo lapho ubhrawuza iphinde igcine izinto zishesha.</translation>
 <translation id="5003967926796347400">Chofoza okuthi “Google Password Manager”</translation>
 <translation id="5120334927898581447">Ngena ngemvume ku-Chrome uma ungena ngemvume kwamanye amasevisi e-Google</translation>
 <translation id="5126049312684316860">I-Chrome ilayisha kusengaphambili amakhasi engeziwe ongase uwavakashele, ukuze alayishe ngokushesha kakhudlwana lapho uwavakashela</translation>
@@ -350,6 +352,7 @@
 <translation id="608006075545470555">Engeza Iphrofayela Yomsebenzi kulesi siphequluli</translation>
 <translation id="6097822892606850415">Bhala ngokuzethemba okuningi ngosizo lwe-AI</translation>
 <translation id="6113794647360055231">I-Chrome isanda kuba ngcono</translation>
+<translation id="6135456723633883042">Lawa mathebhu asebenzisa izinsiza ezengeziwe. Ukuze uthuthukise ukusebenza kwakho, vumela iChrome iwenze ingasebenzi.</translation>
 <translation id="6145313976051292476">Vula ama-PDF ku-Chrome</translation>
 <translation id="6157638032135951407">Inhlangano yakho isula idatha ye-Chrome uma ingasetshenziswa isikhathi esingu-<ph name="TIMEOUT_DURATION" />. Lokhu kungase kuhlanganise umlando, ukugcwalisa ngokuzenzakalelayo, nokudawuniloda.</translation>
 <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - I-Google Chrome</translation>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 0c5983b4..710db8d 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -2005,6 +2005,7 @@
     "//components/cross_device/logging",
     "//components/enterprise/buildflags",
     "//components/enterprise/common:files_scan_data",
+    "//components/input",
     "//components/nacl/common:buildflags",
     "//components/optimization_guide:machine_learning_tflite_buildflags",
     "//components/page_info",
@@ -2586,6 +2587,7 @@
     "//sql",
     "//storage/browser",
     "//storage/common",
+    "//third_party/anonymous_tokens:anonymous_tokens_cc_proto",
     "//third_party/blink/public:buildflags",
     "//third_party/blink/public:resources",
     "//third_party/blink/public:scaled_resources",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 671eaf3..99c6ddd 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -587,12 +587,12 @@
 };
 
 const FeatureEntry::FeatureParam kCCTDoubleDeckerBottomBarParam[] = {
-    {"google_bottom_bar_layout_variant", "0"}};
+    {"google_bottom_bar_variant_layout", "1"}};
 const FeatureEntry::FeatureParam kCCTSingleDeckerBottomBarParam[] = {
-    {"google_bottom_bar_layout_variant", "1"}};
+    {"google_bottom_bar_variant_layout", "2"}};
 const FeatureEntry::FeatureParam
     kCCTSingleDeckerBottomBarWithButtonsOnRightParam[] = {
-        {"google_bottom_bar_layout_variant", "2"}};
+        {"google_bottom_bar_variant_layout", "3"}};
 
 const FeatureEntry::FeatureVariation
     kCCTGoogleBottomBarVariantLayoutsVariations[] = {
@@ -6747,10 +6747,11 @@
      FEATURE_WITH_PARAMS_VALUE_TYPE(features::kScrollableTabStripOverflow,
                                     kScrollableTabStripOverflowVariations,
                                     "ScrollableTabStripOverflow")},
-
+#if !BUILDFLAG(IS_ANDROID)
     {"split-tabstrip", flag_descriptions::kSplitTabStripName,
      flag_descriptions::kSplitTabStripDescription, kOsDesktop,
-     FEATURE_VALUE_TYPE(features::kSplitTabStrip)},
+     FEATURE_VALUE_TYPE(tabs::kSplitTabStrip)},
+#endif
 
     {flag_descriptions::kSidePanelJourneysFlagId,
      flag_descriptions::kSidePanelJourneysName,
@@ -7489,11 +7490,6 @@
      flag_descriptions::kReadAnythingImagesViaAlgorithmDescription, kOsDesktop,
      FEATURE_VALUE_TYPE(features::kReadAnythingImagesViaAlgorithm)},
 
-    {"read-anything-webui-toolbar",
-     flag_descriptions::kReadAnythingWebUIToolbarName,
-     flag_descriptions::kReadAnythingWebUIToolbarDescription, kOsDesktop,
-     FEATURE_VALUE_TYPE(features::kReadAnythingWebUIToolbar)},
-
     {"read-anything-local-side-panel",
      flag_descriptions::kReadAnythingLocalSidePanelName,
      flag_descriptions::kReadAnythingLocalSidePanelDescription, kOsDesktop,
@@ -10305,11 +10301,6 @@
      FEATURE_VALUE_TYPE(arc::kEnableArcS2Idle)},
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-    {"use-multi-plane-format-for-hardware-video",
-     flag_descriptions::kUseMultiPlaneFormatForHardwareVideoName,
-     flag_descriptions::kUseMultiPlaneFormatForHardwareVideoDescription, kOsAll,
-     FEATURE_VALUE_TYPE(media::kUseMultiPlaneFormatForHardwareVideo)},
-
     {"use-multi-plane-format-for-software-video",
      flag_descriptions::kUseMultiPlaneFormatForSoftwareVideoName,
      flag_descriptions::kUseMultiPlaneFormatForSoftwareVideoDescription, kOsAll,
diff --git a/chrome/browser/android/compositor/compositor_view.cc b/chrome/browser/android/compositor/compositor_view.cc
index f4aa2cd6..7c48eaa 100644
--- a/chrome/browser/android/compositor/compositor_view.cc
+++ b/chrome/browser/android/compositor/compositor_view.cc
@@ -25,8 +25,8 @@
 #include "chrome/browser/ui/android/layouts/scene_layer.h"
 #include "content/public/browser/android/compositor.h"
 #include "content/public/browser/child_process_data.h"
+#include "content/public/browser/peak_gpu_memory_tracker_factory.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/common/peak_gpu_memory_tracker.h"
 #include "content/public/common/process_type.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/android/resources/resource_manager.h"
@@ -379,11 +379,11 @@
   if (!compositor_) {
     return;
   }
-  std::unique_ptr<content::PeakGpuMemoryTracker> tracker =
-      content::PeakGpuMemoryTracker::Create(
-          content::PeakGpuMemoryTracker::Usage::CHANGE_TAB);
+  std::unique_ptr<input::PeakGpuMemoryTracker> tracker =
+      content::PeakGpuMemoryTrackerFactory::Create(
+          input::PeakGpuMemoryTracker::Usage::CHANGE_TAB);
   compositor_->RequestSuccessfulPresentationTimeForNextFrame(base::BindOnce(
-      [](std::unique_ptr<content::PeakGpuMemoryTracker> tracker,
+      [](std::unique_ptr<input::PeakGpuMemoryTracker> tracker,
          const viz::FrameTimingDetails& frame_timing_details) {
         // This callback will be ran once the content::Compositor presents the
         // next frame. The destruction of |tracker| will get the peak GPU memory
diff --git a/chrome/browser/android/context_menu/context_menu_native_delegate_impl.cc b/chrome/browser/android/context_menu/context_menu_native_delegate_impl.cc
index 2286644..5901191 100644
--- a/chrome/browser/android/context_menu/context_menu_native_delegate_impl.cc
+++ b/chrome/browser/android/context_menu/context_menu_native_delegate_impl.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/image_decoder/image_decoder.h"
 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
 #include "components/embedder_support/android/contextmenu/context_menu_builder.h"
+#include "components/embedder_support/android/contextmenu/context_menu_image_format.h"
 #include "components/lens/lens_metadata.mojom.h"
 #include "content/public/browser/web_contents.h"
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
diff --git a/chrome/browser/android/context_menu/context_menu_native_delegate_impl.h b/chrome/browser/android/context_menu/context_menu_native_delegate_impl.h
index 9a9cad7..b8e8062 100644
--- a/chrome/browser/android/context_menu/context_menu_native_delegate_impl.h
+++ b/chrome/browser/android/context_menu/context_menu_native_delegate_impl.h
@@ -15,13 +15,6 @@
 class WebContents;
 }
 
-// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.contextmenu
-enum ContextMenuImageFormat {
-  JPEG = 0,
-  PNG = 1,
-  ORIGINAL = 2,
-};
-
 class ContextMenuNativeDelegateImpl {
  public:
   explicit ContextMenuNativeDelegateImpl(
diff --git a/chrome/browser/android/httpclient/java/src/org/chromium/chrome/browser/android/httpclient/SimpleHttpClient.java b/chrome/browser/android/httpclient/java/src/org/chromium/chrome/browser/android/httpclient/SimpleHttpClient.java
index a6b28de..5ca77bfc 100644
--- a/chrome/browser/android/httpclient/java/src/org/chromium/chrome/browser/android/httpclient/SimpleHttpClient.java
+++ b/chrome/browser/android/httpclient/java/src/org/chromium/chrome/browser/android/httpclient/SimpleHttpClient.java
@@ -20,7 +20,6 @@
 import org.chromium.net.NetworkTrafficAnnotationTag;
 import org.chromium.url.GURL;
 
-import java.util.HashMap;
 import java.util.Map;
 import java.util.function.Consumer;
 
@@ -126,28 +125,6 @@
                 });
     }
 
-    // TODO(agrieve): Delete once unused by //clank.
-    public static HttpResponse createHttpResponse(
-            int responseCode,
-            int netErrorCode,
-            byte[] body,
-            String[] headerKeys,
-            String[] headerValues) {
-        assert headerKeys.length == headerValues.length;
-
-        Map<String, String> responseHeaders = new HashMap<>();
-        for (int i = 0; i < headerKeys.length; i++) {
-            if (!responseHeaders.containsKey(headerKeys[i])) {
-                responseHeaders.put(headerKeys[i], headerValues[i]);
-            } else {
-                String headerValue = responseHeaders.get(headerKeys[i]);
-                headerValue += "\n" + headerValues[i];
-                responseHeaders.put(headerKeys[i], headerValue);
-            }
-        }
-        return createHttpResponse(responseCode, netErrorCode, body, responseHeaders);
-    }
-
     /**
      * Create the HttpResponse object based on set of attributes. Note that the order of
      * headerValues are designed to be purposefully matching headerKeys, and some headerKey(s) might
diff --git a/chrome/browser/ash/accessibility/facegaze_test_utils.h b/chrome/browser/ash/accessibility/facegaze_test_utils.h
index 1f6f79b6..a4a69fb0 100644
--- a/chrome/browser/ash/accessibility/facegaze_test_utils.h
+++ b/chrome/browser/ash/accessibility/facegaze_test_utils.h
@@ -92,6 +92,7 @@
     KEY_PRESS_UP = 41,
     KEY_PRESS_DOWN = 42,
     MOUSE_LONG_CLICK_LEFT = 45,
+    TOGGLE_FACEGAZE = 46,
   };
 
   // Facial gestures recognized by Mediapipe. Ensure this enum stays in sync
diff --git a/chrome/browser/ash/cert_provisioning/cert_provisioning_common.h b/chrome/browser/ash/cert_provisioning/cert_provisioning_common.h
index d057325..4638c57 100644
--- a/chrome/browser/ash/cert_provisioning/cert_provisioning_common.h
+++ b/chrome/browser/ash/cert_provisioning/cert_provisioning_common.h
@@ -14,8 +14,6 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/chromeos/platform_keys/platform_keys.h"
-#include "chromeos/ash/components/dbus/attestation/attestation_ca.pb.h"
-#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
 #include "chromeos/ash/components/dbus/constants/attestation_constants.h"
 #include "components/policy/proto/device_management_backend.pb.h"
 #include "net/cert/x509_certificate.h"
@@ -23,6 +21,10 @@
 class PrefRegistrySimple;
 class Profile;
 
+namespace attestation {
+enum VerifiedAccessFlow : int;
+}  // namespace attestation
+
 namespace ash {
 
 namespace platform_keys {
diff --git a/chrome/browser/ash/chromebox_for_meetings/xu_camera/xu_camera_service.cc b/chrome/browser/ash/chromebox_for_meetings/xu_camera/xu_camera_service.cc
index a363e7f..9e3bdb1 100644
--- a/chrome/browser/ash/chromebox_for_meetings/xu_camera/xu_camera_service.cc
+++ b/chrome/browser/ash/chromebox_for_meetings/xu_camera/xu_camera_service.cc
@@ -270,8 +270,10 @@
     }
   }
 
-  content::GetDeviceService().BindUsbDeviceManager(
-      usb_manager_.BindNewPipeAndPassReceiver());
+  if(!usb_manager_) {
+    content::GetDeviceService().BindUsbDeviceManager(
+        usb_manager_.BindNewPipeAndPassReceiver());
+  }
   device::mojom::UsbEnumerationOptionsPtr options =
       device::mojom::UsbEnumerationOptions::New();
   usb_manager_->GetDevices(
diff --git a/chrome/browser/ash/crosapi/clipboard_history_ash_unittest.cc b/chrome/browser/ash/crosapi/clipboard_history_ash_unittest.cc
index 403077a..cfdde0b 100644
--- a/chrome/browser/ash/crosapi/clipboard_history_ash_unittest.cc
+++ b/chrome/browser/ash/crosapi/clipboard_history_ash_unittest.cc
@@ -28,6 +28,7 @@
 
 namespace {
 
+using ::base::test::InvokeFuture;
 using ::testing::ElementsAre;
 
 // Matchers --------------------------------------------------------------------
@@ -106,9 +107,7 @@
         std::vector<mojom::ClipboardHistoryItemDescriptorPtr>>
         future;
     EXPECT_CALL(mock_client_, SetClipboardHistoryItemDescriptors)
-        .WillOnce([&future](auto descriptors) {
-          future.SetValue(std::move(descriptors));
-        });
+        .WillOnce(InvokeFuture(future));
 
     return future.Take();
   }
diff --git a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc
index d1974eb8..d479ad3 100644
--- a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc
+++ b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc
@@ -978,11 +978,11 @@
     return true;
   }
 
-  void Stop(ReportCallback callback) {
+  bool Stop(ReportCallback callback) {
     stopping_ = true;
     throughtput_timer_.Stop();
     callback_ = std::move(callback);
-    tracker_->Stop();
+    return tracker_->Stop();
   }
 
   void CancelReport() { tracker_->CancelReport(); }
@@ -5894,8 +5894,14 @@
       base::BindOnce(&AutotestPrivateStopSmoothnessTrackingFunction::OnTimeOut,
                      this, display_id));
 
-  it->second->Stop(base::BindOnce(
-      &AutotestPrivateStopSmoothnessTrackingFunction::OnReportData, this));
+  if (!it->second->Stop(base::BindOnce(
+          &AutotestPrivateStopSmoothnessTrackingFunction::OnReportData,
+          this))) {
+    timeout_timer_.AbandonAndStop();
+    trackers->erase(it);
+    return RespondNow(
+        Error("No smoothness report, GPU process may have crashed"));
+  }
 
   // Trigger a repaint after ThroughputTracker::Stop() to generate a frame to
   // ensure the tracker report will be sent back.
diff --git a/chrome/browser/ash/growth/show_notification_action_performer.cc b/chrome/browser/ash/growth/show_notification_action_performer.cc
index c794c6e9..3df98b0 100644
--- a/chrome/browser/ash/growth/show_notification_action_performer.cc
+++ b/chrome/browser/ash/growth/show_notification_action_performer.cc
@@ -275,4 +275,9 @@
   CHECK(campaigns_manager);
 
   campaigns_manager->PerformAction(campaign_id, &action);
+
+  // Explicitly remove the notification as the notification framework doesn't
+  // automatically close at buttons click.
+  message_center::MessageCenter::Get()->RemoveNotification(notification_id,
+                                                           /* by_user=*/true);
 }
diff --git a/chrome/browser/ash/magic_boost/magic_boost_controller_ash.cc b/chrome/browser/ash/magic_boost/magic_boost_controller_ash.cc
index 57ebe12..2625819 100644
--- a/chrome/browser/ash/magic_boost/magic_boost_controller_ash.cc
+++ b/chrome/browser/ash/magic_boost/magic_boost_controller_ash.cc
@@ -35,4 +35,8 @@
   disclaimer_widget_->Show();
 }
 
+void MagicBoostControllerAsh::CloseDisclaimerUi() {
+  disclaimer_widget_.reset();
+}
+
 }  // namespace ash
diff --git a/chrome/browser/ash/magic_boost/magic_boost_controller_ash.h b/chrome/browser/ash/magic_boost/magic_boost_controller_ash.h
index 2502f6b..07032cd 100644
--- a/chrome/browser/ash/magic_boost/magic_boost_controller_ash.h
+++ b/chrome/browser/ash/magic_boost/magic_boost_controller_ash.h
@@ -31,6 +31,7 @@
   void ShowDisclaimerUi(
       int64_t display_id,
       crosapi::mojom::MagicBoostController::TransitionAction action) override;
+  void CloseDisclaimerUi() override;
 
  private:
   mojo::ReceiverSet<crosapi::mojom::MagicBoostController> receivers_;
diff --git a/chrome/browser/ash/net/network_diagnostics/fake_udp_socket.h b/chrome/browser/ash/net/network_diagnostics/fake_udp_socket.h
index 7922b2d..d7e8f4b 100644
--- a/chrome/browser/ash/net/network_diagnostics/fake_udp_socket.h
+++ b/chrome/browser/ash/net/network_diagnostics/fake_udp_socket.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_ASH_NET_NETWORK_DIAGNOSTICS_FAKE_UDP_SOCKET_H_
 
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_span.h"
 #include "base/time/time.h"
 #include "content/public/test/browser_task_environment.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -118,7 +119,7 @@
   net::Error udp_connect_code_ = net::ERR_FAILED;
   net::Error udp_send_code_ = net::ERR_FAILED;
   net::Error udp_on_received_code_ = net::ERR_FAILED;
-  base::span<const uint8_t> udp_on_received_data_ = {};
+  base::raw_span<const uint8_t> udp_on_received_data_ = {};
   bool mojo_disconnect_on_connect_ = false;
   bool mojo_disconnect_on_send_ = false;
   bool mojo_disconnect_on_receive_ = false;
diff --git a/chrome/browser/ash/net/network_diagnostics/udp_prober.cc b/chrome/browser/ash/net/network_diagnostics/udp_prober.cc
index 393a45f..6f8442f 100644
--- a/chrome/browser/ash/net/network_diagnostics/udp_prober.cc
+++ b/chrome/browser/ash/net/network_diagnostics/udp_prober.cc
@@ -13,6 +13,7 @@
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/logging.h"
+#include "base/memory/raw_span.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
@@ -100,7 +101,7 @@
   // Contains the hostname and port.
   net::HostPortPair host_port_pair_;
   // Data to be sent to the destination.
-  base::span<const uint8_t> data_;
+  base::raw_span<const uint8_t> data_;
   // Network annotation tag describing the socket traffic.
   net::NetworkTrafficAnnotationTag tag_;
   // Represents the time after host resolution.
diff --git a/chrome/browser/ash/net/network_diagnostics/udp_prober_unittest.cc b/chrome/browser/ash/net/network_diagnostics/udp_prober_unittest.cc
index a9837c3..816c5ea0 100644
--- a/chrome/browser/ash/net/network_diagnostics/udp_prober_unittest.cc
+++ b/chrome/browser/ash/net/network_diagnostics/udp_prober_unittest.cc
@@ -11,6 +11,7 @@
 
 #include "base/containers/span.h"
 #include "base/functional/bind.h"
+#include "base/memory/raw_span.h"
 #include "base/test/bind.h"
 #include "base/test/test_future.h"
 #include "base/time/time.h"
@@ -113,7 +114,7 @@
       net::HostPortPair::FromString("fake_stun_server.com:80");
   const net::IPEndPoint kFakeIPAddress{
       net::IPEndPoint(net::IPAddress::IPv4Localhost(), /*port=*/1234)};
-  const base::span<const uint8_t> kValidStunData = util::GetStunHeader();
+  const base::raw_span<const uint8_t> kValidStunData = util::GetStunHeader();
   const net::NetworkTrafficAnnotationTag kStunTag =
       util::GetStunNetworkAnnotationTag();
   const base::TimeDelta kTimeoutAfterHostResolution = base::Seconds(10);
diff --git a/chrome/browser/ash/system_web_apps/BUILD.gn b/chrome/browser/ash/system_web_apps/BUILD.gn
index 448ccf2..7f1252eb 100644
--- a/chrome/browser/ash/system_web_apps/BUILD.gn
+++ b/chrome/browser/ash/system_web_apps/BUILD.gn
@@ -33,6 +33,7 @@
     "//ash/webui/media_app_ui",
     "//ash/webui/os_feedback_ui",
     "//ash/webui/personalization_app",
+    "//ash/webui/sanitize_ui",
     "//ash/webui/shimless_rma",
     "//ash/webui/shortcut_customization_ui",
     "//ash/webui/system_apps/public:system_web_app_config",
diff --git a/chrome/browser/ash/system_web_apps/apps/terminal_integration_test.yaml b/chrome/browser/ash/system_web_apps/apps/terminal_integration_test.yaml
index 7b330879..ad668330 100644
--- a/chrome/browser/ash/system_web_apps/apps/terminal_integration_test.yaml
+++ b/chrome/browser/ash/system_web_apps/apps/terminal_integration_test.yaml
@@ -16,5 +16,5 @@
   Sends the given text to the element as individual key press commands
 cases:
   - id: "Crosh"
-    tags: ["crosier:crosierdemosuite", "crosier:cq", "group:hw_agnostic"]
+    tags: ["crosier:crosierdemosuite", "crosier:cq", "group:hw_agnostic", "informational"]
 ...
diff --git a/chrome/browser/ash/system_web_apps/system_web_app_manager.cc b/chrome/browser/ash/system_web_apps/system_web_app_manager.cc
index 50d36ec9..f68cdcf 100644
--- a/chrome/browser/ash/system_web_apps/system_web_app_manager.cc
+++ b/chrome/browser/ash/system_web_apps/system_web_app_manager.cc
@@ -152,6 +152,10 @@
     info_vec.push_back(std::make_unique<SanitizeSystemAppDelegate>(profile));
   }
 
+  if (base::FeatureList::IsEnabled(ash::features::kSanitize)) {
+    info_vec.push_back(std::make_unique<SanitizeSystemAppDelegate>(profile));
+  }
+
 #if !defined(OFFICIAL_BUILD)
   info_vec.push_back(std::make_unique<SampleSystemAppDelegate>(profile));
 #endif  // !defined(OFFICIAL_BUILD)
diff --git a/chrome/browser/autofill/content_autofill_shared_storage_handler_browsertest.cc b/chrome/browser/autofill/content_autofill_shared_storage_handler_browsertest.cc
index a27a7ca..e0f9cfd8 100644
--- a/chrome/browser/autofill/content_autofill_shared_storage_handler_browsertest.cc
+++ b/chrome/browser/autofill/content_autofill_shared_storage_handler_browsertest.cc
@@ -65,8 +65,8 @@
       base::Base64Decode(base::UTF16ToUTF8(result.data), &decoded_data));
   card_list_proto.ParseFromString(decoded_data);
   auto card_data_list = card_list_proto.server_cards();
-  // TODO(b/324137757): AddTestServerCreditCard results in duplicate cards in
-  // the database. Check for exactly one card here once that's fixed.
+  // TODO(crbug.com/324137757): AddTestServerCreditCard results in duplicate
+  // cards in the database. Check for exactly one card here once that's fixed.
   ASSERT_LE(1, card_data_list.size());
   AutofillCreditCardData card_data = card_data_list[0];
   EXPECT_EQ(card.LastFourDigits(), base::UTF8ToUTF16(card_data.last_four()));
diff --git a/chrome/browser/autofill/form_structure_browsertest.cc b/chrome/browser/autofill/form_structure_browsertest.cc
index c8e2929d..48dcf74 100644
--- a/chrome/browser/autofill/form_structure_browsertest.cc
+++ b/chrome/browser/autofill/form_structure_browsertest.cc
@@ -222,7 +222,7 @@
           features::kAutofillEnableExpirationDateImprovements,
           // TODO(crbug.com/40279279): Clean up when launched.
           features::kAutofillDefaultToCityAndNumber,
-          // TODO(b/40204601): Clean up when launched.
+          // TODO(crbug.com/40204601): Clean up when launched.
           blink::features::kAutofillIncludeFormElementsInShadowDom,
           blink::features::
               kAutofillIncludeShadowDomInUnassociatedListedElements,
diff --git a/chrome/browser/bookmarks/android/bookmark_bridge.cc b/chrome/browser/bookmarks/android/bookmark_bridge.cc
index c68a730..050b4dfa 100644
--- a/chrome/browser/bookmarks/android/bookmark_bridge.cc
+++ b/chrome/browser/bookmarks/android/bookmark_bridge.cc
@@ -1477,7 +1477,7 @@
   return (folder->type() != BookmarkNode::BOOKMARK_BAR &&
           folder->type() != BookmarkNode::OTHER_NODE) ||
          (identity_manager &&
-          identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync));
+          identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin));
 }
 
 void BookmarkBridge::NotifyIfDoneLoading() {
diff --git a/chrome/browser/browser_features.cc b/chrome/browser/browser_features.cc
index 228b371f..da267e14 100644
--- a/chrome/browser/browser_features.cc
+++ b/chrome/browser/browser_features.cc
@@ -77,17 +77,19 @@
 // insights regarding console (error) messages.
 BASE_FEATURE(kDevToolsConsoleInsights,
              "DevToolsConsoleInsights",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 const base::FeatureParam<std::string> kDevToolsConsoleInsightsAidaScope{
-    &kDevToolsConsoleInsights, "aida_scope", /*default*/ ""};
+    &kDevToolsConsoleInsights, "aida_scope",
+    /*default*/ "https://www.googleapis.com/auth/aida"};
 const base::FeatureParam<std::string> kDevToolsConsoleInsightsAidaEndpoint{
-    &kDevToolsConsoleInsights, "aida_endpoint", /*default*/ ""};
+    &kDevToolsConsoleInsights, "aida_endpoint",
+    /*default*/ "https://aida.googleapis.com/v1/aida:doConversation"};
 const base::FeatureParam<std::string> kDevToolsConsoleInsightsModelId{
     &kDevToolsConsoleInsights, "aida_model_id", /*default*/ ""};
 const base::FeatureParam<double> kDevToolsConsoleInsightsTemperature{
     &kDevToolsConsoleInsights, "aida_temperature", /*default*/ 0.2};
 const base::FeatureParam<bool> kDevToolsConsoleInsightsOptIn{
-    &kDevToolsConsoleInsights, "opt_in", /*default*/ true};
+    &kDevToolsConsoleInsights, "opt_in", /*default*/ false};
 
 // Separate dogfood feature for DevTools console insights,
 // not restricted by enterprise policy or location.
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
index bea4804..1348a73a 100644
--- a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
+++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
@@ -1782,8 +1782,8 @@
           ContentSettingPatternSource(
               ContentSettingsPattern::FromURLNoWildcard(
                   GURL(kPrimaryUrl)),  // https://subdomain.example.com:112
-              ContentSettingsPattern::FromURLNoWildcard(
-                  GURL(kSecondaryUrl)),  // https://subidubi.testsite.com:55
+              ContentSettingsPattern::FromURLToSchemefulSitePattern(
+                  GURL(kSecondaryUrl)),
               content_settings::ContentSettingToValue(CONTENT_SETTING_ALLOW),
               content_settings::ProviderType::kPrefProvider,
               /*incognito=*/false, expected_metadata)));
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
index a5c581f..85ccc7b 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -4826,8 +4826,8 @@
         return ContentSettingPatternSource(
             ContentSettingsPattern::FromURLNoWildcard(
                 GURL(primaryUrl)),  // e.g. https://subdomain.example.com:112
-            ContentSettingsPattern::FromURLNoWildcard(
-                GURL(secondaryUrl)),  // e.g. https://subidubi.testsite.com:55
+            ContentSettingsPattern::FromURLToSchemefulSitePattern(
+                GURL(secondaryUrl)),
             content_settings::ContentSettingToValue(CONTENT_SETTING_ALLOW),
             content_settings::ProviderType::kPrefProvider, /*incognito=*/false,
             GetMetadata());
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc
index 35994e9..562c792 100644
--- a/chrome/browser/chrome_browser_interface_binders.cc
+++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -309,6 +309,7 @@
 #include "ash/webui/projector_app/untrusted_projector_ui.h"
 #include "ash/webui/recorder_app_ui/mojom/recorder_app.mojom.h"
 #include "ash/webui/recorder_app_ui/recorder_app_ui.h"
+#include "ash/webui/sanitize_ui/sanitize_ui.h"
 #include "ash/webui/scanning/mojom/scanning.mojom.h"
 #include "ash/webui/scanning/scanning_ui.h"
 #include "ash/webui/shimless_rma/shimless_rma.h"
@@ -1209,7 +1210,7 @@
       ash::cloud_upload::CloudUploadUI, ash::office_fallback::OfficeFallbackUI,
       ash::multidevice_setup::MultiDeviceSetupDialogUI, ash::ParentAccessUI,
       ash::EmojiUI, ash::RemoteMaintenanceCurtainUI,
-      ash::app_install::AppInstallDialogUI,
+      ash::app_install::AppInstallDialogUI, ash::SanitizeDialogUI,
       ash::printing::print_preview::PrintPreviewCrosUI,
       ash::extended_updates::ExtendedUpdatesUI,
 #endif
@@ -1961,10 +1962,8 @@
     registry.ForWebUI<CompanionSidePanelUntrustedUI>()
         .Add<side_panel::mojom::CompanionPageHandlerFactory>();
   }
-  if (features::IsReadAnythingWebUIToolbarEnabled()) {
-    registry.ForWebUI<ReadAnythingUntrustedUI>()
-        .Add<color_change_listener::mojom::PageHandler>();
-  }
+  registry.ForWebUI<ReadAnythingUntrustedUI>()
+      .Add<color_change_listener::mojom::PageHandler>();
   if (base::FeatureList::IsEnabled(features::kHaTSWebUI)) {
     registry.ForWebUI<HatsUI>().Add<hats::mojom::PageHandlerFactory>();
   }
diff --git a/chrome/browser/chrome_browser_main_linux.cc b/chrome/browser/chrome_browser_main_linux.cc
index a05cbe58..63eb178 100644
--- a/chrome/browser/chrome_browser_main_linux.cc
+++ b/chrome/browser/chrome_browser_main_linux.cc
@@ -42,6 +42,18 @@
 #include "chrome/browser/dbus_memory_pressure_evaluator_linux.h"
 #endif
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "ash/constants/ash_features.h"
+#include "ash/public/cpp/new_window_delegate.h"
+#include "ash/webui/sanitize_ui/url_constants.h"
+#include "ash/webui/system_apps/public/system_web_app_type.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h"
+#include "chrome/browser/ui/webui/ash/settings/pref_names.h"
+#include "components/prefs/pref_service.h"
+#include "components/services/app_service/public/cpp/app_launch_util.h"
+#endif
+
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
 #include "base/linux_util.h"
 #include "chrome/common/chrome_paths_internal.h"
@@ -118,8 +130,9 @@
   ChromeBrowserMainPartsPosix::PreProfileInit();
 }
 
-#if defined(USE_DBUS) && !BUILDFLAG(IS_CHROMEOS)
+#if (defined(USE_DBUS) && !BUILDFLAG(IS_CHROMEOS)) || BUILDFLAG(IS_CHROMEOS_ASH)
 void ChromeBrowserMainPartsLinux::PostBrowserStart() {
+#if defined(USE_DBUS) && !BUILDFLAG(IS_CHROMEOS)
   // static_cast is safe because this is the only implementation of
   // MemoryPressureMonitor.
   auto* monitor =
@@ -131,10 +144,29 @@
         std::make_unique<DbusMemoryPressureEvaluatorLinux>(
             monitor->CreateVoter()));
   }
-
+#endif  // defined(USE_DBUS) && !BUILDFLAG(IS_CHROMEOS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  CheckIfSanitizeCompleted();
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   ChromeBrowserMainPartsPosix::PostBrowserStart();
 }
-#endif  // defined(USE_DBUS) && !BUILDFLAG(IS_CHROMEOS)
+#endif  // (defined(USE_DBUS) && !BUILDFLAG(IS_CHROMEOS)) ||
+        // BUILDFLAG(IS_CHROMEOS_ASH)
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+void ChromeBrowserMainPartsLinux::CheckIfSanitizeCompleted() {
+  PrefService* prefs = ProfileManager::GetPrimaryUserProfile()->GetPrefs();
+  if (base::FeatureList::IsEnabled(ash::features::kSanitize) &&
+      prefs->GetBoolean(ash::settings::prefs::kSanitizeCompleted)) {
+    prefs->SetBoolean(ash::settings::prefs::kSanitizeCompleted, false);
+    prefs->CommitPendingWrite();
+    ash::SystemAppLaunchParams params;
+    params.launch_source = apps::LaunchSource::kUnknown;
+    ash::LaunchSystemWebAppAsync(ProfileManager::GetPrimaryUserProfile(),
+                                 ash::SystemWebAppType::OS_SANITIZE, params);
+  }
+}
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 void ChromeBrowserMainPartsLinux::PostDestroyThreads() {
 #if BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/chrome_browser_main_linux.h b/chrome/browser/chrome_browser_main_linux.h
index b913d529..3623cc3 100644
--- a/chrome/browser/chrome_browser_main_linux.h
+++ b/chrome/browser/chrome_browser_main_linux.h
@@ -34,7 +34,7 @@
   void PostMainMessageLoopRun() override;
 #endif
   void PreProfileInit() override;
-#if defined(USE_DBUS) && !BUILDFLAG(IS_CHROMEOS)
+#if (defined(USE_DBUS) && !BUILDFLAG(IS_CHROMEOS)) || BUILDFLAG(IS_CHROMEOS_ASH)
   // Only needed for native Linux, to set up the low-memory-monitor-based memory
   // monitoring (which depends on D-Bus).
   void PostBrowserStart() override;
@@ -50,6 +50,12 @@
   scoped_refptr<chromeos::tast_support::StackSamplingRecorder>
       stack_sampling_recorder_;
 #endif
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  // Once Sanitize is completed, ash is restarted. After ash has restarted, we
+  // should check if the restart has happened right after a sanitize. If that is
+  // the case, sanitize done dialog should be shown to the user.
+  void CheckIfSanitizeCompleted();
+#endif
 };
 
 #endif  // CHROME_BROWSER_CHROME_BROWSER_MAIN_LINUX_H_
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 8b9165f..4340623 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -6592,73 +6592,6 @@
     mojo::PendingRemote<network::mojom::WebTransportHandshakeClient>
         handshake_client,
     WillCreateWebTransportCallback callback) {
-#if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
-  content::RenderFrameHost* frame =
-      content::RenderFrameHost::FromID(process_id, frame_routing_id);
-  if (frame) {
-    int frame_tree_node_id = frame->GetFrameTreeNodeId();
-    content::WebContents* web_contents =
-        content::WebContents::FromFrameTreeNodeId(frame_tree_node_id);
-    DCHECK(web_contents);
-    Profile* profile =
-        Profile::FromBrowserContext(web_contents->GetBrowserContext());
-    DCHECK(profile);
-    auto checker = std::make_unique<safe_browsing::WebApiHandshakeChecker>(
-        base::BindOnce(
-            &ChromeContentBrowserClient::GetSafeBrowsingUrlCheckerDelegate,
-            base::Unretained(this),
-            safe_browsing::IsSafeBrowsingEnabled(*profile->GetPrefs()),
-            /*should_check_on_sb_disabled=*/false,
-            safe_browsing::GetURLAllowlistByPolicy(profile->GetPrefs())),
-        base::BindRepeating(&content::WebContents::FromFrameTreeNodeId,
-                            frame_tree_node_id),
-        frame_tree_node_id);
-    auto* raw_checker = checker.get();
-    raw_checker->Check(
-        url,
-        base::BindOnce(
-            &ChromeContentBrowserClient::SafeBrowsingWebApiHandshakeChecked,
-            weak_factory_.GetWeakPtr(), std::move(checker), process_id,
-            frame_routing_id, url, initiator_origin,
-            std::move(handshake_client), std::move(callback)));
-    return;
-  }
-#endif
-  MaybeInterceptWebTransport(process_id, frame_routing_id, url,
-                             initiator_origin, std::move(handshake_client),
-                             std::move(callback));
-}
-
-void ChromeContentBrowserClient::SafeBrowsingWebApiHandshakeChecked(
-    std::unique_ptr<safe_browsing::WebApiHandshakeChecker> checker,
-    int process_id,
-    int frame_routing_id,
-    const GURL& url,
-    const url::Origin& initiator_origin,
-    mojo::PendingRemote<network::mojom::WebTransportHandshakeClient>
-        handshake_client,
-    WillCreateWebTransportCallback callback,
-    safe_browsing::WebApiHandshakeChecker::CheckResult result) {
-  if (result == safe_browsing::WebApiHandshakeChecker::CheckResult::kProceed) {
-    MaybeInterceptWebTransport(process_id, frame_routing_id, url,
-                               initiator_origin, std::move(handshake_client),
-                               std::move(callback));
-  } else {
-    std::move(callback).Run(std::move(handshake_client),
-                            network::mojom::WebTransportError::New(
-                                net::ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
-                                "SafeBrowsing check failed", false));
-  }
-}
-
-void ChromeContentBrowserClient::MaybeInterceptWebTransport(
-    int process_id,
-    int frame_routing_id,
-    const GURL& url,
-    const url::Origin& initiator_origin,
-    mojo::PendingRemote<network::mojom::WebTransportHandshakeClient>
-        handshake_client,
-    WillCreateWebTransportCallback callback) {
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // TODO(crbug.com/40195467): Add a unit test which calls
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 5be680d..3c8ea66 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -28,7 +28,6 @@
 #include "chrome/browser/startup_data.h"
 #include "components/file_access/scoped_file_access.h"
 #include "components/safe_browsing/buildflags.h"
-#include "components/safe_browsing/content/browser/web_api_handshake_checker.h"
 #include "content/public/browser/child_process_security_policy.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/digital_identity_provider.h"
@@ -1161,25 +1160,6 @@
       std::optional<content::LegacyTechCookieIssueDetails> cookie_issue_details)
       override;
 
-  void SafeBrowsingWebApiHandshakeChecked(
-      std::unique_ptr<safe_browsing::WebApiHandshakeChecker> checker,
-      int process_id,
-      int frame_routing_id,
-      const GURL& url,
-      const url::Origin& initiator_origin,
-      mojo::PendingRemote<network::mojom::WebTransportHandshakeClient>
-          handshake_client,
-      WillCreateWebTransportCallback callback,
-      safe_browsing::WebApiHandshakeChecker::CheckResult result);
-  void MaybeInterceptWebTransport(
-      int process_id,
-      int frame_routing_id,
-      const GURL& url,
-      const url::Origin& initiator_origin,
-      mojo::PendingRemote<network::mojom::WebTransportHandshakeClient>
-          handshake_client,
-      WillCreateWebTransportCallback callback);
-
 #if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
   std::unique_ptr<blink::URLLoaderThrottle>
   MaybeCreateSafeBrowsingURLLoaderThrottle(
diff --git a/chrome/browser/content_settings/host_content_settings_map_unittest.cc b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
index 1cd5dc42..b2256dc 100644
--- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc
+++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
@@ -1929,20 +1929,6 @@
   EXPECT_EQ(settings[0].secondary_pattern, ContentSettingsPattern::Wildcard());
 
   // Testing cases:
-  //   WebsiteSettingsInfo::REQUESTING_AND_TOP_ORIGIN_SCOPE,
-  host_content_settings_map->SetContentSettingDefaultScope(
-      primary_url, secondary_url, ContentSettingsType::TOP_LEVEL_STORAGE_ACCESS,
-      CONTENT_SETTING_ALLOW);
-
-  settings = host_content_settings_map->GetSettingsForOneType(
-      ContentSettingsType::TOP_LEVEL_STORAGE_ACCESS);
-
-  EXPECT_EQ(settings[0].primary_pattern,
-            ContentSettingsPattern::FromURLNoWildcard(primary_url));
-  EXPECT_EQ(settings[0].secondary_pattern,
-            ContentSettingsPattern::FromURLNoWildcard(secondary_url));
-
-  // Testing cases:
   //   WebsiteSettingsInfo::REQUESTING_ORIGIN_AND_TOP_SCHEMEFUL_SITE_SCOPE,
   host_content_settings_map->SetContentSettingDefaultScope(
       primary_url, secondary_url, ContentSettingsType::TPCD_TRIAL,
@@ -2017,17 +2003,6 @@
   EXPECT_EQ(patterns.second, ContentSettingsPattern::Wildcard());
 
   // Testing cases:
-  //   WebsiteSettingsInfo::REQUESTING_AND_TOP_ORIGIN_SCOPE,
-  patterns = HostContentSettingsMap::GetPatternsForContentSettingsType(
-      primary_url, secondary_url,
-      ContentSettingsType::TOP_LEVEL_STORAGE_ACCESS);
-
-  EXPECT_EQ(patterns.first,
-            ContentSettingsPattern::FromURLNoWildcard(primary_url));
-  EXPECT_EQ(patterns.second,
-            ContentSettingsPattern::FromURLNoWildcard(secondary_url));
-
-  // Testing cases:
   //   WebsiteSettingsInfo::REQUESTING_ORIGIN_AND_TOP_SCHEMEFUL_SITE_SCOPE,
   patterns = HostContentSettingsMap::GetPatternsForContentSettingsType(
       primary_url, secondary_url, ContentSettingsType::TPCD_TRIAL);
diff --git a/chrome/browser/contextmenu/BUILD.gn b/chrome/browser/contextmenu/BUILD.gn
index ba7d3d8..c6b9efd 100644
--- a/chrome/browser/contextmenu/BUILD.gn
+++ b/chrome/browser/contextmenu/BUILD.gn
@@ -8,20 +8,9 @@
 import("//third_party/jni_zero/jni_zero.gni")
 
 android_library("java") {
-  sources = [
-    "java/src/org/chromium/chrome/browser/contextmenu/ChipDelegate.java",
-    "java/src/org/chromium/chrome/browser/contextmenu/ChipRenderParams.java",
-    "java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java",
-    "java/src/org/chromium/chrome/browser/contextmenu/ContextMenuNativeDelegate.java",
-    "java/src/org/chromium/chrome/browser/contextmenu/ContextMenuNativeDelegateImpl.java",
-    "java/src/org/chromium/chrome/browser/contextmenu/ContextMenuPopulator.java",
-    "java/src/org/chromium/chrome/browser/contextmenu/ContextMenuPopulatorFactory.java",
-  ]
+  sources = [ "java/src/org/chromium/chrome/browser/contextmenu/ContextMenuNativeDelegateImpl.java" ]
 
-  srcjar_deps = [
-    ":jni_headers",
-    "//chrome:context_menu_image_format_enum_javagen",
-  ]
+  srcjar_deps = [ ":jni_headers" ]
 
   deps = [
     "//base:base_java",
diff --git a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuNativeDelegateImpl.java b/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuNativeDelegateImpl.java
index 2f6fdd6..e93a2a6 100644
--- a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuNativeDelegateImpl.java
+++ b/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuNativeDelegateImpl.java
@@ -14,6 +14,8 @@
 
 import org.chromium.base.Callback;
 import org.chromium.components.browser_ui.share.ShareImageFileUtils;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuImageFormat;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuNativeDelegate;
 import org.chromium.components.embedder_support.contextmenu.ContextMenuParams;
 import org.chromium.content_public.browser.RenderFrameHost;
 import org.chromium.content_public.browser.WebContents;
diff --git a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
index 10fd31d..24a2560 100644
--- a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
+++ b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
@@ -141,6 +141,32 @@
 
 ChromeDevToolsManagerDelegate* g_instance;
 
+bool IsIsolatedWebApp(content::WebContents* web_contents) {
+  const webapps::AppId* app_id =
+      web_app::WebAppTabHelper::GetAppId(web_contents);
+
+  if (!app_id) {
+    return false;
+  }
+
+  Profile* profile =
+      Profile::FromBrowserContext(web_contents->GetBrowserContext());
+
+  const web_app::WebAppProvider* provider =
+      web_app::WebAppProvider::GetForWebApps(profile);
+  if (!provider) {
+    return false;
+  }
+
+  // In this case we will not modify any data and reading stale data is
+  // fine, since the app will already be installed and open in the case
+  // it needs to be checked in DevTools.
+  const web_app::WebAppRegistrar& registrar = provider->registrar_unsafe();
+
+  const web_app::WebApp* web_app = registrar.GetAppById(*app_id);
+  return web_app && web_app->isolation_data().has_value();
+}
+
 }  // namespace
 
 // static
@@ -234,6 +260,10 @@
 
 std::string ChromeDevToolsManagerDelegate::GetTargetType(
     content::WebContents* web_contents) {
+  if (IsIsolatedWebApp(web_contents)) {
+    return ChromeDevToolsManagerDelegate::kTypeApp;
+  }
+
   if (base::Contains(AllTabContentses(), web_contents))
     return DevToolsAgentHost::kTypePage;
 
diff --git a/chrome/browser/devtools/devtools_browsertest.cc b/chrome/browser/devtools/devtools_browsertest.cc
index 4df0ce1..dd29561 100644
--- a/chrome/browser/devtools/devtools_browsertest.cc
+++ b/chrome/browser/devtools/devtools_browsertest.cc
@@ -4051,7 +4051,7 @@
       configConsoleInsights->FindBool("blockedByEnterprisePolicy").value());
   EXPECT_FALSE(configConsoleInsights->FindBool("blockedByAge").value());
   EXPECT_FALSE(configConsoleInsights->FindBool("blockedByGeo").value());
-  EXPECT_TRUE(configConsoleInsights->FindBool("optIn").value());
+  EXPECT_FALSE(configConsoleInsights->FindBool("optIn").value());
   CloseDevToolsWindow();
 }
 
diff --git a/chrome/browser/devtools/process_sharing_infobar_delegate.cc b/chrome/browser/devtools/process_sharing_infobar_delegate.cc
index 5ebc37f2..ccd6880b 100644
--- a/chrome/browser/devtools/process_sharing_infobar_delegate.cc
+++ b/chrome/browser/devtools/process_sharing_infobar_delegate.cc
@@ -23,6 +23,15 @@
   return BUTTON_NONE;
 }
 
+std::u16string ProcessSharingInfobarDelegate::GetLinkText() const {
+  return l10n_util::GetStringUTF16(
+      IDS_DEV_TOOLS_SHARED_PROCESS_INFOBAR_LEARN_MORE);
+}
+
+GURL ProcessSharingInfobarDelegate::GetLinkURL() const {
+  return GURL("https://developer.chrome.com/docs/devtools/shared-processes");
+}
+
 infobars::InfoBarDelegate::InfoBarIdentifier
 ProcessSharingInfobarDelegate::GetIdentifier() const {
   return DEV_TOOLS_SHARED_PROCESS_DELEGATE;
diff --git a/chrome/browser/devtools/process_sharing_infobar_delegate.h b/chrome/browser/devtools/process_sharing_infobar_delegate.h
index 0800e70..74de490 100644
--- a/chrome/browser/devtools/process_sharing_infobar_delegate.h
+++ b/chrome/browser/devtools/process_sharing_infobar_delegate.h
@@ -20,6 +20,8 @@
   // ConfirmInfoBarDelegate:
   std::u16string GetMessageText() const override;
   int GetButtons() const override;
+  std::u16string GetLinkText() const override;
+  GURL GetLinkURL() const override;
 
   // infobars::InfoBarDelegate
   infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override;
diff --git a/chrome/browser/devtools/protocol/devtools_printtopdf_browsertest.cc b/chrome/browser/devtools/protocol/devtools_printtopdf_browsertest.cc
index 55421db..545596e 100644
--- a/chrome/browser/devtools/protocol/devtools_printtopdf_browsertest.cc
+++ b/chrome/browser/devtools/protocol/devtools_printtopdf_browsertest.cc
@@ -9,6 +9,7 @@
 #include "base/base64.h"
 #include "base/containers/span.h"
 #include "base/functional/bind.h"
+#include "base/memory/raw_span.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/test/values_test_util.h"
@@ -128,7 +129,7 @@
   net::EmbeddedTestServer https_server_;
 
   std::string pdf_data_;
-  base::span<const uint8_t> pdf_span_;
+  base::raw_span<const uint8_t, DanglingUntriaged> pdf_span_;
   int pdf_num_pages_ = 0;
 
   headless::PDFPageBitmap page_bitmap;
diff --git a/chrome/browser/enterprise/connectors/analysis/analysis_settings.h b/chrome/browser/enterprise/connectors/analysis/analysis_settings.h
index 4bda9d8f..d5f9be1 100644
--- a/chrome/browser/enterprise/connectors/analysis/analysis_settings.h
+++ b/chrome/browser/enterprise/connectors/analysis/analysis_settings.h
@@ -10,6 +10,7 @@
 #include <vector>
 
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_span.h"
 #include "components/enterprise/common/proto/connectors.pb.h"
 #include "components/enterprise/connectors/service_provider_config.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
@@ -76,7 +77,7 @@
 
   std::string local_path;
   bool user_specific = false;
-  base::span<const char* const> subject_names;
+  base::raw_span<const char* const> subject_names;
   // The scanning limit for pasted text and image in local content analysis.
   size_t max_file_size;
   // Arrays of base64 encoded signing key signatures.
diff --git a/chrome/browser/extensions/api/identity/identity_api.cc b/chrome/browser/extensions/api/identity/identity_api.cc
index 3421a09..009ce652 100644
--- a/chrome/browser/extensions/api/identity/identity_api.cc
+++ b/chrome/browser/extensions/api/identity/identity_api.cc
@@ -13,6 +13,7 @@
 #include <vector>
 
 #include "base/containers/contains.h"
+#include "base/functional/callback_forward.h"
 #include "base/lazy_instance.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/trace_event/trace_event.h"
@@ -39,6 +40,11 @@
 #include "google_apis/gaia/gaia_urls.h"
 #include "url/gurl.h"
 
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
+#endif
+
 using signin::ConsentLevel;
 using signin::PrimaryAccountChangeEvent;
 
@@ -128,6 +134,73 @@
   return identity_manager_->HasPrimaryAccount(ConsentLevel::kSignin);
 }
 
+std::vector<CoreAccountInfo>
+IdentityAPI::GetAccountsWithRefreshTokensForExtensions() {
+  if (!HasAccessToChromeAccounts()) {
+    return {};
+  }
+  return identity_manager_->GetAccountsWithRefreshTokens();
+}
+
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+void IdentityAPI::MaybeShowChromeSigninDialog(std::string_view extension_name,
+                                              base::OnceClosure on_complete) {
+  if (HasAccessToChromeAccounts() ||
+      identity_manager_->GetAccountsWithRefreshTokens().empty()) {
+    DVLOG(1) << "The user is not signed in on the web!";
+    std::move(on_complete).Run();
+    return;
+  }
+
+  if (is_chrome_signin_dialog_open_) {
+    DVLOG(1) << "Chrome sign in dialog is already open, extensions are not "
+                "allowed to trigger more than one";
+    on_chrome_signin_dialog_completed_.push_back(std::move(on_complete));
+    return;
+  }
+
+  // Used in unittests to avoid creating a browser.
+  if (skip_ui_for_testing_callback_) {
+    HandleSkipUIForTesting(std::move(on_complete));  // IN-TEST
+    return;
+  }
+
+  chrome::ScopedTabbedBrowserDisplayer displayer(profile_);
+  Browser* browser = displayer.browser();
+  if (!browser) {
+    DVLOG(1) << "Could not create a browser to show Extensions Chrome Sign in "
+                "dialog.";
+    std::move(on_complete).Run();
+    return;
+  }
+  on_chrome_signin_dialog_completed_.push_back(std::move(on_complete));
+  is_chrome_signin_dialog_open_ = true;
+  browser->signin_view_controller()->MaybeShowChromeSigninDialogForExtensions(
+      extension_name,
+      base::BindOnce(&IdentityAPI::OnChromeSigninDialogDestroyed,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void IdentityAPI::OnChromeSigninDialogDestroyed() {
+  is_chrome_signin_dialog_open_ = false;
+  std::vector<base::OnceClosure> callbacks;
+  std::swap(on_chrome_signin_dialog_completed_, callbacks);
+  for (auto& callback : callbacks) {
+    std::move(callback).Run();
+  }
+}
+
+void IdentityAPI::HandleSkipUIForTesting(base::OnceClosure on_complete) {
+  is_chrome_signin_dialog_open_ = true;
+  on_chrome_signin_dialog_completed_.push_back(std::move(on_complete));
+  // Allow tests to complete the flow.
+  std::move(skip_ui_for_testing_callback_)
+      .Run(base::BindOnce(&IdentityAPI::OnChromeSigninDialogDestroyed,
+                          weak_ptr_factory_.GetWeakPtr()));
+  return;
+}
+#endif
+
 IdentityAPI::IdentityAPI(Profile* profile,
                          signin::IdentityManager* identity_manager,
                          ExtensionPrefs* extension_prefs,
@@ -140,14 +213,6 @@
   EraseStaleGaiaIdsForAllExtensions();
 }
 
-std::vector<CoreAccountInfo>
-IdentityAPI::GetAccountsWithRefreshTokensForExtensions() {
-  if (!HasAccessToChromeAccounts()) {
-    return {};
-  }
-  return identity_manager_->GetAccountsWithRefreshTokens();
-}
-
 void IdentityAPI::OnPrimaryAccountChanged(
     const PrimaryAccountChangeEvent& event_details) {
   switch (event_details.GetEventTypeFor(ConsentLevel::kSignin)) {
diff --git a/chrome/browser/extensions/api/identity/identity_api.h b/chrome/browser/extensions/api/identity/identity_api.h
index 144d0323..e9fbdf0 100644
--- a/chrome/browser/extensions/api/identity/identity_api.h
+++ b/chrome/browser/extensions/api/identity/identity_api.h
@@ -12,6 +12,7 @@
 #include "base/callback_list.h"
 #include "base/containers/flat_set.h"
 #include "base/feature_list.h"
+#include "base/functional/callback_forward.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "build/build_config.h"
@@ -81,6 +82,27 @@
   // account only.
   bool AreExtensionsRestrictedToPrimaryAccount();
 
+  // Returns accounts that extension have access to.
+  // This returns empty if Chrome is not signed in. Otherwise, returns all
+  // accounts in the `identity_manager_`.
+  std::vector<CoreAccountInfo> GetAccountsWithRefreshTokensForExtensions();
+
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+  // Shows the Chrome sign in dialog for extensions if:
+  // - The dialog is not already showing
+  // - The user is signed in on the web but not to Chrome
+  // `on_complete` is guaranteed to be called.
+  void MaybeShowChromeSigninDialog(std::string_view extension_name,
+                                   base::OnceClosure on_complete);
+
+  // Callback to be called when the tests triggers showing UI.
+  // Should be used in unittests.
+  void SetSkipUIForTesting(
+      base::OnceCallback<void(base::OnceClosure)> callback) {
+    skip_ui_for_testing_callback_ = std::move(callback);
+  }
+#endif
+
  private:
   friend class BrowserContextKeyedAPIFactory<IdentityAPI>;
   friend class IdentityAPITest;
@@ -98,10 +120,6 @@
   // Returns true if extensions have access to Chrome accounts.
   // Access requires Chrome to be signed in.
   bool HasAccessToChromeAccounts() const;
-  // Returns accounts that extension have access to.
-  // This returns empty if Chrome is not signed in. Otherwise, returns all
-  // accounts in the `identity_manager_`.
-  std::vector<CoreAccountInfo> GetAccountsWithRefreshTokensForExtensions();
 
   // signin::IdentityManager::Observer:
   void OnPrimaryAccountChanged(
@@ -118,6 +136,11 @@
   void FireOnAccountSignInChanged(const std::string& gaia_id,
                                   bool is_signed_in);
 
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+  void OnChromeSigninDialogDestroyed();
+  void HandleSkipUIForTesting(base::OnceClosure on_complete);
+#endif
+
   const raw_ptr<Profile> profile_;
   const raw_ptr<signin::IdentityManager> identity_manager_;
   const raw_ptr<ExtensionPrefs> extension_prefs_;
@@ -131,6 +154,14 @@
   OnSignInChangedCallback on_signin_changed_callback_for_testing_;
 
   base::OnceCallbackList<void()> on_shutdown_callback_list_;
+
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+  bool is_chrome_signin_dialog_open_ = false;
+  std::vector<base::OnceClosure> on_chrome_signin_dialog_completed_;
+  // Should only be set in unittests.
+  base::OnceCallback<void(base::OnceClosure)> skip_ui_for_testing_callback_;
+  base::WeakPtrFactory<IdentityAPI> weak_ptr_factory_{this};
+#endif
 };
 
 template <>
diff --git a/chrome/browser/extensions/api/identity/identity_api_unittest.cc b/chrome/browser/extensions/api/identity/identity_api_unittest.cc
index eaa3c93f..6acea94 100644
--- a/chrome/browser/extensions/api/identity/identity_api_unittest.cc
+++ b/chrome/browser/extensions/api/identity/identity_api_unittest.cc
@@ -9,6 +9,7 @@
 
 #include "base/task/single_thread_task_runner.h"
 #include "base/test/mock_callback.h"
+#include "base/test/test_future.h"
 #include "chrome/browser/extensions/test_extension_prefs.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/signin/public/base/consent_level.h"
@@ -206,4 +207,85 @@
   Mock::VerifyAndClearExpectations(&mock_on_signin_changed_callback());
 #endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
 }
+
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+TEST_F(IdentityAPITest, MaybeShowChromeSigninDialogChromeAlreadySignedIn) {
+  EXPECT_CALL(mock_on_signin_changed_callback(), Run(_));
+  identity_env()->MakePrimaryAccountAvailable(kTestAccount,
+                                              signin::ConsentLevel::kSignin);
+  ASSERT_TRUE(identity_env()->identity_manager()->HasPrimaryAccount(
+      signin::ConsentLevel::kSignin));
+  base::test::TestFuture<void> on_complete;
+  api()->MaybeShowChromeSigninDialog("Extension name",
+                                     on_complete.GetCallback());
+  // The UI is not shown and the callback is shown immediately.
+  EXPECT_TRUE(on_complete.IsReady());
+}
+
+TEST_F(IdentityAPITest, MaybeShowChromeSigninDialogNoAccountsOnTheWeb) {
+  ASSERT_TRUE(identity_env()
+                  ->identity_manager()
+                  ->GetAccountsWithRefreshTokens()
+                  .empty());
+  base::test::TestFuture<void> on_complete;
+  api()->MaybeShowChromeSigninDialog("Extension name",
+                                     on_complete.GetCallback());
+  // The UI is not shown and the callback is shown immediately.
+  EXPECT_TRUE(on_complete.IsReady());
+}
+
+TEST_F(IdentityAPITest, MaybeShowChromeSigninDialog) {
+  identity_env()->MakeAccountAvailable(kTestAccount);
+  ASSERT_FALSE(identity_env()
+                   ->identity_manager()
+                   ->GetAccountsWithRefreshTokens()
+                   .empty());
+
+  const size_t kShowTwice = 2;
+  for (size_t i = 0; i < kShowTwice; i++) {
+    base::test::TestFuture<base::OnceClosure> on_ui_triggered;
+    api()->SetSkipUIForTesting(on_ui_triggered.GetCallback());
+
+    base::test::TestFuture<void> on_complete;
+    api()->MaybeShowChromeSigninDialog("Extension name",
+                                       on_complete.GetCallback());
+
+    EXPECT_FALSE(on_complete.IsReady());
+    EXPECT_TRUE(on_ui_triggered.IsReady());
+
+    // Complete the dialog.
+    std::move(on_ui_triggered.Take()).Run();
+    EXPECT_TRUE(on_complete.IsReady());
+  }
+}
+
+TEST_F(IdentityAPITest, MaybeShowChromeSigninDialogConcurrent) {
+  identity_env()->MakeAccountAvailable(kTestAccount);
+  ASSERT_FALSE(identity_env()
+                   ->identity_manager()
+                   ->GetAccountsWithRefreshTokens()
+                   .empty());
+
+  base::test::TestFuture<base::OnceClosure> on_ui_triggered;
+  api()->SetSkipUIForTesting(on_ui_triggered.GetCallback());
+
+  base::test::TestFuture<void> on_complete_1;
+  base::test::TestFuture<void> on_complete_2;
+  api()->MaybeShowChromeSigninDialog("Extension name",
+                                     on_complete_1.GetCallback());
+
+  EXPECT_TRUE(on_ui_triggered.IsReady());
+  // Should crash if UI is shown as `on_ui_triggered` should have been already
+  // consumed.
+  api()->MaybeShowChromeSigninDialog("Extension name",
+                                     on_complete_2.GetCallback());
+
+  EXPECT_FALSE(on_complete_1.IsReady());
+  EXPECT_FALSE(on_complete_2.IsReady());
+  // Complete the dialog.
+  std::move(on_ui_triggered.Take()).Run();
+  EXPECT_TRUE(on_complete_1.IsReady());
+  EXPECT_TRUE(on_complete_2.IsReady());
+}
+#endif
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/identity/identity_apitest.cc b/chrome/browser/extensions/api/identity/identity_apitest.cc
index c6ad0488..93b16c2 100644
--- a/chrome/browser/extensions/api/identity/identity_apitest.cc
+++ b/chrome/browser/extensions/api/identity/identity_apitest.cc
@@ -99,6 +99,8 @@
 #include "ui/base/idle/idle.h"
 #include "ui/base/idle/scoped_set_idle_state.h"
 #include "ui/gfx/geometry/rect.h"
+#include "ui/views/widget/any_widget_observer.h"
+#include "ui/views/window/dialog_delegate.h"
 #include "url/gurl.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -667,20 +669,19 @@
       GenerateFailureResult(gaia_ids, nullptr) << "Result was not an array";
     const base::Value::List& results = (*callback_arguments_list)[0].GetList();
 
-    std::set<std::string> result_ids;
+    std::vector<std::string> result_ids;
     for (const base::Value& item : results) {
       std::optional<api::identity::AccountInfo> info =
           api::identity::AccountInfo::FromValue(item);
       if (info) {
-        result_ids.insert(info->id);
+        result_ids.push_back(info->id);
       } else {
         return GenerateFailureResult(gaia_ids, &results);
       }
     }
 
-    for (const std::string& gaia_id : gaia_ids) {
-      if (result_ids.find(gaia_id) == result_ids.end())
-        return GenerateFailureResult(gaia_ids, &results);
+    if (result_ids != gaia_ids) {
+      return GenerateFailureResult(gaia_ids, &results);
     }
 
     return testing::AssertionResult(true);
@@ -710,6 +711,10 @@
 
     return testing::AssertionFailure(msg);
   }
+
+ private:
+  base::test::ScopedFeatureList feature_list_{
+      switches::kExplicitBrowserSigninUIOnDesktop};
 };
 
 IN_PROC_BROWSER_TEST_F(IdentityGetAccountsFunctionTest, AllAccountsOn) {
@@ -729,7 +734,7 @@
                        PrimaryAccountHasInvalidRefreshToken) {
   CoreAccountId primary_account_id = SignIn("primary@example.com");
   identity_test_env()->SetInvalidRefreshTokenForPrimaryAccount();
-  EXPECT_TRUE(ExpectGetAccounts({}));
+  EXPECT_TRUE(ExpectGetAccounts({"gaia_id_for_primary_example.com"}));
 }
 
 IN_PROC_BROWSER_TEST_F(IdentityGetAccountsFunctionTest,
@@ -749,6 +754,15 @@
   }
 }
 
+IN_PROC_BROWSER_TEST_F(IdentityGetAccountsFunctionTest, SignedInOnTheWeb) {
+  identity_test_env()->MakeAccountAvailable("secondary@example.com");
+  EXPECT_TRUE(ExpectGetAccounts({}));
+
+  SignIn("primary@example.com");
+  EXPECT_TRUE(ExpectGetAccounts({"gaia_id_for_primary_example.com",
+                                 "gaia_id_for_secondary_example.com"}));
+}
+
 class IdentityGetProfileUserInfoFunctionTest : public IdentityTestWithSignin {
  protected:
   std::optional<api::identity::ProfileUserInfo> RunGetProfileUserInfo() {
@@ -1074,7 +1088,8 @@
     std::move(on_access_token_requested_).Run();
   }
 
-  base::test::ScopedFeatureList feature_list_;
+  base::test::ScopedFeatureList feature_list_{
+      switches::kExplicitBrowserSigninUIOnDesktop};
   base::HistogramTester histogram_tester_;
   ExtensionId extension_id_;
   std::set<std::string> oauth_scopes_;
@@ -1435,6 +1450,145 @@
       1);
 }
 
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, SignedInWebOnlyAcceptPrompt) {
+  identity_test_env()->MakeAccountAvailable("account@gmail.com",
+                                            {.set_cookie = true});
+  ASSERT_FALSE(identity_test_env()->identity_manager()->HasPrimaryAccount(
+      signin::ConsentLevel::kSignin));
+  ASSERT_FALSE(identity_test_env()
+                   ->identity_manager()
+                   ->GetAccountsWithRefreshTokens()
+                   .empty());
+
+  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
+  scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
+  func->set_extension(extension.get());
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS);
+
+  views::NamedWidgetShownWaiter widget_waiter(
+      views::test::AnyWidgetTestPasskey{},
+      "ChromeSigninChoiceForExtensionsPrompt");
+
+  RunFunctionAsync(func.get(), "[{\"interactive\": true}]");
+  views::Widget* confirmation_prompt = widget_waiter.WaitIfNeededAndGet();
+  views::DialogDelegate* dialog_delegate =
+      confirmation_prompt->widget_delegate()->AsDialogDelegate();
+  ASSERT_TRUE(dialog_delegate);
+  dialog_delegate->AcceptDialog();
+
+  std::string access_token;
+  std::set<std::string> granted_scopes;
+  WaitForGetAuthTokenResults(func.get(), &access_token, &granted_scopes);
+  EXPECT_EQ(std::string(kAccessToken), access_token);
+  EXPECT_EQ(func->GetExtensionTokenKeyForTest()->scopes, granted_scopes);
+
+  EXPECT_FALSE(func->login_ui_shown());
+  EXPECT_FALSE(func->scope_ui_shown());
+  histogram_tester()->ExpectUniqueSample(
+      kGetAuthTokenResultHistogramName, IdentityGetAuthTokenError::State::kNone,
+      1);
+}
+
+IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, SignedInWebOnlyDeclinePrompt) {
+  identity_test_env()->MakeAccountAvailable("account@gmail.com",
+                                            {.set_cookie = true});
+  ASSERT_FALSE(identity_test_env()->identity_manager()->HasPrimaryAccount(
+      signin::ConsentLevel::kSignin));
+  ASSERT_FALSE(identity_test_env()
+                   ->identity_manager()
+                   ->GetAccountsWithRefreshTokens()
+                   .empty());
+
+  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
+  scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
+  func->set_extension(extension.get());
+  func->push_mint_token_result(TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS);
+
+  views::NamedWidgetShownWaiter widget_waiter(
+      views::test::AnyWidgetTestPasskey{},
+      "ChromeSigninChoiceForExtensionsPrompt");
+
+  RunFunctionAsync(func.get(), "[{\"interactive\": true}]");
+  views::Widget* confirmation_prompt = widget_waiter.WaitIfNeededAndGet();
+  views::DialogDelegate* dialog_delegate =
+      confirmation_prompt->widget_delegate()->AsDialogDelegate();
+  ASSERT_TRUE(dialog_delegate);
+  dialog_delegate->CancelDialog();
+
+  EXPECT_EQ(std::string(errors::kUserNotSignedIn), WaitForError(func.get()));
+
+  EXPECT_FALSE(func->login_ui_shown());
+  EXPECT_FALSE(func->scope_ui_shown());
+  histogram_tester()->ExpectUniqueSample(
+      kGetAuthTokenResultHistogramName,
+      IdentityGetAuthTokenError::State::kSignInFailed, 1);
+}
+
+IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
+                       SignedInWebOnlyAcceptPromptMultipleFunctions) {
+  identity_test_env()->MakeAccountAvailable("account@gmail.com",
+                                            {.set_cookie = true});
+  ASSERT_FALSE(identity_test_env()->identity_manager()->HasPrimaryAccount(
+      signin::ConsentLevel::kSignin));
+  ASSERT_FALSE(identity_test_env()
+                   ->identity_manager()
+                   ->GetAccountsWithRefreshTokens()
+                   .empty());
+
+  scoped_refptr<const Extension> extension(CreateExtension(CLIENT_ID | SCOPES));
+  scoped_refptr<FakeGetAuthTokenFunction> func1(new FakeGetAuthTokenFunction());
+  func1->set_extension(extension.get());
+  func1->push_mint_token_result(TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS);
+
+  scoped_refptr<FakeGetAuthTokenFunction> func2(new FakeGetAuthTokenFunction());
+  scoped_refptr<const Extension> extension2(
+      CreateExtension(CLIENT_ID | SCOPES));
+  func2->set_extension(extension2.get());
+  func2->push_mint_token_result(TestOAuth2MintTokenFlow::MINT_TOKEN_SUCCESS);
+
+  AsyncFunctionRunner func1_runner;
+  func1_runner.RunFunctionAsync(func1.get(), "[{\"interactive\": true}]",
+                                browser()->profile());
+
+  AsyncFunctionRunner func2_runner;
+  func2_runner.RunFunctionAsync(func2.get(), "[{\"interactive\": true}]",
+                                browser()->profile());
+
+  views::NamedWidgetShownWaiter widget_waiter(
+      views::test::AnyWidgetTestPasskey{},
+      "ChromeSigninChoiceForExtensionsPrompt");
+
+  views::Widget* confirmation_prompt = widget_waiter.WaitIfNeededAndGet();
+  views::DialogDelegate* dialog_delegate =
+      confirmation_prompt->widget_delegate()->AsDialogDelegate();
+  ASSERT_TRUE(dialog_delegate);
+  dialog_delegate->AcceptDialog();
+
+  std::string access_token;
+  std::set<std::string> granted_scopes;
+  WaitForGetAuthTokenResults(func1.get(), &access_token, &granted_scopes,
+                             &func1_runner);
+  EXPECT_EQ(std::string(kAccessToken), access_token);
+  EXPECT_EQ(func1->GetExtensionTokenKeyForTest()->scopes, granted_scopes);
+
+  EXPECT_FALSE(func1->login_ui_shown());
+  EXPECT_FALSE(func1->scope_ui_shown());
+
+  WaitForGetAuthTokenResults(func2.get(), &access_token, &granted_scopes,
+                             &func2_runner);
+  EXPECT_EQ(std::string(kAccessToken), access_token);
+  EXPECT_EQ(func2->GetExtensionTokenKeyForTest()->scopes, granted_scopes);
+
+  EXPECT_FALSE(func2->login_ui_shown());
+  EXPECT_FALSE(func2->scope_ui_shown());
+
+  histogram_tester()->ExpectUniqueSample(
+      kGetAuthTokenResultHistogramName, IdentityGetAuthTokenError::State::kNone,
+      2);
+}
+#endif
+
 IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
                        InteractiveLoginSuccessApprovalAborted) {
   scoped_refptr<FakeGetAuthTokenFunction> func(new FakeGetAuthTokenFunction());
diff --git a/chrome/browser/extensions/api/identity/identity_get_accounts_function.cc b/chrome/browser/extensions/api/identity/identity_get_accounts_function.cc
index cdacd79..319b34ca 100644
--- a/chrome/browser/extensions/api/identity/identity_get_accounts_function.cc
+++ b/chrome/browser/extensions/api/identity/identity_get_accounts_function.cc
@@ -30,20 +30,18 @@
     return RespondNow(Error(identity_constants::kOffTheRecord));
   }
 
+  Profile* profile = Profile::FromBrowserContext(browser_context());
+  IdentityAPI* identity_api = IdentityAPI::GetFactoryInstance()->Get(profile);
   std::vector<CoreAccountInfo> accounts =
-      IdentityManagerFactory::GetForProfile(
-          Profile::FromBrowserContext(browser_context()))
-          ->GetAccountsWithRefreshTokens();
+      identity_api->GetAccountsWithRefreshTokensForExtensions();
   base::Value::List infos;
 
   if (accounts.empty()) {
     return RespondNow(WithArguments(std::move(infos)));
   }
 
-  Profile* profile = Profile::FromBrowserContext(browser_context());
-  bool primary_account_only = IdentityAPI::GetFactoryInstance()
-                                  ->Get(profile)
-                                  ->AreExtensionsRestrictedToPrimaryAccount();
+  bool primary_account_only =
+      identity_api->AreExtensionsRestrictedToPrimaryAccount();
 
   auto* identity_manager = IdentityManagerFactory::GetForProfile(profile);
   api::identity::AccountInfo account_info;
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
index 9da26d3..2795481 100644
--- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
+++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
@@ -30,6 +30,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/signin/public/base/consent_level.h"
 #include "components/signin/public/base/signin_pref_names.h"
+#include "components/signin/public/base/signin_switches.h"
 #include "components/signin/public/identity_manager/access_token_info.h"
 #include "components/signin/public/identity_manager/account_info.h"
 #include "components/signin/public/identity_manager/accounts_in_cookie_jar_info.h"
@@ -320,8 +321,16 @@
   waiting_on_account_ = true;
   auto* identity_manager = IdentityManagerFactory::GetForProfile(GetProfile());
   scoped_identity_manager_observation_.Observe(identity_manager);
-  // TODO(msalama): Check if the user is signed in on the web and show a
-  // different UI.
+
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+  if (!identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin) &&
+      !identity_manager->GetAccountsWithRefreshTokens().empty() &&
+      switches::IsExplicitBrowserSigninUIOnDesktopEnabled()) {
+    // The user is signed in on the web but not to Chrome.
+    MaybeShowChromeSigninDialog();
+    return;
+  }
+#endif  // BUILDFLAG(ENABLE_DICE_SUPPORT)
   ShowExtensionLoginPrompt();
 #endif
 }
@@ -795,6 +804,33 @@
                           login_access_token);
 }
 
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+void IdentityGetAuthTokenFunction::MaybeShowChromeSigninDialog() {
+  IdentityAPI* identity_api =
+      IdentityAPI::GetFactoryInstance()->Get(GetProfile());
+  identity_api->MaybeShowChromeSigninDialog(
+      extension()->name(),
+      base::BindOnce(
+          &IdentityGetAuthTokenFunction::OnChromeSigninDialogDestroyed,
+          weak_ptr_factory_.GetWeakPtr()));
+}
+
+void IdentityGetAuthTokenFunction::OnChromeSigninDialogDestroyed() {
+  if (!IdentityManagerFactory::GetForProfile(GetProfile())
+           ->HasPrimaryAccount(signin::ConsentLevel::kSignin)) {
+    // The user, cancelled or dismissed the Chrome sign in dialog for
+    // extensions.
+    waiting_on_account_ = false;
+    scoped_identity_manager_observation_.Reset();
+    CompleteFunctionWithError(IdentityGetAuthTokenError(
+        IdentityGetAuthTokenError::State::kSignInFailed));
+    return;
+  }
+  // Note: We rely on `OnPrimaryAccountChanged()` to detect that Chrome is
+  // signed in.
+}
+#endif
+
 void IdentityGetAuthTokenFunction::ShowExtensionLoginPrompt() {
   const CoreAccountInfo& account = token_key_.account_info;
   std::string email_hint = account.IsEmpty()
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h
index 3b79048..108bd69 100644
--- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h
+++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.h
@@ -224,6 +224,14 @@
   virtual void StartDeviceAccessTokenRequest();
 #endif
 
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+  // This dialog prompts the user to sign in with an account that is already
+  // present in the identity manager. This is different from the signin dialog
+  // shown when there are no accounts in the identity manager.
+  void MaybeShowChromeSigninDialog();
+  void OnChromeSigninDialogDestroyed();
+#endif
+
   // Methods for invoking UI. Overridable for testing.
   virtual void ShowExtensionLoginPrompt();
   virtual void ShowRemoteConsentDialog(
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 daf1e733..b6e8fc7 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
@@ -72,6 +72,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/signin/public/base/signin_metrics.h"
 #include "components/sync/base/features.h"
+#include "components/sync/service/sync_user_settings.h"
 #include "components/url_formatter/elide_url.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/storage_partition.h"
@@ -285,6 +286,37 @@
   return nullptr;
 }
 
+std::string GetGroupIconUrl(const password_manager::AffiliatedGroup& group,
+                            const syncer::SyncService* sync_service) {
+  if (!sync_service) {
+    return group.GetFallbackIconURL().spec();
+  }
+
+  if (sync_service->GetUserSettings()->IsUsingExplicitPassphrase()) {
+    // Users with explicit passphrase should only use fallback icon.
+    return group.GetFallbackIconURL().spec();
+  }
+
+  // TODO(crbug.com/40067296): Migrate away from `ConsentLevel::kSync` on
+  // desktop platforms.
+  if (password_manager::sync_util::IsSyncFeatureEnabledIncludingPasswords(
+          sync_service)) {
+    // Syncing users can use icon provided by the affiliation service.
+    return group.GetIconURL().spec();
+  }
+
+  for (const CredentialUIEntry& credential : group.GetCredentials()) {
+    if (credential.stored_in.contains(
+            password_manager::PasswordForm::Store::kAccountStore)) {
+      // If at least one credential is stored in the account, icon provided by
+      // the affiliation service can be used for the whole group.
+      return group.GetIconURL().spec();
+    }
+  }
+
+  return group.GetFallbackIconURL().spec();
+}
+
 }  // namespace
 
 namespace extensions {
@@ -372,19 +404,14 @@
 PasswordsPrivateDelegate::CredentialsGroups
 PasswordsPrivateDelegateImpl::GetCredentialGroups() {
   std::vector<api::passwords_private::CredentialGroup> groups;
-  // TODO(crbug.com/40067296): Migrate away from `ConsentLevel::kSync` on
-  // desktop platforms.
-  bool sync_enabled =
-      password_manager::sync_util::IsSyncFeatureEnabledIncludingPasswords(
-          SyncServiceFactory::GetForProfile(profile_));
   for (const password_manager::AffiliatedGroup& group :
        saved_passwords_presenter_.GetAffiliatedGroups()) {
     api::passwords_private::CredentialGroup group_api;
     group_api.name = group.GetDisplayName();
-    group_api.icon_url = sync_enabled ? group.GetIconURL().spec()
-                                      : group.GetFallbackIconURL().spec();
+    group_api.icon_url =
+        GetGroupIconUrl(group, SyncServiceFactory::GetForProfile(profile_));
 
-    DCHECK(!group.GetCredentials().empty());
+    CHECK(!group.GetCredentials().empty());
     for (const CredentialUIEntry& credential : group.GetCredentials()) {
       group_api.entries.push_back(
           CreatePasswordUiEntryFromCredentialUiEntry(credential));
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc
index 5ce1bff9..28c1af3 100644
--- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc
+++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc
@@ -432,6 +432,8 @@
     return web_contents;
   }
 
+  syncer::TestSyncService* SyncService();
+
  protected:
   raw_ptr<extensions::TestEventRouter, DanglingUntriaged> event_router_ =
       nullptr;
@@ -521,6 +523,11 @@
   return result;
 }
 
+syncer::TestSyncService* PasswordsPrivateDelegateImplTest::SyncService() {
+  return static_cast<syncer::TestSyncService*>(
+      SyncServiceFactory::GetForProfile(profile()));
+}
+
 TEST_F(PasswordsPrivateDelegateImplTest, GetSavedPasswordsList) {
   auto delegate = CreateDelegate();
 
@@ -2212,4 +2219,64 @@
   task_environment()->RunUntilIdle();
 }
 
+TEST_F(PasswordsPrivateDelegateImplTest, GetCredentialGroups_SyncOn) {
+  SyncService()->SetHasSyncConsent(true);
+
+  auto delegate = CreateDelegate();
+
+  PasswordForm password =
+      CreateSampleForm(PasswordForm::Store::kProfileStore, u"username2");
+
+  SetUpPasswordStores({password});
+
+  auto groups = delegate->GetCredentialGroups();
+  EXPECT_EQ(1u, groups.size());
+  EXPECT_EQ(1u, groups[0].entries.size());
+  EXPECT_EQ("abc1.com", groups[0].name);
+  EXPECT_EQ(
+      "https://t1.gstatic.com/"
+      "faviconV2?client=PASSWORD_MANAGER&type=FAVICON&fallback_opts=TYPE,SIZE,"
+      "URL,TOP_DOMAIN&size=32&url=https%3A%2F%2Fabc1.com%2F",
+      groups[0].icon_url);
+}
+
+TEST_F(PasswordsPrivateDelegateImplTest, GetCredentialGroups_SyncOff) {
+  auto delegate = CreateDelegate();
+
+  PasswordForm password =
+      CreateSampleForm(PasswordForm::Store::kProfileStore, u"username2");
+
+  SetUpPasswordStores({password});
+
+  auto groups = delegate->GetCredentialGroups();
+  EXPECT_EQ(1u, groups.size());
+  EXPECT_EQ(1u, groups[0].entries.size());
+  EXPECT_EQ("abc1.com", groups[0].name);
+  EXPECT_EQ("https://abc1.com/favicon.ico", groups[0].icon_url);
+}
+
+TEST_F(PasswordsPrivateDelegateImplTest, GetCredentialGroups_Butter) {
+  signin::IdentityTestEnvironment identity_test_env_;
+  identity_test_env_.MakePrimaryAccountAvailable("test@email.com",
+                                                 signin::ConsentLevel::kSignin);
+  identity_test_env_.SetAutomaticIssueOfAccessTokens(true);
+
+  auto delegate = CreateDelegate();
+
+  PasswordForm password =
+      CreateSampleForm(PasswordForm::Store::kAccountStore, u"username2");
+
+  SetUpPasswordStores({password});
+
+  auto groups = delegate->GetCredentialGroups();
+  EXPECT_EQ(1u, groups.size());
+  EXPECT_EQ(1u, groups[0].entries.size());
+  EXPECT_EQ("abc1.com", groups[0].name);
+  EXPECT_EQ(
+      "https://t1.gstatic.com/"
+      "faviconV2?client=PASSWORD_MANAGER&type=FAVICON&fallback_opts=TYPE,SIZE,"
+      "URL,TOP_DOMAIN&size=32&url=https%3A%2F%2Fabc1.com%2F",
+      groups[0].icon_url);
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/facilitated_payments/ui/android/internal/BUILD.gn b/chrome/browser/facilitated_payments/ui/android/internal/BUILD.gn
index f5c70a1..e8e56ac 100644
--- a/chrome/browser/facilitated_payments/ui/android/internal/BUILD.gn
+++ b/chrome/browser/facilitated_payments/ui/android/internal/BUILD.gn
@@ -37,6 +37,7 @@
     "//chrome/browser/touch_to_fill/common/android:java_resources",
     "//components/autofill/android:payments_autofill_java",
     "//components/browser_ui/bottomsheet/android:java",
+    "//components/payments/content/android:java",
     "//content/public/android:content_full_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_appcompat_appcompat_resources_java",
@@ -95,6 +96,7 @@
     ":java",
     ":java_resources",
     "//base:base_java_test_support",
+    "//chrome/android:chrome_app_java_resources",
     "//chrome/android:chrome_public_base_module_java_for_test",
     "//chrome/browser/flags:java",
     "//chrome/browser/touch_to_fill/common/android:java_resources",
diff --git a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/BankAccountViewBinder.java b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/BankAccountViewBinder.java
index ab201c6..24c82df 100644
--- a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/BankAccountViewBinder.java
+++ b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/BankAccountViewBinder.java
@@ -7,6 +7,7 @@
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties.BANK_ACCOUNT_DRAWABLE_ID;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties.BANK_ACCOUNT_SUMMARY;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties.BANK_NAME;
+import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties.ON_BANK_ACCOUNT_CLICK_ACTION;
 
 import android.view.LayoutInflater;
 import android.view.View;
@@ -42,6 +43,8 @@
             bankAccountIcon.setImageDrawable(
                     AppCompatResources.getDrawable(
                             view.getContext(), model.get(BANK_ACCOUNT_DRAWABLE_ID)));
+        } else if (propertyKey == ON_BANK_ACCOUNT_CLICK_ACTION) {
+            view.setOnClickListener(unusedView -> model.get(ON_BANK_ACCOUNT_CLICK_ACTION).run());
         } else {
             assert false : "Unhandled update to property:" + propertyKey;
         }
diff --git a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsControllerBridge.java b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsControllerBridge.java
index 7100fd94..72e1289b 100644
--- a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsControllerBridge.java
+++ b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsControllerBridge.java
@@ -35,6 +35,10 @@
         }
     }
 
+    @Override
+    // TODO(b:344904949): Pass click events on the bottomsheet to the fp controller
+    public void onBankAccountSelected(long instrumentId) {}
+
     @NativeMethods
     interface Natives {
         void onDismissed(long nativeFacilitatedPaymentsController);
diff --git a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsControllerRobolectricTest.java b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsControllerRobolectricTest.java
index 5f89ff0..78a64d75 100644
--- a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsControllerRobolectricTest.java
+++ b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsControllerRobolectricTest.java
@@ -16,6 +16,7 @@
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.DISMISS_HANDLER;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.ItemType.ADDITIONAL_INFO;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.ItemType.BANK_ACCOUNT;
+import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.ItemType.CONTINUE_BUTTON;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.ItemType.HEADER;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.SHEET_ITEMS;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.VISIBLE;
@@ -47,6 +48,8 @@
 import org.chromium.ui.modelutil.PropertyModel;
 
 import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
 
 /**
  * Tests for {@link FacilitatedPaymentsPaymentMethodsCoordinator} and {@link
@@ -142,4 +145,27 @@
         assertThat(mFacilitatedPaymentsPaymentMethodsModel.get(VISIBLE), is(false));
         verify(mDelegateMock).onDismissed();
     }
+
+    @Test
+    public void testShowsContinueButtonWhenOneBankAccount() {
+        mCoordinator.showSheet(List.of(BANK_ACCOUNT_1));
+
+        ModelList itemList = mFacilitatedPaymentsPaymentMethodsModel.get(SHEET_ITEMS);
+        assertEquals(getModelsOfType(itemList, CONTINUE_BUTTON).size(), 1);
+    }
+
+    @Test
+    public void testNoContinueButtonWhenManyBankAccounts() {
+        mCoordinator.showSheet(List.of(BANK_ACCOUNT_1, BANK_ACCOUNT_2));
+
+        ModelList itemList = mFacilitatedPaymentsPaymentMethodsModel.get(SHEET_ITEMS);
+        assertEquals(getModelsOfType(itemList, CONTINUE_BUTTON).size(), 0);
+    }
+
+    private static List<PropertyModel> getModelsOfType(ModelList items, int type) {
+        return StreamSupport.stream(items.spliterator(), false)
+                .filter(item -> item.type == type)
+                .map(item -> item.model)
+                .collect(Collectors.toList());
+    }
 }
diff --git a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsCoordinator.java b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsCoordinator.java
index 94212a7..0a5e805 100644
--- a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsCoordinator.java
+++ b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsCoordinator.java
@@ -7,6 +7,7 @@
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.DISMISS_HANDLER;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.ItemType.ADDITIONAL_INFO;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.ItemType.BANK_ACCOUNT;
+import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.ItemType.CONTINUE_BUTTON;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.ItemType.HEADER;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.SHEET_ITEMS;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.VISIBLE;
@@ -87,6 +88,10 @@
                 ADDITIONAL_INFO,
                 FacilitatedPaymentsPaymentMethodsViewBinder::createAdditionalInfoView,
                 FacilitatedPaymentsPaymentMethodsViewBinder::bindAdditionalInfoView);
+        adapter.registerType(
+                CONTINUE_BUTTON,
+                FacilitatedPaymentsPaymentMethodsViewBinder::createContinueButtonView,
+                FacilitatedPaymentsPaymentMethodsViewBinder::bindContinueButtonView);
         view.getSheetItemListView().setAdapter(adapter);
     }
 
diff --git a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsMediator.java b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsMediator.java
index 4438065..4e67a03 100644
--- a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsMediator.java
+++ b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsMediator.java
@@ -8,10 +8,12 @@
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties.BANK_ACCOUNT_DRAWABLE_ID;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties.BANK_ACCOUNT_SUMMARY;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties.BANK_NAME;
+import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties.ON_BANK_ACCOUNT_CLICK_ACTION;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.HeaderProperties.DESCRIPTION_ID;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.HeaderProperties.IMAGE_DRAWABLE_ID;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.HeaderProperties.TITLE_ID;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.ItemType.BANK_ACCOUNT;
+import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.ItemType.CONTINUE_BUTTON;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.SHEET_ITEMS;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.VISIBLE;
 
@@ -26,11 +28,13 @@
 import org.chromium.components.autofill.payments.AccountType;
 import org.chromium.components.autofill.payments.BankAccount;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.StateChangeReason;
+import org.chromium.components.payments.InputProtector;
 import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
 import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
 import org.chromium.ui.modelutil.PropertyModel;
 
 import java.util.List;
+import java.util.stream.StreamSupport;
 
 /**
  * Contains the logic for the facilitated payments component. It sets the state of the model and
@@ -41,6 +45,8 @@
     private PropertyModel mModel;
     private Delegate mDelegate;
 
+    private InputProtector mInputProtector = new InputProtector();
+
     void initialize(Context context, PropertyModel model, Delegate delegate) {
         mContext = context;
         mModel = model;
@@ -55,16 +61,19 @@
         ModelList sheetItems = mModel.get(SHEET_ITEMS);
         sheetItems.clear();
 
-        sheetItems.add(buildHeader());
-
         for (BankAccount bankAccount : bankAccounts) {
             final PropertyModel model = createBankAccountModel(mContext, bankAccount);
             sheetItems.add(new ListItem(BANK_ACCOUNT, model));
         }
 
+        maybeShowContinueButton(sheetItems);
+
         sheetItems.add(buildAdditionalInfo());
 
+        sheetItems.add(0, buildHeader());
+
         mModel.set(VISIBLE, true);
+        mInputProtector.markShowTime();
 
         return true;
     }
@@ -97,18 +106,27 @@
     }
 
     @VisibleForTesting
-    static PropertyModel createBankAccountModel(Context context, BankAccount bankAccount) {
+    PropertyModel createBankAccountModel(Context context, BankAccount bankAccount) {
         PropertyModel.Builder bankAccountModelBuilder =
                 new PropertyModel.Builder(BankAccountProperties.NON_TRANSFORMING_KEYS)
                         .with(BANK_NAME, bankAccount.getBankName())
                         .with(
                                 BANK_ACCOUNT_SUMMARY,
                                 getBankAccountSummaryString(context, bankAccount))
-                        .with(BANK_ACCOUNT_DRAWABLE_ID, R.drawable.ic_account_balance);
+                        .with(BANK_ACCOUNT_DRAWABLE_ID, R.drawable.ic_account_balance)
+                        .with(
+                                ON_BANK_ACCOUNT_CLICK_ACTION,
+                                () -> this.onSelectedBankAccount(bankAccount));
         return bankAccountModelBuilder.build();
     }
 
-    private static String getBankAccountSummaryString(Context context, BankAccount bankAccount) {
+    public void onSelectedBankAccount(BankAccount bankAccount) {
+        if (!mInputProtector.shouldInputBeProcessed()) return;
+        mDelegate.onBankAccountSelected(bankAccount.getInstrumentId());
+    }
+
+    @VisibleForTesting
+    static String getBankAccountSummaryString(Context context, BankAccount bankAccount) {
         return context.getResources()
                 .getString(
                         R.string.settings_pix_bank_account_identifer,
@@ -116,8 +134,8 @@
                         bankAccount.getAccountNumberSuffix());
     }
 
-    private static String getBankAccountTypeString(
-            Context context, @AccountType int bankAccountType) {
+    @VisibleForTesting
+    static String getBankAccountTypeString(Context context, @AccountType int bankAccountType) {
         switch (bankAccountType) {
             case AccountType.CHECKING:
                 return context.getResources().getString(R.string.bank_account_type_checking);
@@ -134,4 +152,20 @@
                 return "";
         }
     }
+
+    private void maybeShowContinueButton(ModelList sheetItems) {
+        if (StreamSupport.stream(sheetItems.spliterator(), false)
+                        .filter(item -> item.type == BANK_ACCOUNT)
+                        .count()
+                != 1) {
+            return;
+        }
+        PropertyModel model =
+                StreamSupport.stream(sheetItems.spliterator(), false)
+                        .filter(item -> item.type == BANK_ACCOUNT)
+                        .findFirst()
+                        .get()
+                        .model;
+        sheetItems.add(new ListItem(CONTINUE_BUTTON, model));
+    }
 }
diff --git a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsProperties.java b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsProperties.java
index c3ebc0a3..4d1b389 100644
--- a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsProperties.java
+++ b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsProperties.java
@@ -34,6 +34,10 @@
         // Additional info to users making payments through bottom sheet.
         int ADDITIONAL_INFO = 2;
 
+        // A "Continue" button, which is shown when there is only one payment
+        // method available.
+        int CONTINUE_BUTTON = 3;
+
         // A footer section containing additional actions.
         int FOOTER = 3;
     }
@@ -46,9 +50,11 @@
                 new ReadableObjectPropertyKey("bank_account_summary");
         static final ReadableIntPropertyKey BANK_ACCOUNT_DRAWABLE_ID =
                 new ReadableIntPropertyKey("bank_account_drawable_id");
+        static final ReadableObjectPropertyKey<Runnable> ON_BANK_ACCOUNT_CLICK_ACTION =
+                new ReadableObjectPropertyKey<>("on_bank_account_click_action");
 
         static final PropertyKey[] NON_TRANSFORMING_KEYS = {
-            BANK_NAME, BANK_ACCOUNT_SUMMARY, BANK_ACCOUNT_DRAWABLE_ID
+            BANK_NAME, BANK_ACCOUNT_SUMMARY, BANK_ACCOUNT_DRAWABLE_ID, ON_BANK_ACCOUNT_CLICK_ACTION
         };
 
         private BankAccountProperties() {}
diff --git a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsViewBinder.java b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsViewBinder.java
index 3453edd8..5c6ac4c9 100644
--- a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsViewBinder.java
+++ b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsViewBinder.java
@@ -5,6 +5,10 @@
 package org.chromium.chrome.browser.facilitated_payments;
 
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.AdditionalInfoProperties.DESCRIPTION_1_ID;
+import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties.BANK_ACCOUNT_DRAWABLE_ID;
+import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties.BANK_ACCOUNT_SUMMARY;
+import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties.BANK_NAME;
+import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties.ON_BANK_ACCOUNT_CLICK_ACTION;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.DISMISS_HANDLER;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.HeaderProperties.DESCRIPTION_ID;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.HeaderProperties.IMAGE_DRAWABLE_ID;
@@ -121,4 +125,25 @@
             assert false : "Unhandled update to property:" + propertyKey;
         }
     }
+
+    static View createContinueButtonView(ViewGroup parent) {
+        View buttonView =
+                LayoutInflater.from(parent.getContext())
+                        .inflate(R.layout.touch_to_fill_fill_button, parent, false);
+        return buttonView;
+    }
+
+    static void bindContinueButtonView(PropertyModel model, View view, PropertyKey propertyKey) {
+        if (propertyKey == ON_BANK_ACCOUNT_CLICK_ACTION) {
+            view.setOnClickListener(unusedView -> model.get(ON_BANK_ACCOUNT_CLICK_ACTION).run());
+            TextView buttonTitleText = view.findViewById(R.id.touch_to_fill_button_title);
+            buttonTitleText.setText(R.string.autofill_payment_method_continue_button);
+        } else if (propertyKey == BANK_NAME
+                || propertyKey == BANK_ACCOUNT_SUMMARY
+                || propertyKey == BANK_ACCOUNT_DRAWABLE_ID) {
+            // Skip, because none of these changes affect the button
+        } else {
+            assert false : "Unhandled update to property:" + propertyKey;
+        }
+    }
 }
diff --git a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsViewTest.java b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsViewTest.java
index f63cafd9..f218681 100644
--- a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsViewTest.java
+++ b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsViewTest.java
@@ -8,6 +8,10 @@
 
 import static org.hamcrest.Matchers.is;
 
+import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties.BANK_ACCOUNT_DRAWABLE_ID;
+import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties.BANK_ACCOUNT_SUMMARY;
+import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties.BANK_NAME;
+import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties.ON_BANK_ACCOUNT_CLICK_ACTION;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.ItemType.BANK_ACCOUNT;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.SHEET_ITEMS;
 import static org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.VISIBLE;
@@ -28,6 +32,7 @@
 import org.mockito.quality.Strictness;
 
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.chrome.browser.facilitated_payments.FacilitatedPaymentsPaymentMethodsProperties.BankAccountProperties;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
@@ -174,8 +179,17 @@
     }
 
     private PropertyModel createBankAccountModel(BankAccount bankAccount) {
-        return FacilitatedPaymentsPaymentMethodsMediator.createBankAccountModel(
-                mActivityTestRule.getActivity(), bankAccount);
+        PropertyModel.Builder bankAccountModelBuilder =
+                new PropertyModel.Builder(BankAccountProperties.NON_TRANSFORMING_KEYS)
+                        .with(BANK_NAME, bankAccount.getBankName())
+                        .with(
+                                BANK_ACCOUNT_SUMMARY,
+                                FacilitatedPaymentsPaymentMethodsMediator
+                                        .getBankAccountSummaryString(
+                                                mActivityTestRule.getActivity(), bankAccount))
+                        .with(BANK_ACCOUNT_DRAWABLE_ID, R.drawable.ic_account_balance)
+                        .with(ON_BANK_ACCOUNT_CLICK_ACTION, () -> {});
+        return bankAccountModelBuilder.build();
     }
 
     private RecyclerView getBankAccounts() {
diff --git a/chrome/browser/facilitated_payments/ui/android/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsComponent.java b/chrome/browser/facilitated_payments/ui/android/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsComponent.java
index 4a57f325..fa05633 100644
--- a/chrome/browser/facilitated_payments/ui/android/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsComponent.java
+++ b/chrome/browser/facilitated_payments/ui/android/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsComponent.java
@@ -23,6 +23,9 @@
     interface Delegate {
         /** Called whenever the sheet is dismissed. */
         void onDismissed();
+
+        /** Called whenever a bank account is selected. */
+        void onBankAccountSelected(long instrumentId);
     }
 
     /** Initializes the component. */
diff --git a/chrome/browser/facilitated_payments/ui/chrome_facilitated_payments_client.cc b/chrome/browser/facilitated_payments/ui/chrome_facilitated_payments_client.cc
index 3d71df46..b3e187f 100644
--- a/chrome/browser/facilitated_payments/ui/chrome_facilitated_payments_client.cc
+++ b/chrome/browser/facilitated_payments/ui/chrome_facilitated_payments_client.cc
@@ -78,17 +78,12 @@
 bool ChromeFacilitatedPaymentsClient::ShowPixPaymentPrompt(
     base::span<autofill::BankAccount> bank_account_suggestions,
     base::OnceCallback<void(bool, int64_t)> on_user_decision_callback) {
-#if BUILDFLAG(IS_ANDROID)
   return facilitated_payments_controller_->Show(
       &GetWebContents(),
       std::make_unique<
           payments::facilitated::FacilitatedPaymentsBottomSheetBridge>(),
       std::move(bank_account_suggestions),
       std::move(on_user_decision_callback));
-#else
-  // Facilitated Payments is not supported on Desktop.
-  NOTREACHED_NORETURN();
-#endif
 }
 
 void ChromeFacilitatedPaymentsClient::
diff --git a/chrome/browser/facilitated_payments/ui/chrome_facilitated_payments_client.h b/chrome/browser/facilitated_payments/ui/chrome_facilitated_payments_client.h
index 576aefa..4c42ddd7 100644
--- a/chrome/browser/facilitated_payments/ui/chrome_facilitated_payments_client.h
+++ b/chrome/browser/facilitated_payments/ui/chrome_facilitated_payments_client.h
@@ -63,10 +63,8 @@
   std::unique_ptr<payments::facilitated::FacilitatedPaymentsNetworkInterface>
       facilitated_payments_network_interface_;
 
-#if BUILDFLAG(IS_ANDROID)
   std::unique_ptr<FacilitatedPaymentsController>
       facilitated_payments_controller_;
-#endif
 
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 };
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 6faf01d5..660b0242 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -5390,7 +5390,7 @@
   {
       "name": "ipp-first-setup-for-usb-printers",
       "owners": [ "pawliczek@chromium.org", "project-bolton@google.com" ],
-      "expiry_milestone": 125
+      "expiry_milestone": 133
   },
   {
     "name": "isolate-origins",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 3416289..5e64c89 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -3894,12 +3894,6 @@
     "Use chrome passthrough command decoder instead of validating command "
     "decoder.";
 
-const char kUseMultiPlaneFormatForHardwareVideoName[] =
-    "Enable multi-plane formats for hardware video decoder";
-const char kUseMultiPlaneFormatForHardwareVideoDescription[] =
-    "Enable single shared image and mailbox for multi-plane formats for "
-    "hardware video decoder";
-
 const char kUseMultiPlaneFormatForSoftwareVideoName[] =
     "Enable multi-plane formats for software video decoder";
 const char kUseMultiPlaneFormatForSoftwareVideoDescription[] =
@@ -4990,11 +4984,6 @@
     "Have Reading Mode use a local rules based algorithm to include images "
     "from webpages.";
 
-const char kReadAnythingWebUIToolbarName[] = "Reading Mode WebUI Toolbar";
-const char kReadAnythingWebUIToolbarDescription[] =
-    "Enables the Reading Mode toolbar implemented with WebUI instead of with "
-    "Views.";
-
 const char kReadAnythingReadAloudName[] = "Reading Mode Read Aloud";
 const char kReadAnythingReadAloudDescription[] =
     "Enables the experimental Read Aloud feature in Reading Mode.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 534809c..e2b695d 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -2279,9 +2279,6 @@
 extern const char kUsePassthroughCommandDecoderName[];
 extern const char kUsePassthroughCommandDecoderDescription[];
 
-extern const char kUseMultiPlaneFormatForHardwareVideoName[];
-extern const char kUseMultiPlaneFormatForHardwareVideoDescription[];
-
 extern const char kUseMultiPlaneFormatForSoftwareVideoName[];
 extern const char kUseMultiPlaneFormatForSoftwareVideoDescription[];
 
@@ -2905,9 +2902,6 @@
 extern const char kReadAnythingImagesViaAlgorithmName[];
 extern const char kReadAnythingImagesViaAlgorithmDescription[];
 
-extern const char kReadAnythingWebUIToolbarName[];
-extern const char kReadAnythingWebUIToolbarDescription[];
-
 extern const char kReadAnythingReadAloudName[];
 extern const char kReadAnythingReadAloudDescription[];
 
diff --git a/chrome/browser/headless/headless_mode_util.cc b/chrome/browser/headless/headless_mode_util.cc
index fdfeca2..ef813e12 100644
--- a/chrome/browser/headless/headless_mode_util.cc
+++ b/chrome/browser/headless/headless_mode_util.cc
@@ -34,7 +34,7 @@
   kNoHeadlessMode,
   kOldHeadlessMode,
   kNewHeadlessMode,
-  kDefaultHeadlessMode = kOldHeadlessMode
+  kDefaultHeadlessMode = kNewHeadlessMode
 };
 
 HeadlessMode GetHeadlessMode() {
diff --git a/chrome/browser/ip_protection/BUILD.gn b/chrome/browser/ip_protection/BUILD.gn
index f3179d3..4f0258fd 100644
--- a/chrome/browser/ip_protection/BUILD.gn
+++ b/chrome/browser/ip_protection/BUILD.gn
@@ -42,6 +42,7 @@
     "//services/network/public/cpp:cpp",
     "//services/network/public/mojom:mojom",
     "//services/network/public/mojom:url_loader_base",
+    "//third_party/anonymous_tokens:anonymous_tokens_cc_proto",
   ]
 }
 
@@ -70,6 +71,7 @@
     "//net/traffic_annotation:test_support",
     "//services/network:test_support",
     "//testing/gtest:gtest",
+    "//third_party/anonymous_tokens:anonymous_tokens_cc_proto",
   ]
 }
 
@@ -88,6 +90,7 @@
     "//components/privacy_sandbox:features",
     "//components/signin/public/identity_manager:identity_manager",
     "//components/signin/public/identity_manager:test_support",
+    "//third_party/anonymous_tokens:anonymous_tokens_cc_proto",
   ]
 
   if (is_android) {
diff --git a/chrome/browser/ip_protection/ip_protection_config_provider.h b/chrome/browser/ip_protection/ip_protection_config_provider.h
index 6f51d7c..0998479 100644
--- a/chrome/browser/ip_protection/ip_protection_config_provider.h
+++ b/chrome/browser/ip_protection/ip_protection_config_provider.h
@@ -38,6 +38,43 @@
 struct BlindSignToken;
 }  // namespace quiche
 
+// The result of a fetch of tokens from the IP Protection auth token server.
+//
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused. Keep this in sync with
+// IpProtectionTokenBatchRequestResult in enums.xml.
+enum class IpProtectionTryGetAuthTokensResult {
+  // The request was successful and resulted in new tokens.
+  kSuccess = 0,
+  // No primary account is set.
+  kFailedNoAccount = 1,
+  // Chrome determined the primary account is not eligible.
+  kFailedNotEligible = 2,
+  // There was a failure fetching an OAuth token for the primary account.
+  // Deprecated in favor of `kFailedOAuthToken{Transient,Persistent}`.
+  kFailedOAuthTokenDeprecated = 3,
+  // There was a failure in BSA with the given status code.
+  kFailedBSA400 = 4,
+  kFailedBSA401 = 5,
+  kFailedBSA403 = 6,
+
+  // Any other issue calling BSA.
+  kFailedBSAOther = 7,
+
+  // There was a transient failure fetching an OAuth token for the primary
+  // account.
+  kFailedOAuthTokenTransient = 8,
+  // There was a persistent failure fetching an OAuth token for the primary
+  // account.
+  kFailedOAuthTokenPersistent = 9,
+
+  // The attempt to request tokens failed because IP Protection was disabled by
+  // the user.
+  kFailedDisabledByUser = 10,
+
+  kMaxValue = kFailedDisabledByUser,
+};
+
 // Fetches IP protection tokens on demand for the network service.
 //
 // This class handles both requesting OAuth2 tokens for the signed-in user, and
diff --git a/chrome/browser/ip_protection/ip_protection_config_provider_browsertest.cc b/chrome/browser/ip_protection/ip_protection_config_provider_browsertest.cc
index c8adcea..a154a57 100644
--- a/chrome/browser/ip_protection/ip_protection_config_provider_browsertest.cc
+++ b/chrome/browser/ip_protection/ip_protection_config_provider_browsertest.cc
@@ -609,16 +609,8 @@
       profile_selections_;
 };
 
-// TODO(https://crbug.com/328624105): These policy tests are flaky on Android.
-// Re-enable them once the root cause has been determined.
-#if BUILDFLAG(IS_ANDROID)
-#define MAYBE(test) DISABLED_##test
-#else
-#define MAYBE(test) test
-#endif
-
 IN_PROC_BROWSER_TEST_F(IpProtectionConfigProviderPolicyBrowserTest,
-                       MAYBE(IpProtectionEnterprisePolicyDisableAndEnable)) {
+                       IpProtectionEnterprisePolicyDisableAndEnable) {
   IpProtectionConfigProvider* provider =
       IpProtectionConfigProvider::Get(GetProfile());
 
@@ -639,7 +631,7 @@
 // pref value should no longer be considered managed and should effectively be
 // reset to its initial state.
 IN_PROC_BROWSER_TEST_F(IpProtectionConfigProviderPolicyBrowserTest,
-                       MAYBE(IpProtectionEnterprisePolicyUnsetAfterSet)) {
+                       IpProtectionEnterprisePolicyUnsetAfterSet) {
   IpProtectionConfigProvider* provider =
       IpProtectionConfigProvider::Get(GetProfile());
 
diff --git a/chrome/browser/ip_protection/ip_protection_config_provider_unittest.cc b/chrome/browser/ip_protection/ip_protection_config_provider_unittest.cc
index 0ebd1155..c0f39a7 100644
--- a/chrome/browser/ip_protection/ip_protection_config_provider_unittest.cc
+++ b/chrome/browser/ip_protection/ip_protection_config_provider_unittest.cc
@@ -7,7 +7,6 @@
 #include <memory>
 #include <optional>
 
-#include "base/base64.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/notreached.h"
 #include "base/test/bind.h"
@@ -44,35 +43,6 @@
 
 constexpr char kTestEmail[] = "test@example.com";
 
-privacy::ppn::PrivacyPassTokenData CreateMockPrivacyPassToken(
-    std::string token_value) {
-  privacy::ppn::PrivacyPassTokenData privacy_pass_token_data;
-
-  // The PrivacyPassTokenData values get base64-encoded by BSA, so simulate that
-  // here.
-  std::string encoded_token_value = base::Base64Encode(token_value);
-  std::string encoded_extension_value =
-      base::Base64Encode("mock-extension-value");
-
-  privacy_pass_token_data.set_token(std::move(encoded_token_value));
-  privacy_pass_token_data.set_encoded_extensions(
-      std::move(encoded_extension_value));
-
-  return privacy_pass_token_data;
-}
-
-// Creates a `quiche::BlindSignToken()` in the format that the BSA library
-// will return them.
-quiche::BlindSignToken CreateMockBlindSignToken(std::string token_value,
-                                                base::Time expiration) {
-  privacy::ppn::PrivacyPassTokenData privacy_pass_token_data =
-      CreateMockPrivacyPassToken(std::move(token_value));
-  quiche::BlindSignToken blind_sign_token;
-  blind_sign_token.token = privacy_pass_token_data.SerializeAsString();
-  blind_sign_token.expiration = absl::FromTimeT(expiration.ToTimeT());
-  return blind_sign_token;
-}
-
 class MockBlindSignAuth : public quiche::BlindSignAuthInterface {
  public:
   void GetTokens(std::optional<std::string> oauth_token,
@@ -317,32 +287,8 @@
     }
   }
 
-  // Shortcut to create a ProxyChain from hostnames.
-  net::ProxyChain MakeChain(
-      std::vector<std::string> hostnames,
-      int chain_id = net::ProxyChain::kDefaultIpProtectionChainId) {
-    std::vector<net::ProxyServer> servers;
-    for (auto& hostname : hostnames) {
-      servers.push_back(net::ProxyServer::FromSchemeHostAndPort(
-          net::ProxyServer::SCHEME_HTTPS, hostname, std::nullopt));
-    }
-    return net::ProxyChain::ForIpProtection(servers, chain_id);
-  }
-
   sync_preferences::TestingPrefServiceSyncable* prefs() { return &prefs_; }
 
-  // Converts a mock token value and expiration time into the struct that will
-  // be passed to the network service, including the formatting that the
-  // `IpProtectionConfigProvider()` will do.
-  static network::mojom::BlindSignedAuthTokenPtr CreateMockBlindSignedAuthToken(
-      std::string token_value,
-      base::Time expiration) {
-    quiche::BlindSignToken blind_sign_token =
-        CreateMockBlindSignToken(token_value, expiration);
-    return IpProtectionConfigProviderHelper::CreateBlindSignedAuthToken(
-        std::move(blind_sign_token));
-  }
-
   // The behavior of the identity manager.
   PrimaryAccountBehavior primary_account_behavior_ =
       PrimaryAccountBehavior::kReturnsToken;
@@ -388,8 +334,11 @@
 // it.
 TEST_F(IpProtectionConfigProviderTest, Success) {
   primary_account_behavior_ = PrimaryAccountBehavior::kReturnsToken;
-  bsa_->tokens_ = {CreateMockBlindSignToken("single-use-1", expiration_time_),
-                   CreateMockBlindSignToken("single-use-2", expiration_time_)};
+  bsa_->tokens_ = {
+      IpProtectionConfigProviderHelper::CreateBlindSignTokenForTesting(
+          "single-use-1", expiration_time_),
+      IpProtectionConfigProviderHelper::CreateBlindSignTokenForTesting(
+          "single-use-2", expiration_time_)};
 
   TryGetAuthTokens(2, network::mojom::IpProtectionProxyLayer::kProxyB);
 
@@ -398,10 +347,12 @@
   EXPECT_EQ(bsa_->num_tokens_, 2);
   EXPECT_EQ(bsa_->proxy_layer_, quiche::ProxyLayer::kProxyB);
   std::vector<network::mojom::BlindSignedAuthTokenPtr> expected;
-  expected.push_back(
-      CreateMockBlindSignedAuthToken("single-use-1", expiration_time_));
-  expected.push_back(
-      CreateMockBlindSignedAuthToken("single-use-2", expiration_time_));
+  expected.push_back(IpProtectionConfigProviderHelper::
+                         CreateMockBlindSignedAuthTokenForTesting(
+                             "single-use-1", expiration_time_));
+  expected.push_back(IpProtectionConfigProviderHelper::
+                         CreateMockBlindSignedAuthTokenForTesting(
+                             "single-use-2", expiration_time_));
   ExpectTryGetAuthTokensResult(std::move(expected));
   histogram_tester_.ExpectUniqueSample(
       kTryGetAuthTokensResultHistogram,
@@ -532,8 +483,11 @@
 // The CanUseChromeIpProtection capability is not present (`kUnknown`).
 TEST_F(IpProtectionConfigProviderTest, AccountCapabilityUnknown) {
   primary_account_behavior_ = PrimaryAccountBehavior::kUnknownEligibility;
-  bsa_->tokens_ = {CreateMockBlindSignToken("single-use-1", expiration_time_),
-                   CreateMockBlindSignToken("single-use-2", expiration_time_)};
+  bsa_->tokens_ = {
+      IpProtectionConfigProviderHelper::CreateBlindSignTokenForTesting(
+          "single-use-1", expiration_time_),
+      IpProtectionConfigProviderHelper::CreateBlindSignTokenForTesting(
+          "single-use-2", expiration_time_)};
 
   TryGetAuthTokens(2, network::mojom::IpProtectionProxyLayer::kProxyA);
 
@@ -542,10 +496,12 @@
   EXPECT_EQ(bsa_->num_tokens_, 2);
   EXPECT_EQ(bsa_->proxy_layer_, quiche::ProxyLayer::kProxyA);
   std::vector<network::mojom::BlindSignedAuthTokenPtr> expected;
-  expected.push_back(
-      CreateMockBlindSignedAuthToken("single-use-1", expiration_time_));
-  expected.push_back(
-      CreateMockBlindSignedAuthToken("single-use-2", expiration_time_));
+  expected.push_back(IpProtectionConfigProviderHelper::
+                         CreateMockBlindSignedAuthTokenForTesting(
+                             "single-use-1", expiration_time_));
+  expected.push_back(IpProtectionConfigProviderHelper::
+                         CreateMockBlindSignedAuthTokenForTesting(
+                             "single-use-2", expiration_time_));
   ExpectTryGetAuthTokensResult(std::move(expected));
   histogram_tester_.ExpectUniqueSample(
       kTryGetAuthTokensResultHistogram,
@@ -629,7 +585,9 @@
   ExpectTryGetAuthTokensResultFailed(base::TimeDelta::Max());
 
   primary_account_behavior_ = PrimaryAccountBehavior::kReturnsToken;
-  bsa_->tokens_ = {CreateMockBlindSignToken("single-use-1", expiration_time_)};
+  bsa_->tokens_ = {
+      IpProtectionConfigProviderHelper::CreateBlindSignTokenForTesting(
+          "single-use-1", expiration_time_)};
 
   TryGetAuthTokens(1, network::mojom::IpProtectionProxyLayer::kProxyA);
 
@@ -667,7 +625,9 @@
       account_info.account_id,
       GoogleServiceAuthError(GoogleServiceAuthError::State::NONE));
 
-  bsa_->tokens_ = {CreateMockBlindSignToken("single-use-1", expiration_time_)};
+  bsa_->tokens_ = {
+      IpProtectionConfigProviderHelper::CreateBlindSignTokenForTesting(
+          "single-use-1", expiration_time_)};
   tokens_future.Clear();
   getter_->TryGetAuthTokens(1, network::mojom::IpProtectionProxyLayer::kProxyB,
                             tokens_future.GetCallback());
@@ -753,7 +713,10 @@
   getter_->GetProxyList(proxy_list_future_.GetCallback());
   ASSERT_TRUE(proxy_list_future_.Wait()) << "GetProxyList did not call back";
   std::vector<net::ProxyChain> exp_proxy_list = {
-      MakeChain({"proxy1", "proxy1b"}, 1), MakeChain({"proxy2", "proxy2b"}, 2)};
+      IpProtectionConfigProviderHelper::MakeChainForTesting(
+          {"proxy1", "proxy1b"}, 1),
+      IpProtectionConfigProviderHelper::MakeChainForTesting(
+          {"proxy2", "proxy2b"}, 2)};
   EXPECT_THAT(proxy_list_future_.Get(),
               testing::Optional(testing::ElementsAreArray(exp_proxy_list)));
 }
@@ -782,7 +745,8 @@
   getter_->GetProxyList(proxy_list_future_.GetCallback());
   ASSERT_TRUE(proxy_list_future_.Wait()) << "GetProxyList did not call back";
   std::vector<net::ProxyChain> exp_proxy_list = {
-      MakeChain({"proxy1", "proxy1b"})};
+      IpProtectionConfigProviderHelper::MakeChainForTesting(
+          {"proxy1", "proxy1b"})};
   exp_proxy_list.push_back(net::ProxyChain::ForIpProtection(
       {net::ProxyServer::FromSchemeHostAndPort(net::ProxyServer::SCHEME_HTTPS,
                                                "proxy2", 80),
@@ -817,7 +781,9 @@
 
   getter_->GetProxyList(proxy_list_future_.GetCallback());
   ASSERT_TRUE(proxy_list_future_.Wait()) << "GetProxyList did not call back";
-  std::vector<net::ProxyChain> exp_proxy_list = {MakeChain({"valid", "valid"})};
+  std::vector<net::ProxyChain> exp_proxy_list = {
+      IpProtectionConfigProviderHelper::MakeChainForTesting(
+          {"valid", "valid"})};
   EXPECT_THAT(proxy_list_future_.Get(),
               testing::Optional(testing::ElementsAreArray(exp_proxy_list)));
 }
@@ -840,16 +806,19 @@
   getter_->GetProxyList(proxy_list_future_.GetCallback());
   ASSERT_TRUE(proxy_list_future_.Wait()) << "GetProxyList did not call back";
   // The proxy chain is still used, but the chain ID is set to the default.
-  std::vector<net::ProxyChain> exp_proxy_list = {MakeChain(
-      {"proxya", "proxyb"}, net::ProxyChain::kDefaultIpProtectionChainId)};
+  std::vector<net::ProxyChain> exp_proxy_list = {
+      IpProtectionConfigProviderHelper::MakeChainForTesting(
+          {"proxya", "proxyb"}, net::ProxyChain::kDefaultIpProtectionChainId)};
   EXPECT_THAT(proxy_list_future_.Get(),
               testing::Optional(testing::ElementsAreArray(exp_proxy_list)));
 }
 
 TEST_F(IpProtectionConfigProviderTest, ProxyOverrideFlagsAll) {
   std::vector<net::ProxyChain> proxy_override_list = {
-      MakeChain({"proxyAOverride", "proxyBOverride"}),
-      MakeChain({"proxyAOverride", "proxyBOverride"}),
+      IpProtectionConfigProviderHelper::MakeChainForTesting(
+          {"proxyAOverride", "proxyBOverride"}),
+      IpProtectionConfigProviderHelper::MakeChainForTesting(
+          {"proxyAOverride", "proxyBOverride"}),
   };
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeatureWithParameters(
@@ -988,7 +957,9 @@
 // Do a basic check of the token formats.
 TEST_F(IpProtectionConfigProviderTest, TokenFormat) {
   network::mojom::BlindSignedAuthTokenPtr result =
-      CreateMockBlindSignedAuthToken("single-use-1", expiration_time_);
+      IpProtectionConfigProviderHelper::
+          CreateMockBlindSignedAuthTokenForTesting("single-use-1",
+                                                   expiration_time_);
   std::string token = (*result).token;
   size_t token_position = token.find("PrivateToken token=");
   size_t extensions_position = token.find("extensions=");
diff --git a/chrome/browser/lens/BUILD.gn b/chrome/browser/lens/BUILD.gn
index 292f9f1..d606492 100644
--- a/chrome/browser/lens/BUILD.gn
+++ b/chrome/browser/lens/BUILD.gn
@@ -14,6 +14,7 @@
     "//base:base_java",
     "//chrome/browser/contextmenu:java",
     "//chrome/browser/ui/android/strings:ui_strings_grd",
+    "//components/embedder_support/android:context_menu_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//ui/android:ui_java",
   ]
@@ -38,6 +39,7 @@
     "//base:base_java",
     "//chrome/browser/contextmenu:java",
     "//chrome/browser/ui/android/strings:ui_strings_grd",
+    "//components/embedder_support/android:context_menu_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//ui/android:ui_java",
   ]
diff --git a/chrome/browser/lens/java/src/org/chromium/chrome/browser/lens/LensController.java b/chrome/browser/lens/java/src/org/chromium/chrome/browser/lens/LensController.java
index 2066b5f4..51807fb 100644
--- a/chrome/browser/lens/java/src/org/chromium/chrome/browser/lens/LensController.java
+++ b/chrome/browser/lens/java/src/org/chromium/chrome/browser/lens/LensController.java
@@ -6,7 +6,7 @@
 import androidx.annotation.NonNull;
 
 import org.chromium.base.Callback;
-import org.chromium.chrome.browser.contextmenu.ChipRenderParams;
+import org.chromium.components.embedder_support.contextmenu.ChipRenderParams;
 import org.chromium.ui.base.WindowAndroid;
 
 /** A class which manages communication with the Lens SDK. */
diff --git a/chrome/browser/lens/java/src/org/chromium/chrome/browser/lens/LensControllerDelegate.java b/chrome/browser/lens/java/src/org/chromium/chrome/browser/lens/LensControllerDelegate.java
index c324bc3..c137bb4e 100644
--- a/chrome/browser/lens/java/src/org/chromium/chrome/browser/lens/LensControllerDelegate.java
+++ b/chrome/browser/lens/java/src/org/chromium/chrome/browser/lens/LensControllerDelegate.java
@@ -13,16 +13,18 @@
 import androidx.annotation.StringRes;
 
 import org.chromium.base.Callback;
-import org.chromium.chrome.browser.contextmenu.ChipRenderParams;
+import org.chromium.components.embedder_support.contextmenu.ChipRenderParams;
 import org.chromium.ui.base.WindowAndroid;
 
 /**
- * Base class for defining methods where different behavior is required by downstream targets.
- * The correct version of {@link LensControllerDelegateImpl} will be determined at compile time
- * via build rules.
+ * Base class for defining methods where different behavior is required by downstream targets. The
+ * correct version of {@link LensControllerDelegateImpl} will be determined at compile time via
+ * build rules.
  */
 public class LensControllerDelegate {
-    /** @see {@link LensController#isSdkAvailable()} */
+    /**
+     * @see {@link LensController#isSdkAvailable()}
+     */
     public boolean isSdkAvailable() {
         return false;
     }
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
index 9d6c1ed..fa0c1a9 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -1105,7 +1105,7 @@
       base::MakeRefCounted<safe_browsing::TestSafeBrowsingUIManager>();
   security_interstitials::UnsafeResource resource;
   safe_browsing::SafeBrowsingUserInteractionObserver::CreateForWebContents(
-      test_web_contents.get(), resource, /* is_main_frame= */ true, ui_manager);
+      test_web_contents.get(), resource, ui_manager);
   autofill::ChromeAutofillClient::CreateForWebContents(test_web_contents.get());
   MockChromePasswordManagerClient* client =
       MockChromePasswordManagerClient::CreateForWebContentsAndGet(
diff --git a/chrome/browser/payments/journey_logger_browsertest.cc b/chrome/browser/payments/journey_logger_browsertest.cc
index 7ba4eb2..3e0f82f 100644
--- a/chrome/browser/payments/journey_logger_browsertest.cc
+++ b/chrome/browser/payments/journey_logger_browsertest.cc
@@ -11,6 +11,10 @@
 
 namespace payments {
 
+namespace {
+using Event2 = payments::JourneyLogger::Event2;
+}  // namespace
+
 class JourneyLoggerTest : public PaymentRequestPlatformBrowserTestBase {
  public:
   JourneyLoggerTest() : gpay_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
@@ -70,14 +74,6 @@
   EXPECT_THAT(eval_js_result.ExtractString(),
               testing::StartsWith("NotSupportedError"));
 
-  std::vector<base::Bucket> buckets =
-      histogram_tester.GetAllSamples("PaymentRequest.Events");
-  ASSERT_EQ(1U, buckets.size());
-  EXPECT_FALSE(buckets[0].min &
-               JourneyLogger::EVENT_AVAILABLE_METHOD_BASIC_CARD);
-  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_AVAILABLE_METHOD_GOOGLE);
-  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_AVAILABLE_METHOD_OTHER);
-
   // Verify recorded checkout steps.
   histogram_tester.ExpectBucketCount(
       "PaymentRequest.CheckoutFunnel",
@@ -110,12 +106,11 @@
 
   // Make sure the events were logged correctly.
   std::vector<base::Bucket> buckets =
-      histogram_tester.GetAllSamples("PaymentRequest.Events");
+      histogram_tester.GetAllSamples("PaymentRequest.Events2");
   ASSERT_EQ(1U, buckets.size());
-  EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_REQUEST_SHIPPING);
-  EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_REQUEST_METHOD_OTHER);
-  EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_COULD_NOT_SHOW);
-  EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_NEEDS_COMPLETION_PAYMENT);
+  EXPECT_TRUE(buckets[0].min & static_cast<int>(Event2::kRequestShipping));
+  EXPECT_TRUE(buckets[0].min & static_cast<int>(Event2::kRequestMethodOther));
+  EXPECT_TRUE(buckets[0].min & static_cast<int>(Event2::kCouldNotShow));
 }
 
 IN_PROC_BROWSER_TEST_F(JourneyLoggerTest, GooglePaymentApp) {
@@ -125,14 +120,6 @@
   EXPECT_EQ("{\"apiVersion\":1}",
             content::EvalJs(GetActiveWebContents(), "testGPay()"));
 
-  std::vector<base::Bucket> buckets =
-      histogram_tester.GetAllSamples("PaymentRequest.Events");
-  ASSERT_EQ(1U, buckets.size());
-  EXPECT_FALSE(buckets[0].min &
-               JourneyLogger::EVENT_AVAILABLE_METHOD_BASIC_CARD);
-  EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_AVAILABLE_METHOD_GOOGLE);
-  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_AVAILABLE_METHOD_OTHER);
-
   // Verify recorded checkout steps.
   histogram_tester.ExpectBucketCount(
       "PaymentRequest.CheckoutFunnel",
diff --git a/chrome/browser/payments/payment_handler_just_in_time_installation_browsertest.cc b/chrome/browser/payments/payment_handler_just_in_time_installation_browsertest.cc
index bd5becd..74861f0e3 100644
--- a/chrome/browser/payments/payment_handler_just_in_time_installation_browsertest.cc
+++ b/chrome/browser/payments/payment_handler_just_in_time_installation_browsertest.cc
@@ -11,6 +11,10 @@
 
 namespace payments {
 
+namespace {
+using Event2 = payments::JourneyLogger::Event2;
+}  // namespace
+
 class PaymentHandlerJustInTimeInstallationTest
     : public PaymentRequestPlatformBrowserTestBase {
  protected:
@@ -122,12 +126,11 @@
       "PaymentRequest.PaymentHandlerInstallSuccess", false, 0);
 
   std::vector<base::Bucket> buckets =
-      histogram_tester.GetAllSamples("PaymentRequest.Events");
+      histogram_tester.GetAllSamples("PaymentRequest.Events2");
   ASSERT_EQ(1U, buckets.size());
-  EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SKIPPED_SHOW);
-  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_SHOWN);
-  EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_AVAILABLE_METHOD_OTHER);
-  EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_SELECTED_OTHER);
+  EXPECT_TRUE(buckets[0].min & static_cast<int>(Event2::kSkippedShow));
+  EXPECT_FALSE(buckets[0].min & static_cast<int>(Event2::kShown));
+  EXPECT_TRUE(buckets[0].min & static_cast<int>(Event2::kSelectedOther));
 }
 
 IN_PROC_BROWSER_TEST_F(PaymentHandlerJustInTimeInstallationTest,
@@ -145,20 +148,6 @@
   // The request is expected to stop at the payment sheet waiting for user
   // action.
   EXPECT_TRUE(content::ExecJs(GetActiveWebContents(), "abort()"));
-
-  std::vector<base::Bucket> buckets =
-      histogram_tester.GetAllSamples("PaymentRequest.Events");
-  ASSERT_EQ(1U, buckets.size());
-
-  // The merchant did not request https://google.com/pay or
-  // https://android.com/pay payment methods and no payment apps were added to
-  // Chrome with these payment method identifiers, so no Google payment
-  // instruments were available for the user to select.
-  EXPECT_FALSE(buckets[0].min & JourneyLogger::EVENT_AVAILABLE_METHOD_GOOGLE);
-
-  // Chrome looks up the JIT installable payment handlers, so these "other"
-  // payment instruments are available for the user to select.
-  EXPECT_TRUE(buckets[0].min & JourneyLogger::EVENT_AVAILABLE_METHOD_OTHER);
 }
 
 }  // namespace payments
diff --git a/chrome/browser/performance_manager/public/user_tuning/performance_detection_manager.h b/chrome/browser/performance_manager/public/user_tuning/performance_detection_manager.h
index 7ac7e995..e39d415c 100644
--- a/chrome/browser/performance_manager/public/user_tuning/performance_detection_manager.h
+++ b/chrome/browser/performance_manager/public/user_tuning/performance_detection_manager.h
@@ -73,6 +73,9 @@
                    base::OnceCallback<void(bool)> post_discard_cb =
                        base::OnceCallback<void(bool)>());
 
+  void NotifyActionableTabObserversForTesting(ResourceType resource_type,
+                                              const ActionableTabsResult& tabs);
+
   // Returns whether a PerformanceDetectionManager was created and installed.
   // Should only return false in unit tests.
   static bool HasInstance();
diff --git a/chrome/browser/performance_manager/user_tuning/performance_detection_manager.cc b/chrome/browser/performance_manager/user_tuning/performance_detection_manager.cc
index 3bad8bfd..553a68bf 100644
--- a/chrome/browser/performance_manager/user_tuning/performance_detection_manager.cc
+++ b/chrome/browser/performance_manager/user_tuning/performance_detection_manager.cc
@@ -92,6 +92,12 @@
                                    std::move(post_discard_cb))));
 }
 
+void PerformanceDetectionManager::NotifyActionableTabObserversForTesting(
+    ResourceType resource_type,
+    const ActionableTabsResult& tabs) {
+  NotifyActionableTabObservers(resource_type, tabs);
+}
+
 // static
 bool PerformanceDetectionManager::HasInstance() {
   return g_performance_detection_manager;
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index bcf31a7..942870a 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -96,6 +96,9 @@
 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
 #include "chrome/browser/ui/webui/policy/policy_ui.h"
 #include "chrome/browser/ui/webui/print_preview/policy_settings.h"
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "chrome/browser/ui/webui/settings/reset_settings_handler.h"
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/updates/announcement_notification/announcement_notification_service.h"
 #include "chrome/browser/user_education/browser_feature_promo_storage_service.h"
 #include "chrome/browser/webauthn/chrome_authenticator_request_delegate.h"
@@ -1908,7 +1911,6 @@
       registry);
   ash::Preferences::RegisterPrefs(registry);
   ash::ResetScreen::RegisterPrefs(registry);
-  settings::ResetSettingsHandler::RegisterLocalStatePrefs(registry);
   ash::SchedulerConfigurationManager::RegisterLocalStatePrefs(registry);
   ash::ServicesCustomizationDocument::RegisterPrefs(registry);
   ash::standalone_browser::migrator_util::RegisterLocalStatePrefs(registry);
@@ -2100,6 +2102,9 @@
   QuietNotificationPermissionUiState::RegisterProfilePrefs(registry);
   RegisterBrowserUserPrefs(registry);
   RegisterPrefersDefaultScrollbarStylesPrefs(registry);
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  settings::ResetSettingsHandler::RegisterProfilePrefs(registry);
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   safe_browsing::file_type::RegisterProfilePrefs(registry);
   safe_browsing::RegisterProfilePrefs(registry);
   SearchPrefetchService::RegisterProfilePrefs(registry);
@@ -3142,18 +3147,6 @@
   syncer::SyncPrefs::MaybeMigratePasswordsToPerAccountPref(profile_prefs);
 #endif  // !BUILDFLAG(IS_ANDROID)
 
-  // Added 06/2024.
-  // crbug.com/40535332.
-#if BUILDFLAG(IS_MAC)
-  if (profile_prefs->HasPrefPath(prefs::kWebKitFixedFontFamily)) {
-    std::string font_name =
-        profile_prefs->GetString(prefs::kWebKitFixedFontFamily);
-    if (font_name == "Osaka") {
-      profile_prefs->ClearPref(prefs::kWebKitFixedFontFamily);
-    }
-  }
-#endif
-
   // Please don't delete the following line. It is used by PRESUBMIT.py.
   // END_MIGRATE_OBSOLETE_PROFILE_PREFS
 
diff --git a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/HistorySyncFragment.java b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/HistorySyncFragment.java
index 9a99a78..0d601a1 100644
--- a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/HistorySyncFragment.java
+++ b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/HistorySyncFragment.java
@@ -37,29 +37,37 @@
     @Override
     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
         mSyncService = SyncServiceFactory.getForProfile(getProfile());
-        mInitialKeepEverythingSynced = mSyncService.hasKeepEverythingSynced();
 
         MaterialSwitchWithText historySyncSwitch = view.findViewById(R.id.history_sync_switch);
         historySyncSwitch.setChecked(PrivacyGuideUtils.isHistorySyncEnabled(getProfile()));
 
         historySyncSwitch.setOnCheckedChangeListener(this);
 
-        if (ChromeFeatureList.isEnabled(
+        if (!ChromeFeatureList.isEnabled(
                 ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS)) {
-            ((TextView) historySyncSwitch.findViewById(R.id.switch_text))
-                    .setText(R.string.privacy_guide_history_and_tabs_sync_toggle);
-            ((PrivacyGuideExplanationItem) view.findViewById(R.id.history_sync_item_one))
-                    .setSummaryText(
-                            getContext()
-                                    .getString(
-                                            R.string.privacy_guide_history_and_tabs_sync_item_one));
+            mInitialKeepEverythingSynced = mSyncService.hasKeepEverythingSynced();
+            return;
         }
+
+        ((TextView) historySyncSwitch.findViewById(R.id.switch_text))
+                .setText(R.string.privacy_guide_history_and_tabs_sync_toggle);
+        ((PrivacyGuideExplanationItem) view.findViewById(R.id.history_sync_item_one))
+                .setSummaryText(
+                        getContext()
+                                .getString(R.string.privacy_guide_history_and_tabs_sync_item_one));
     }
 
     @Override
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
         PrivacyGuideMetricsDelegate.recordMetricsOnHistorySyncChange(isChecked);
 
+        if (ChromeFeatureList.isEnabled(
+                ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS)) {
+            mSyncService.setSelectedType(UserSelectableType.HISTORY, isChecked);
+            mSyncService.setSelectedType(UserSelectableType.TABS, isChecked);
+            return;
+        }
+
         boolean keepEverythingSynced = isChecked && mInitialKeepEverythingSynced;
 
         Set<Integer> syncTypes = mSyncService.getSelectedTypes();
diff --git a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideUtils.java b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideUtils.java
index bc618e7..4e90dfb 100644
--- a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideUtils.java
+++ b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideUtils.java
@@ -7,6 +7,7 @@
 import android.content.Context;
 import android.content.Intent;
 
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.safe_browsing.SafeBrowsingBridge;
@@ -34,7 +35,18 @@
 
     static boolean isHistorySyncEnabled(Profile profile) {
         Set<Integer> syncTypes = SyncServiceFactory.getForProfile(profile).getSelectedTypes();
-        return syncTypes.contains(UserSelectableType.HISTORY);
+
+        if (!ChromeFeatureList.isEnabled(
+                ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS)) {
+            return syncTypes.contains(UserSelectableType.HISTORY);
+        }
+        // The toggle represents both History and Tabs.
+        // History and Tabs should usually have the same value, but in some
+        // cases they may not, e.g. if one of them is disabled by policy. In that
+        // case, show the toggle as on if at least one of them is enabled. The
+        // toggle should reflect the value of the non-disabled type.
+        return syncTypes.contains(UserSelectableType.HISTORY)
+                || syncTypes.contains(UserSelectableType.TABS);
     }
 
     static boolean isUserSignedIn(Profile profile) {
diff --git a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/StepDisplayHandlerImpl.java b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/StepDisplayHandlerImpl.java
index e0958ce..5313f35 100644
--- a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/StepDisplayHandlerImpl.java
+++ b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/StepDisplayHandlerImpl.java
@@ -4,15 +4,19 @@
 
 package org.chromium.chrome.browser.privacy_guide;
 
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.prefetch.settings.PreloadPagesSettingsBridge;
 import org.chromium.chrome.browser.prefetch.settings.PreloadPagesState;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.safe_browsing.SafeBrowsingState;
+import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
 import org.chromium.chrome.browser.sync.SyncServiceFactory;
 import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge;
 import org.chromium.components.content_settings.ContentSettingsType;
 import org.chromium.components.content_settings.CookieControlsMode;
+import org.chromium.components.signin.identitymanager.ConsentLevel;
 import org.chromium.components.sync.SyncService;
+import org.chromium.components.sync.UserSelectableType;
 
 /** Computes for each privacy guide step whether it should be displayed or not. */
 class StepDisplayHandlerImpl implements StepDisplayHandler {
@@ -25,7 +29,31 @@
     @Override
     public boolean shouldDisplayHistorySync() {
         SyncService syncService = SyncServiceFactory.getForProfile(mProfile);
-        return syncService != null && syncService.isSyncFeatureEnabled();
+        if (syncService == null) {
+            return false;
+        }
+        if (!ChromeFeatureList.isEnabled(
+                ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS)) {
+            return syncService.isSyncFeatureEnabled();
+        }
+
+        if (!IdentityServicesProvider.get()
+                .getIdentityManager(mProfile)
+                .hasPrimaryAccount(ConsentLevel.SIGNIN)) {
+            return false;
+        }
+        if (syncService.isSyncDisabledByEnterprisePolicy()) {
+            return false;
+        }
+        if (syncService.isTypeManagedByPolicy(UserSelectableType.HISTORY)
+                && syncService.isTypeManagedByPolicy(UserSelectableType.TABS)) {
+            return false;
+        }
+        if (syncService.isTypeManagedByCustodian(UserSelectableType.HISTORY)
+                && syncService.isTypeManagedByCustodian(UserSelectableType.TABS)) {
+            return false;
+        }
+        return true;
     }
 
     @Override
diff --git a/chrome/browser/privacy_guide/android/junit/src/org/chromium/chrome/browser/privacy_guide/HistorySyncFragmentTest.java b/chrome/browser/privacy_guide/android/junit/src/org/chromium/chrome/browser/privacy_guide/HistorySyncFragmentTest.java
index 6994cc8..dce99b6 100644
--- a/chrome/browser/privacy_guide/android/junit/src/org/chromium/chrome/browser/privacy_guide/HistorySyncFragmentTest.java
+++ b/chrome/browser/privacy_guide/android/junit/src/org/chromium/chrome/browser/privacy_guide/HistorySyncFragmentTest.java
@@ -85,10 +85,14 @@
     }
 
     private void initSyncState(boolean syncAll, boolean historySync) {
-        when(mSyncService.hasKeepEverythingSynced()).thenReturn(syncAll);
+        // With the flag enabled, hasKeepEverythingSynced() will always return false.
+        if (!ChromeFeatureList.isEnabled(
+                ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS)) {
+            when(mSyncService.hasKeepEverythingSynced()).thenReturn(syncAll);
 
-        if (syncAll) {
-            historySync = true;
+            if (syncAll) {
+                historySync = true;
+            }
         }
 
         Set<Integer> syncTypes = new HashSet<>();
@@ -117,6 +121,7 @@
     }
 
     @Test
+    @DisableFeatures({ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS})
     public void testTurnHistorySyncOffWhenSyncAllOn() {
         initFragmentWithSyncState(true, true);
         mHistorySyncButton.performClick();
@@ -125,6 +130,7 @@
     }
 
     @Test
+    @DisableFeatures({ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS})
     public void testTurnHistorySyncOn() {
         initFragmentWithSyncState(false, false);
         mHistorySyncButton.performClick();
@@ -133,6 +139,7 @@
     }
 
     @Test
+    @DisableFeatures({ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS})
     public void testTurnHistorySyncOffThenOnWhenSyncAllOn() {
         initFragmentWithSyncState(true, true);
         mHistorySyncButton.performClick();
@@ -142,6 +149,7 @@
     }
 
     @Test
+    @DisableFeatures({ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS})
     public void testTurnHistorySyncOffThenOnWhenSyncAllOff() {
         initFragmentWithSyncState(false, true);
         mHistorySyncButton.performClick();
@@ -151,6 +159,26 @@
     }
 
     @Test
+    public void testToggleOn() throws Exception {
+        initFragmentWithSyncState(false, false);
+        assertFalse(mHistorySyncButton.isChecked());
+
+        mHistorySyncButton.performClick();
+        verify(mSyncService, times(1)).setSelectedType(eq(UserSelectableType.HISTORY), eq(true));
+        verify(mSyncService, times(1)).setSelectedType(eq(UserSelectableType.TABS), eq(true));
+    }
+
+    @Test
+    public void testToggleOff() throws Exception {
+        initFragmentWithSyncState(false, true);
+        assertTrue(mHistorySyncButton.isChecked());
+
+        mHistorySyncButton.performClick();
+        verify(mSyncService, times(1)).setSelectedType(eq(UserSelectableType.HISTORY), eq(false));
+        verify(mSyncService, times(1)).setSelectedType(eq(UserSelectableType.TABS), eq(false));
+    }
+
+    @Test
     public void testTurnHistorySyncOn_changeHistorySyncOnUserAction() {
         initFragmentWithSyncState(false, false);
         mHistorySyncButton.performClick();
@@ -215,8 +243,7 @@
     }
 
     @Test
-    @EnableFeatures({ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS})
-    public void testStringsWhenReplaceSyncPromosWithSignInPromosFlagIsEnabled() throws Exception {
+    public void testStrings() throws Exception {
         initSyncState(true, true);
         mScenario =
                 FragmentScenario.launchInContainer(
@@ -240,4 +267,19 @@
                                             R.string.privacy_guide_history_and_tabs_sync_item_one));
                 });
     }
+
+    @Test
+    public void testToggleAccountsForTabsSync() throws Exception {
+        Set<Integer> syncTypes = new HashSet<>();
+        syncTypes.add(UserSelectableType.TABS);
+        when(mSyncService.getSelectedTypes()).thenReturn(syncTypes);
+        mScenario =
+                FragmentScenario.launchInContainer(
+                        HistorySyncFragment.class, Bundle.EMPTY, R.style.Theme_MaterialComponents);
+        mScenario.onFragment(
+                fragment -> {
+                    mHistorySyncButton = fragment.getView().findViewById(R.id.history_sync_switch);
+                    assertTrue(mHistorySyncButton.isChecked());
+                });
+    }
 }
diff --git a/chrome/browser/privacy_guide/android/junit/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideMetricsDelegateTest.java b/chrome/browser/privacy_guide/android/junit/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideMetricsDelegateTest.java
index 802cc95..bf922326 100644
--- a/chrome/browser/privacy_guide/android/junit/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideMetricsDelegateTest.java
+++ b/chrome/browser/privacy_guide/android/junit/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideMetricsDelegateTest.java
@@ -46,6 +46,7 @@
 
 /** JUnit tests of the class {@link PrivacyGuideMetricsDelegate}. */
 @RunWith(BaseRobolectricTestRunner.class)
+@EnableFeatures({ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS})
 public class PrivacyGuideMetricsDelegateTest {
     private static final String SETTINGS_STATES_HISTOGRAM = "Settings.PrivacyGuide.SettingsStates";
     private static final String NEXT_NAVIGATION_HISTOGRAM = "Settings.PrivacyGuide.NextNavigation";
diff --git a/chrome/browser/privacy_guide/android/junit/src/org/chromium/chrome/browser/privacy_guide/StepDisplayHandlerImplTest.java b/chrome/browser/privacy_guide/android/junit/src/org/chromium/chrome/browser/privacy_guide/StepDisplayHandlerImplTest.java
index 056514b1..e21f7f2 100644
--- a/chrome/browser/privacy_guide/android/junit/src/org/chromium/chrome/browser/privacy_guide/StepDisplayHandlerImplTest.java
+++ b/chrome/browser/privacy_guide/android/junit/src/org/chromium/chrome/browser/privacy_guide/StepDisplayHandlerImplTest.java
@@ -18,11 +18,15 @@
 import org.mockito.junit.MockitoRule;
 
 import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.Features.DisableFeatures;
+import org.chromium.base.test.util.Features.EnableFeatures;
 import org.chromium.base.test.util.JniMocker;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.safe_browsing.SafeBrowsingBridge;
 import org.chromium.chrome.browser.safe_browsing.SafeBrowsingBridgeJni;
 import org.chromium.chrome.browser.safe_browsing.SafeBrowsingState;
+import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
 import org.chromium.chrome.browser.sync.SyncServiceFactory;
 import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge;
 import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridgeJni;
@@ -30,7 +34,10 @@
 import org.chromium.components.content_settings.CookieControlsMode;
 import org.chromium.components.content_settings.PrefNames;
 import org.chromium.components.prefs.PrefService;
+import org.chromium.components.signin.identitymanager.ConsentLevel;
+import org.chromium.components.signin.identitymanager.IdentityManager;
 import org.chromium.components.sync.SyncService;
+import org.chromium.components.sync.UserSelectableType;
 import org.chromium.components.user_prefs.UserPrefs;
 import org.chromium.components.user_prefs.UserPrefsJni;
 
@@ -39,6 +46,7 @@
  * compressed if @ParameterizedTest from JUnit5 can be used.
  */
 @RunWith(BaseRobolectricTestRunner.class)
+@EnableFeatures({ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS})
 public class StepDisplayHandlerImplTest {
     @Rule public JniMocker mMocker = new JniMocker();
     @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
@@ -46,6 +54,8 @@
     @Mock private SafeBrowsingBridge.Natives mSBNativesMock;
     @Mock private SyncService mSyncService;
     @Mock private Profile mProfile;
+    @Mock private IdentityServicesProvider mIdentityServicesProvider;
+    @Mock private IdentityManager mIdentityManager;
     @Mock private PrefService mPrefServiceMock;
     @Mock private UserPrefs.Natives mUserPrefsNativesMock;
     @Mock private WebsitePreferenceBridge.Natives mWebsitePreferenceNativesMock;
@@ -59,6 +69,9 @@
 
         mMocker.mock(WebsitePreferenceBridgeJni.TEST_HOOKS, mWebsitePreferenceNativesMock);
 
+        IdentityServicesProvider.setInstanceForTests(mIdentityServicesProvider);
+        when(mIdentityServicesProvider.getIdentityManager(mProfile)).thenReturn(mIdentityManager);
+
         SyncServiceFactory.setInstanceForTesting(mSyncService);
         mMocker.mock(SafeBrowsingBridgeJni.TEST_HOOKS, mSBNativesMock);
         mStepDisplayHandler = new StepDisplayHandlerImpl(mProfile);
@@ -99,18 +112,75 @@
     }
 
     @Test
+    @DisableFeatures({ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS})
     public void testDisplayHistorySyncWhenSyncOn() {
         setSyncState(true);
         assertTrue(mStepDisplayHandler.shouldDisplayHistorySync());
     }
 
     @Test
+    @DisableFeatures({ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS})
     public void testDontDisplayHistorySyncWhenSyncOff() {
         setSyncState(false);
         assertFalse(mStepDisplayHandler.shouldDisplayHistorySync());
     }
 
     @Test
+    public void testDontDisplayHistorySyncWhenNotSignedIn() {
+        when(mIdentityManager.hasPrimaryAccount(ConsentLevel.SIGNIN)).thenReturn(false);
+        assertFalse(mStepDisplayHandler.shouldDisplayHistorySync());
+    }
+
+    @Test
+    public void testDontDisplayHistorySyncWhenSyncDisabledByEnterprisePolicy() {
+        when(mIdentityManager.hasPrimaryAccount(ConsentLevel.SIGNIN)).thenReturn(true);
+        when(mSyncService.isSyncDisabledByEnterprisePolicy()).thenReturn(true);
+        assertFalse(mStepDisplayHandler.shouldDisplayHistorySync());
+    }
+
+    @Test
+    public void testDontDisplayHistorySyncWhenHistoryAndTabsSyncIsManagedByPolicy() {
+        when(mIdentityManager.hasPrimaryAccount(ConsentLevel.SIGNIN)).thenReturn(true);
+        when(mSyncService.isSyncDisabledByEnterprisePolicy()).thenReturn(false);
+        when(mSyncService.isTypeManagedByPolicy(UserSelectableType.HISTORY)).thenReturn(true);
+        when(mSyncService.isTypeManagedByPolicy(UserSelectableType.TABS)).thenReturn(true);
+        assertFalse(mStepDisplayHandler.shouldDisplayHistorySync());
+    }
+
+    @Test
+    public void testDisplayHistorySyncWhenOnlyHistorySyncIsManagedByPolicy() {
+        when(mIdentityManager.hasPrimaryAccount(ConsentLevel.SIGNIN)).thenReturn(true);
+        when(mSyncService.isSyncDisabledByEnterprisePolicy()).thenReturn(false);
+        when(mSyncService.isTypeManagedByPolicy(UserSelectableType.HISTORY)).thenReturn(true);
+        when(mSyncService.isTypeManagedByPolicy(UserSelectableType.TABS)).thenReturn(false);
+        when(mSyncService.isTypeManagedByCustodian(UserSelectableType.HISTORY)).thenReturn(false);
+        when(mSyncService.isTypeManagedByCustodian(UserSelectableType.TABS)).thenReturn(false);
+        assertTrue(mStepDisplayHandler.shouldDisplayHistorySync());
+    }
+
+    @Test
+    public void testDontDisplayHistorySyncWhenHistoryAndTabsSyncIsManagedByCustodian() {
+        when(mIdentityManager.hasPrimaryAccount(ConsentLevel.SIGNIN)).thenReturn(true);
+        when(mSyncService.isSyncDisabledByEnterprisePolicy()).thenReturn(false);
+        when(mSyncService.isTypeManagedByPolicy(UserSelectableType.HISTORY)).thenReturn(false);
+        when(mSyncService.isTypeManagedByPolicy(UserSelectableType.TABS)).thenReturn(false);
+        when(mSyncService.isTypeManagedByCustodian(UserSelectableType.HISTORY)).thenReturn(true);
+        when(mSyncService.isTypeManagedByCustodian(UserSelectableType.TABS)).thenReturn(true);
+        assertFalse(mStepDisplayHandler.shouldDisplayHistorySync());
+    }
+
+    @Test
+    public void testDisplayHistorySyncWhenOnlyHistorySyncIsManagedByCustodian() {
+        when(mIdentityManager.hasPrimaryAccount(ConsentLevel.SIGNIN)).thenReturn(true);
+        when(mSyncService.isSyncDisabledByEnterprisePolicy()).thenReturn(false);
+        when(mSyncService.isTypeManagedByPolicy(UserSelectableType.HISTORY)).thenReturn(false);
+        when(mSyncService.isTypeManagedByPolicy(UserSelectableType.TABS)).thenReturn(false);
+        when(mSyncService.isTypeManagedByCustodian(UserSelectableType.HISTORY)).thenReturn(true);
+        when(mSyncService.isTypeManagedByCustodian(UserSelectableType.TABS)).thenReturn(false);
+        assertTrue(mStepDisplayHandler.shouldDisplayHistorySync());
+    }
+
+    @Test
     public void testDontDisplayCookiesWhenCookiesAllAllowed() {
         setCookieState(CookieControlsMode.OFF, true);
         assertFalse(mStepDisplayHandler.shouldDisplayCookies());
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
index ecfcab0..d7eddbb 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -1329,9 +1329,6 @@
 #endif
   WebDataServiceFactory::GetInstance();
   webrtc_event_logging::WebRtcEventLogManagerKeyedServiceFactory::GetInstance();
-#if !BUILDFLAG(IS_ANDROID)
-  WebUIContentsPreloadManager::EnsureFactoryBuilt();
-#endif
 }
 
 void ChromeBrowserMainExtraPartsProfiles::PreProfileInit() {
diff --git a/chrome/browser/profiles/profile_keyed_service_browsertest.cc b/chrome/browser/profiles/profile_keyed_service_browsertest.cc
index c8519ab..69075da 100644
--- a/chrome/browser/profiles/profile_keyed_service_browsertest.cc
+++ b/chrome/browser/profiles/profile_keyed_service_browsertest.cc
@@ -641,7 +641,6 @@
     "PermissionsUpdaterShutdownFactory",
     "PluginInfoHostImpl",
     "TurnSyncOnHelperShutdownNotifier",
-    "WebUIContentsPreloadManager",
   };
   // clang-format on
 
@@ -682,7 +681,6 @@
     "PermissionsUpdaterShutdownFactory",
     "PluginInfoHostImpl",
     "TurnSyncOnHelperShutdownNotifier",
-    "WebUIContentsPreloadManager",
   };
   // clang-format on
 
diff --git a/chrome/browser/quick_delete/android/java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteDelegate.java b/chrome/browser/quick_delete/android/java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteDelegate.java
index c2876d2..77a71ea 100644
--- a/chrome/browser/quick_delete/android/java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteDelegate.java
+++ b/chrome/browser/quick_delete/android/java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteDelegate.java
@@ -54,14 +54,12 @@
 
     /**
      * @param {@link Profile} from which to query the syncing history status.
-     *
      * @return A boolean indicating whether the user is syncing history and history deletions are
-     *         propagated.
+     *     propagated.
      */
     static boolean isSyncingHistory(@NonNull Profile profile) {
         SyncService syncService = SyncServiceFactory.getForProfile(profile);
         return syncService != null
-                && syncService.isSyncFeatureEnabled()
                 && syncService.getActiveDataTypes().contains(ModelType.HISTORY_DELETE_DIRECTIVES);
     }
 
diff --git a/chrome/browser/quick_delete/android/javatests/src/org/chromium/chrome/browser/quick_delete/QuickDeleteDialogDelegateTest.java b/chrome/browser/quick_delete/android/javatests/src/org/chromium/chrome/browser/quick_delete/QuickDeleteDialogDelegateTest.java
index 455fd473..f6e7e7e 100644
--- a/chrome/browser/quick_delete/android/javatests/src/org/chromium/chrome/browser/quick_delete/QuickDeleteDialogDelegateTest.java
+++ b/chrome/browser/quick_delete/android/javatests/src/org/chromium/chrome/browser/quick_delete/QuickDeleteDialogDelegateTest.java
@@ -142,7 +142,6 @@
     private void setSyncable(boolean syncable) {
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> {
-                    when(mMockSyncService.isSyncFeatureEnabled()).thenReturn(syncable);
                     when(mMockSyncService.getActiveDataTypes())
                             .thenReturn(
                                     syncable
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/player/mini/MiniPlayerMediator.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/player/mini/MiniPlayerMediator.java
index 84d62f47..b9b9030 100644
--- a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/player/mini/MiniPlayerMediator.java
+++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/player/mini/MiniPlayerMediator.java
@@ -197,7 +197,7 @@
      *
      * @param newState New visibility.
      */
-    public void onTransitionFinished(@VisibilityState int newState) {
+    private void onTransitionFinished(@VisibilityState int newState) {
         mModel.set(Properties.VISIBILITY, newState);
     }
 
@@ -249,6 +249,7 @@
     @Override
     public boolean isVisible() {
         // Consider layer visible even it's during transition.
-        return mModel.get(Properties.VISIBILITY) != VisibilityState.GONE;
+        return mModel.get(Properties.VISIBILITY) == VisibilityState.VISIBLE
+                || mModel.get(Properties.VISIBILITY) == VisibilityState.SHOWING;
     }
 }
diff --git a/chrome/browser/renderer_context_menu/link_to_text_menu_observer.cc b/chrome/browser/renderer_context_menu/link_to_text_menu_observer.cc
index 539430f..4de9ae2 100644
--- a/chrome/browser/renderer_context_menu/link_to_text_menu_observer.cc
+++ b/chrome/browser/renderer_context_menu/link_to_text_menu_observer.cc
@@ -12,6 +12,7 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/time/time.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/enterprise/data_protection/data_protection_clipboard_utils.h"
 #include "chrome/browser/feature_engagement/tracker_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/grit/generated_resources.h"
@@ -22,6 +23,7 @@
 #include "components/shared_highlighting/core/common/fragment_directives_utils.h"
 #include "components/shared_highlighting/core/common/shared_highlighting_features.h"
 #include "content/public/browser/browser_context.h"
+#include "content/public/browser/clipboard_types.h"
 #include "content/public/browser/context_menu_params.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
@@ -377,10 +379,45 @@
   auto* rfh = content::RenderFrameHost::FromID(render_frame_host_id_);
   CHECK(rfh);
 
-  ui::ScopedClipboardWriter scw(
-      ui::ClipboardBuffer::kCopyPaste,
-      std::make_unique<ui::DataTransferEndpoint>(
-          rfh->GetMainFrame()->GetLastCommittedURL(),
-          rfh->GetBrowserContext()->IsOffTheRecord()));
-  scw.WriteText(base::UTF8ToUTF16(text));
+  ui::DataTransferEndpoint dte(rfh->GetMainFrame()->GetLastCommittedURL(),
+                               rfh->GetBrowserContext()->IsOffTheRecord());
+  content::ClipboardEndpoint clipboard_endpoint(
+      dte,
+      base::BindRepeating(
+          [](content::GlobalRenderFrameHostId rfh_id)
+              -> content::BrowserContext* {
+            auto* rfh = content::RenderFrameHost::FromID(rfh_id);
+            if (!rfh) {
+              return nullptr;
+            }
+            return rfh->GetBrowserContext();
+          },
+          rfh->GetGlobalId()),
+      *rfh);
+
+  content::ClipboardPasteData data;
+  data.text = base::UTF8ToUTF16(text);
+  size_t size = data.text.size() * sizeof(std::u16string::value_type);
+
+  enterprise_data_protection::IsClipboardCopyAllowedByPolicy(
+      std::move(clipboard_endpoint),
+      {
+          .size = size,
+          .format_type = ui::ClipboardFormatType::PlainTextType(),
+      },
+      std::move(data),
+      base::BindOnce(
+          [](std::unique_ptr<ui::DataTransferEndpoint> dte,
+             const ui::ClipboardFormatType& data_type,
+             const content::ClipboardPasteData& data,
+             std::optional<std::u16string> replacement_data) {
+            ui::ScopedClipboardWriter scw(ui::ClipboardBuffer::kCopyPaste,
+                                          std::move(dte));
+            if (replacement_data) {
+              scw.WriteText(std::move(*replacement_data));
+            } else {
+              scw.WriteText(data.text);
+            }
+          },
+          std::make_unique<ui::DataTransferEndpoint>(std::move(dte))));
 }
diff --git a/chrome/browser/renderer_context_menu/link_to_text_menu_observer_interactive_uitest.cc b/chrome/browser/renderer_context_menu/link_to_text_menu_observer_interactive_uitest.cc
index 12682f9..f7eefcdf 100644
--- a/chrome/browser/renderer_context_menu/link_to_text_menu_observer_interactive_uitest.cc
+++ b/chrome/browser/renderer_context_menu/link_to_text_menu_observer_interactive_uitest.cc
@@ -6,13 +6,18 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/enterprise/data_controls/data_controls_dialog_test_helper.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/renderer_context_menu/mock_render_view_context_menu.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/chrome_test_utils.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/enterprise/data_controls/features.h"
+#include "components/enterprise/data_controls/test_utils.h"
 #include "components/shared_highlighting/core/common/shared_highlighting_features.h"
 #include "components/shared_highlighting/core/common/shared_highlighting_metrics.h"
 #include "content/public/browser/context_menu_params.h"
@@ -134,6 +139,18 @@
 LinkToTextMenuObserverTest::LinkToTextMenuObserverTest() = default;
 LinkToTextMenuObserverTest::~LinkToTextMenuObserverTest() = default;
 
+class LinkToTextMenuObserverDataControlsTest
+    : public LinkToTextMenuObserverTest {
+ public:
+  LinkToTextMenuObserverDataControlsTest() {
+    scoped_features_.InitAndEnableFeature(
+        data_controls::kEnableDesktopDataControls);
+  }
+
+ protected:
+  base::test::ScopedFeatureList scoped_features_;
+};
+
 }  // namespace
 
 IN_PROC_BROWSER_TEST_F(LinkToTextMenuObserverTest, AddsCopyMenuItem) {
@@ -519,3 +536,138 @@
   EXPECT_EQ(u"http://foo.com/#bar:~:baz=keep&baz=keep2&text=hello%20world",
             text);
 }
+
+IN_PROC_BROWSER_TEST_F(LinkToTextMenuObserverDataControlsTest,
+                       BlocksCopyingLinkToText) {
+  data_controls::SetDataControls(browser()->profile()->GetPrefs(), {R"({
+                                   "name": "rule_name",
+                                   "rule_id": "rule_id",
+                                   "sources": {
+                                     "urls": ["*"]
+                                   },
+                                   "restrictions": [
+                                     {"class": "CLIPBOARD", "level": "BLOCK"}
+                                   ]
+                                 })"});
+  data_controls::DataControlsDialogTestHelper helper(
+      data_controls::DataControlsDialog::Type::kClipboardCopyBlock);
+
+  content::BrowserTestClipboardScope test_clipboard_scope;
+  content::ContextMenuParams params;
+  params.page_url = GURL("http://foo.com/");
+  params.selection_text = u"hello world";
+  observer()->SetGenerationResults(
+      "hello%20world", shared_highlighting::LinkGenerationError::kNone,
+      shared_highlighting::LinkGenerationReadyStatus::kRequestedAfterReady);
+  InitMenu(params);
+  menu()->ExecuteCommand(IDC_CONTENT_CONTEXT_COPYLINKTOTEXT, 0);
+
+  helper.WaitForDialogToInitialize();
+  helper.CancelDialog();
+  helper.WaitForDialogToClose();
+
+  ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
+  std::u16string text;
+  clipboard->ReadText(ui::ClipboardBuffer::kCopyPaste, nullptr, &text);
+  EXPECT_TRUE(text.empty());
+}
+
+IN_PROC_BROWSER_TEST_F(LinkToTextMenuObserverDataControlsTest,
+                       WarnsCopyingLinkToTextAndCancel) {
+  data_controls::SetDataControls(browser()->profile()->GetPrefs(), {R"({
+                                   "name": "rule_name",
+                                   "rule_id": "rule_id",
+                                   "sources": {
+                                     "urls": ["*"]
+                                   },
+                                   "restrictions": [
+                                     {"class": "CLIPBOARD", "level": "WARN"}
+                                   ]
+                                 })"});
+  data_controls::DataControlsDialogTestHelper helper(
+      data_controls::DataControlsDialog::Type::kClipboardCopyWarn);
+
+  content::BrowserTestClipboardScope test_clipboard_scope;
+  content::ContextMenuParams params;
+  params.page_url = GURL("http://foo.com/");
+  params.selection_text = u"hello world";
+  observer()->SetGenerationResults(
+      "hello%20world", shared_highlighting::LinkGenerationError::kNone,
+      shared_highlighting::LinkGenerationReadyStatus::kRequestedAfterReady);
+  InitMenu(params);
+  menu()->ExecuteCommand(IDC_CONTENT_CONTEXT_COPYLINKTOTEXT, 0);
+
+  helper.WaitForDialogToInitialize();
+  helper.CancelDialog();
+  helper.WaitForDialogToClose();
+
+  ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
+  std::u16string text;
+  clipboard->ReadText(ui::ClipboardBuffer::kCopyPaste, nullptr, &text);
+  EXPECT_TRUE(text.empty());
+}
+
+IN_PROC_BROWSER_TEST_F(LinkToTextMenuObserverDataControlsTest,
+                       WarnsCopyingLinkToTextAndBypass) {
+  data_controls::SetDataControls(browser()->profile()->GetPrefs(), {R"({
+                                   "name": "rule_name",
+                                   "rule_id": "rule_id",
+                                   "sources": {
+                                     "urls": ["*"]
+                                   },
+                                   "restrictions": [
+                                     {"class": "CLIPBOARD", "level": "WARN"}
+                                   ]
+                                 })"});
+  data_controls::DataControlsDialogTestHelper helper(
+      data_controls::DataControlsDialog::Type::kClipboardCopyWarn);
+
+  content::BrowserTestClipboardScope test_clipboard_scope;
+  content::ContextMenuParams params;
+  params.page_url = GURL("http://foo.com/");
+  params.selection_text = u"hello world";
+  observer()->SetGenerationResults(
+      "hello%20world", shared_highlighting::LinkGenerationError::kNone,
+      shared_highlighting::LinkGenerationReadyStatus::kRequestedAfterReady);
+  InitMenu(params);
+  menu()->ExecuteCommand(IDC_CONTENT_CONTEXT_COPYLINKTOTEXT, 0);
+
+  helper.WaitForDialogToInitialize();
+  helper.AcceptDialog();
+  helper.WaitForDialogToClose();
+
+  ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
+  std::u16string text;
+  clipboard->ReadText(ui::ClipboardBuffer::kCopyPaste, nullptr, &text);
+  EXPECT_EQ(u"http://foo.com/#:~:text=hello%20world", text);
+}
+
+IN_PROC_BROWSER_TEST_F(LinkToTextMenuObserverDataControlsTest,
+                       ReplacesCopyingLinkToText) {
+  data_controls::SetDataControls(browser()->profile()->GetPrefs(), {R"({
+                                   "name": "rule_name",
+                                   "rule_id": "rule_id",
+                                   "destinations": {
+                                     "os_clipboard": true
+                                   },
+                                   "restrictions": [
+                                     {"class": "CLIPBOARD", "level": "BLOCK"}
+                                   ]
+                                 })"});
+
+  content::BrowserTestClipboardScope test_clipboard_scope;
+  content::ContextMenuParams params;
+  params.page_url = GURL("http://foo.com/");
+  params.selection_text = u"hello world";
+  observer()->SetGenerationResults(
+      "hello%20world", shared_highlighting::LinkGenerationError::kNone,
+      shared_highlighting::LinkGenerationReadyStatus::kRequestedAfterReady);
+  InitMenu(params);
+  menu()->ExecuteCommand(IDC_CONTENT_CONTEXT_COPYLINKTOTEXT, 0);
+
+  ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
+  std::u16string text;
+  clipboard->ReadText(ui::ClipboardBuffer::kCopyPaste, nullptr, &text);
+  EXPECT_EQ(u"Pasting this content here is blocked by your administrator.",
+            text);
+}
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
index 59dfcd28..9b9c274 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -2882,9 +2882,7 @@
     case IDC_CONTENT_CONTEXT_COPYVIDEOFRAME:
     case IDC_CONTENT_CONTEXT_SEARCHLENSFORVIDEOFRAME:
     case IDC_CONTENT_CONTEXT_SEARCHWEBFORVIDEOFRAME:
-      return (params_.media_flags & ContextMenuData::kMediaEncrypted) == 0 &&
-             (params_.media_flags &
-              ContextMenuData::kMediaHasReadableVideoFrame) != 0;
+      return IsVideoFrameItemEnabled(id);
 
     case IDC_CONTENT_CONTEXT_COPYAVLOCATION:
       return params_.src_url.is_valid() && !params_.src_url.SchemeIsBlob();
@@ -3729,6 +3727,10 @@
     return false;
   }
 
+  if (!IsSaveAsItemAllowedByUntrustedNetworkStatus()) {
+    return false;
+  }
+
   return params_.has_image_contents;
 }
 
@@ -3880,6 +3882,17 @@
 #endif  // BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES)
 }
 
+bool RenderViewContextMenu::IsVideoFrameItemEnabled(int id) const {
+  if (id == IDC_CONTENT_CONTEXT_SAVEVIDEOFRAMEAS &&
+      !IsSaveAsItemAllowedByUntrustedNetworkStatus()) {
+    return false;
+  }
+
+  return (params_.media_flags & ContextMenuData::kMediaEncrypted) == 0 &&
+         (params_.media_flags & ContextMenuData::kMediaHasReadableVideoFrame) !=
+             0;
+}
+
 // Returns true if the item was appended.
 bool RenderViewContextMenu::AppendQRCodeGeneratorItem(bool for_image,
                                                       bool draw_icon,
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.h b/chrome/browser/renderer_context_menu/render_view_context_menu.h
index a64338b..2f0fa9a 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.h
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.h
@@ -350,6 +350,7 @@
   bool IsOpenLinkAllowedByDlp(const GURL& link_url) const;
   bool IsRegionSearchEnabled() const;
   bool IsAddANoteEnabled() const;
+  bool IsVideoFrameItemEnabled(int id) const;
 
   // Command execution functions.
   void ExecSearchWebInCompanionSidePanel(const GURL& url);
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
index bb73297c..1455a0a 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -2518,6 +2518,314 @@
               testing::Not(testing::Contains(IDC_CONTENT_CONTEXT_SAVEAVAS)));
 }
 
+IN_PROC_BROWSER_TEST_F(ContextMenuFencedFrameTest,
+                       SaveVideoAsEntryIsDisabledAfterNetworkCutoff) {
+  // Add content/test/data for cross_site_iframe_factory.html
+  https_server()->ServeFilesFromSourceDirectory("content/test/data");
+  ASSERT_TRUE(https_server()->Start());
+
+  // Navigate fenced frame to a page with a video element.
+  GURL fenced_frame_url(
+      https_server()->GetURL("a.test", "/media/video-player-autoplay.html"));
+
+  GURL main_url(https_server()->GetURL(
+      "a.test",
+      base::StringPrintf("/cross_site_iframe_factory.html?a.test(%s{fenced})",
+                         fenced_frame_url.spec().c_str())));
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
+
+  // Get fenced frame render frame host.
+  std::vector<content::RenderFrameHost*> child_frames =
+      fenced_frame_test_helper().GetChildFencedFrameHosts(
+          primary_main_frame_host());
+  ASSERT_EQ(child_frames.size(), 1u);
+  content::RenderFrameHost* fenced_frame_rfh = child_frames[0];
+  ASSERT_EQ(fenced_frame_rfh->GetLastCommittedURL(), fenced_frame_url);
+
+  // To avoid flakiness and ensure fenced_frame_rfh is ready for hit testing.
+  content::WaitForHitTestData(fenced_frame_rfh);
+  content::WaitForLoadStop(
+      content::WebContents::FromRenderFrameHost(fenced_frame_rfh));
+
+  // Click the video inside the fenced frame.
+  const gfx::PointF click_point(15, 15);
+
+  // Open a context menu by right clicking on the video element.
+  ContextMenuWaiter menu_observer;
+  SimulateClickAt(fenced_frame_rfh, blink::WebMouseEvent::Button::kRight,
+                  click_point);
+
+  // Wait for context menu to be visible.
+  menu_observer.WaitForMenuOpenAndClose();
+
+  // "Save Video As..." and "Save Video Frame As..." should be present and
+  // enabled in the context menu.
+  EXPECT_THAT(menu_observer.GetCapturedCommandIds(),
+              testing::IsSupersetOf({IDC_CONTENT_CONTEXT_SAVEAVAS,
+                                     IDC_CONTENT_CONTEXT_SAVEVIDEOFRAMEAS}));
+  EXPECT_THAT(menu_observer.GetCapturedEnabledCommandIds(),
+              testing::IsSupersetOf({IDC_CONTENT_CONTEXT_SAVEAVAS,
+                                     IDC_CONTENT_CONTEXT_SAVEVIDEOFRAMEAS}));
+
+  // Disable fenced frame untrusted network access.
+  ASSERT_TRUE(ExecJs(fenced_frame_rfh, R"(
+    (async () => {
+      return window.fence.disableUntrustedNetwork();
+    })();
+  )"));
+
+  // Open the context menu again.
+  ContextMenuWaiter menu_observer_after_network_cutoff;
+  SimulateClickAt(fenced_frame_rfh, blink::WebMouseEvent::Button::kRight,
+                  click_point);
+
+  // Wait for context menu to be visible.
+  menu_observer_after_network_cutoff.WaitForMenuOpenAndClose();
+
+  // "Save Video As..." and "Save Video Frame As..." should be disabled in the
+  // context menu after fenced frame has untrusted network access revoked.
+  EXPECT_THAT(menu_observer_after_network_cutoff.GetCapturedCommandIds(),
+              testing::IsSupersetOf({IDC_CONTENT_CONTEXT_SAVEAVAS,
+                                     IDC_CONTENT_CONTEXT_SAVEVIDEOFRAMEAS}));
+  EXPECT_THAT(menu_observer_after_network_cutoff.GetCapturedEnabledCommandIds(),
+              testing::Not(testing::Contains(IDC_CONTENT_CONTEXT_SAVEAVAS)));
+  EXPECT_THAT(
+      menu_observer_after_network_cutoff.GetCapturedEnabledCommandIds(),
+      testing::Not(testing::Contains(IDC_CONTENT_CONTEXT_SAVEVIDEOFRAMEAS)));
+}
+
+IN_PROC_BROWSER_TEST_F(
+    ContextMenuFencedFrameTest,
+    SaveVideoAsEntryIsDisabledInNestedIframeAfterNetworkCutoff) {
+  // Add content/test/data for cross_site_iframe_factory.html
+  https_server()->ServeFilesFromSourceDirectory("content/test/data");
+  ASSERT_TRUE(https_server()->Start());
+
+  // Navigate the nested iframe to a page with a video element.
+  GURL nested_iframe_url(
+      https_server()->GetURL("a.test", "/media/video-player-autoplay.html"));
+
+  // The page has a fenced frame with a nested iframe inside.
+  GURL main_url(https_server()->GetURL(
+      "a.test",
+      base::StringPrintf(
+          "/cross_site_iframe_factory.html?a.test(a.test{fenced}(%s))",
+          nested_iframe_url.spec().c_str())));
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
+
+  // Get fenced frame and nested iframe render frame host.
+  std::vector<content::RenderFrameHost*> child_frames =
+      fenced_frame_test_helper().GetChildFencedFrameHosts(
+          primary_main_frame_host());
+  ASSERT_EQ(child_frames.size(), 1u);
+  content::RenderFrameHost* fenced_frame_rfh = child_frames[0];
+  content::RenderFrameHost* nested_iframe_rfh =
+      content::ChildFrameAt(fenced_frame_rfh, 0);
+  ASSERT_EQ(nested_iframe_rfh->GetLastCommittedURL(), nested_iframe_url);
+
+  // To avoid flakiness and ensure fenced_frame_rfh and nested_iframe_rfh is
+  // ready for hit testing.
+  content::WaitForHitTestData(fenced_frame_rfh);
+  content::WaitForHitTestData(nested_iframe_rfh);
+
+  // Click the video inside the fenced frame.
+  gfx::PointF click_point(15, 15);
+
+  // Because the mouse event is forwarded to the `RenderWidgetHost` of the
+  // fenced frame, the click point needs to be offset by the top left
+  // coordinates of the nested iframe relative to the fenced frame.
+  const gfx::PointF iframe_offset =
+      GetTopLeftCoordinatesOfElementWithId(fenced_frame_rfh, "child-0");
+  click_point.Offset(iframe_offset.x(), iframe_offset.y());
+
+  // Open a context menu by right clicking on the video element.
+  ContextMenuWaiter menu_observer;
+  SimulateClickAt(nested_iframe_rfh, blink::WebMouseEvent::Button::kRight,
+                  click_point);
+
+  // Wait for context menu to be visible.
+  menu_observer.WaitForMenuOpenAndClose();
+
+  // "Save Video As..." and "Save Video Frame As..." should be present and
+  // enabled in the context menu.
+  EXPECT_THAT(menu_observer.GetCapturedCommandIds(),
+              testing::IsSupersetOf({IDC_CONTENT_CONTEXT_SAVEAVAS,
+                                     IDC_CONTENT_CONTEXT_SAVEVIDEOFRAMEAS}));
+  EXPECT_THAT(menu_observer.GetCapturedEnabledCommandIds(),
+              testing::IsSupersetOf({IDC_CONTENT_CONTEXT_SAVEAVAS,
+                                     IDC_CONTENT_CONTEXT_SAVEVIDEOFRAMEAS}));
+
+  // Disable fenced frame untrusted network access.
+  ASSERT_TRUE(ExecJs(fenced_frame_rfh, R"(
+    (async () => {
+      return window.fence.disableUntrustedNetwork();
+    })();
+  )"));
+
+  // Open the context menu again.
+  ContextMenuWaiter menu_observer_after_network_cutoff;
+  SimulateClickAt(nested_iframe_rfh, blink::WebMouseEvent::Button::kRight,
+                  click_point);
+
+  // Wait for context menu to be visible.
+  menu_observer_after_network_cutoff.WaitForMenuOpenAndClose();
+
+  // "Save Video As..." and "Save Video Frame As..." should be disabled in the
+  // context menu after fenced frame has untrusted network access revoked.
+  EXPECT_THAT(menu_observer_after_network_cutoff.GetCapturedCommandIds(),
+              testing::IsSupersetOf({IDC_CONTENT_CONTEXT_SAVEAVAS,
+                                     IDC_CONTENT_CONTEXT_SAVEVIDEOFRAMEAS}));
+  EXPECT_THAT(menu_observer_after_network_cutoff.GetCapturedEnabledCommandIds(),
+              testing::Not(testing::Contains(IDC_CONTENT_CONTEXT_SAVEAVAS)));
+  EXPECT_THAT(
+      menu_observer_after_network_cutoff.GetCapturedEnabledCommandIds(),
+      testing::Not(testing::Contains(IDC_CONTENT_CONTEXT_SAVEVIDEOFRAMEAS)));
+}
+
+IN_PROC_BROWSER_TEST_F(ContextMenuFencedFrameTest,
+                       SaveImageAsEntryIsDisabledAfterNetworkCutoff) {
+  // Add content/test/data for cross_site_iframe_factory.html.
+  https_server()->ServeFilesFromSourceDirectory("content/test/data");
+  ASSERT_TRUE(https_server()->Start());
+
+  // Navigate fenced frame to an image.
+  GURL fenced_frame_url(https_server()->GetURL("a.test", "/test_visual.html"));
+
+  GURL main_url(https_server()->GetURL(
+      "a.test",
+      base::StringPrintf("/cross_site_iframe_factory.html?a.test(%s{fenced})",
+                         fenced_frame_url.spec().c_str())));
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
+
+  // Get fenced frame render frame host.
+  std::vector<content::RenderFrameHost*> child_frames =
+      fenced_frame_test_helper().GetChildFencedFrameHosts(
+          primary_main_frame_host());
+  ASSERT_EQ(child_frames.size(), 1u);
+  content::RenderFrameHost* fenced_frame_rfh = child_frames[0];
+  ASSERT_EQ(fenced_frame_rfh->GetLastCommittedURL(), fenced_frame_url);
+
+  // To avoid flakiness and ensure fenced_frame_rfh is ready for hit testing.
+  content::WaitForHitTestData(fenced_frame_rfh);
+
+  // Click inside the fenced frame.
+  const gfx::PointF click_point(15, 15);
+
+  // Open a context menu by right clicking on the image.
+  ContextMenuWaiter menu_observer;
+  SimulateClickAt(fenced_frame_rfh, blink::WebMouseEvent::Button::kRight,
+                  click_point);
+
+  // Wait for context menu to be visible.
+  menu_observer.WaitForMenuOpenAndClose();
+
+  // "Save Image As..." should be present and enabled in the context menu.
+  EXPECT_THAT(menu_observer.GetCapturedEnabledCommandIds(),
+              testing::Contains(IDC_CONTENT_CONTEXT_SAVEIMAGEAS));
+
+  // Disable fenced frame untrusted network access.
+  ASSERT_TRUE(ExecJs(fenced_frame_rfh, R"(
+    (async () => {
+      return window.fence.disableUntrustedNetwork();
+    })();
+  )"));
+
+  // Open the context menu again.
+  ContextMenuWaiter menu_observer_after_network_cutoff;
+  SimulateClickAt(fenced_frame_rfh, blink::WebMouseEvent::Button::kRight,
+                  click_point);
+
+  // Wait for context menu to be visible.
+  menu_observer_after_network_cutoff.WaitForMenuOpenAndClose();
+
+  // "Save Image As..." should be disabled in the context menu after fenced
+  // frame has untrusted network access revoked.
+  EXPECT_THAT(menu_observer_after_network_cutoff.GetCapturedCommandIds(),
+              testing::Contains(IDC_CONTENT_CONTEXT_SAVEIMAGEAS));
+  EXPECT_THAT(menu_observer_after_network_cutoff.GetCapturedEnabledCommandIds(),
+              testing::Not(testing::Contains(IDC_CONTENT_CONTEXT_SAVEIMAGEAS)));
+}
+
+IN_PROC_BROWSER_TEST_F(
+    ContextMenuFencedFrameTest,
+    SaveImageAsEntryIsDisabledInNestedIframeAfterNetworkCutoff) {
+  // Add content/test/data for cross_site_iframe_factory.html.
+  https_server()->ServeFilesFromSourceDirectory("content/test/data");
+  ASSERT_TRUE(https_server()->Start());
+
+  // Navigate the nested iframe to an image.
+  GURL nested_iframe_url(https_server()->GetURL("a.test", "/test_visual.html"));
+
+  // The page has a fenced frame with a nested iframe inside.
+  GURL main_url(https_server()->GetURL(
+      "a.test",
+      base::StringPrintf(
+          "/cross_site_iframe_factory.html?a.test(a.test{fenced}(%s))",
+          nested_iframe_url.spec().c_str())));
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
+
+  // Get fenced frame and nested iframe render frame host.
+  std::vector<content::RenderFrameHost*> child_frames =
+      fenced_frame_test_helper().GetChildFencedFrameHosts(
+          primary_main_frame_host());
+  ASSERT_EQ(child_frames.size(), 1u);
+  content::RenderFrameHost* fenced_frame_rfh = child_frames[0];
+  content::RenderFrameHost* nested_iframe_rfh =
+      content::ChildFrameAt(fenced_frame_rfh, 0);
+  ASSERT_EQ(nested_iframe_rfh->GetLastCommittedURL(), nested_iframe_url);
+
+  // To avoid flakiness and ensure fenced_frame_rfh and nested_iframe_rfh are
+  // ready for hit testing.
+  content::WaitForHitTestData(fenced_frame_rfh);
+  content::WaitForHitTestData(nested_iframe_rfh);
+
+  // Click inside the nested iframe.
+  gfx::PointF click_point(15, 15);
+
+  // Because the mouse event is forwarded to the `RenderWidgetHost` of the
+  // fenced frame, the click point needs to be offset by the top left
+  // coordinates of the nested iframe relative to the fenced frame.
+  const gfx::PointF iframe_offset =
+      GetTopLeftCoordinatesOfElementWithId(fenced_frame_rfh, "child-0");
+  click_point.Offset(iframe_offset.x(), iframe_offset.y());
+
+  // Open a context menu by right clicking on the image.
+  ContextMenuWaiter menu_observer;
+  SimulateClickAt(fenced_frame_rfh, blink::WebMouseEvent::Button::kRight,
+                  click_point);
+
+  // Wait for context menu to be visible.
+  menu_observer.WaitForMenuOpenAndClose();
+
+  // "Save Image As..." should be present and enabled in the context menu.
+  EXPECT_THAT(menu_observer.GetCapturedCommandIds(),
+              testing::Contains(IDC_CONTENT_CONTEXT_SAVEIMAGEAS));
+  EXPECT_THAT(menu_observer.GetCapturedEnabledCommandIds(),
+              testing::Contains(IDC_CONTENT_CONTEXT_SAVEIMAGEAS));
+
+  // Disable fenced frame untrusted network access.
+  ASSERT_TRUE(ExecJs(fenced_frame_rfh, R"(
+    (async () => {
+      return window.fence.disableUntrustedNetwork();
+    })();
+  )"));
+
+  // Open the context menu again.
+  ContextMenuWaiter menu_observer_after_network_cutoff;
+  SimulateClickAt(fenced_frame_rfh, blink::WebMouseEvent::Button::kRight,
+                  click_point);
+
+  // Wait for context menu to be visible.
+  menu_observer_after_network_cutoff.WaitForMenuOpenAndClose();
+
+  // "Save Image As..." should be disabled in the context menu after fenced
+  // frame has untrusted network access revoked.
+  EXPECT_THAT(menu_observer_after_network_cutoff.GetCapturedCommandIds(),
+              testing::Contains(IDC_CONTENT_CONTEXT_SAVEIMAGEAS));
+  EXPECT_THAT(menu_observer_after_network_cutoff.GetCapturedEnabledCommandIds(),
+              testing::Not(testing::Contains(IDC_CONTENT_CONTEXT_SAVEIMAGEAS)));
+}
+
 // TODO(crbug.com/40285326): This fails with the field trial testing config.
 class ContextMenuFencedFrameTestNoTestingConfig
     : public ContextMenuFencedFrameTest {
@@ -2999,17 +3307,9 @@
   loop.Run();
 }
 
-// TODO(crbug.com/346738477): Re-enable the test.
-#if BUILDFLAG(IS_CHROMEOS)
-#define MAYBE_ValidNonGoogleRegionSearchWithUnifiedSidePanelAndSideImageSearch \
-  DISABLED_ValidNonGoogleRegionSearchWithUnifiedSidePanelAndSideImageSearch
-#else
-#define MAYBE_ValidNonGoogleRegionSearchWithUnifiedSidePanelAndSideImageSearch \
-  ValidNonGoogleRegionSearchWithUnifiedSidePanelAndSideImageSearch
-#endif
 IN_PROC_BROWSER_TEST_F(
     SearchByRegionWithUnifiedSidePanelBrowserTest,
-    MAYBE_ValidNonGoogleRegionSearchWithUnifiedSidePanelAndSideImageSearch) {
+    ValidNonGoogleRegionSearchWithUnifiedSidePanelAndSideImageSearch) {
   SetupNonGoogleRegionSearchEngine();
   SetupUnifiedSidePanel();
   // We need a base::RunLoop to ensure that our test does not finish until the
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_button_row.html b/chrome/browser/resources/ash/settings/device_page/customize_button_row.html
index 0eaedc6..0f56768 100644
--- a/chrome/browser/resources/ash/settings/device_page/customize_button_row.html
+++ b/chrome/browser/resources/ash/settings/device_page/customize_button_row.html
@@ -129,7 +129,7 @@
         action-list="[[actionList]]"
         button-remapping-list="{{buttonRemappingList}}"
         remapping-index="[[remappingIndex]]"
-        has-launcher-button="[[hasLauncherButton]]">
+        meta-key="[[metaKey]]">
     </customize-button-select>
   </div>
 </div>
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_button_row.ts b/chrome/browser/resources/ash/settings/device_page/customize_button_row.ts
index 61bcb789d..776ea8df 100644
--- a/chrome/browser/resources/ash/settings/device_page/customize_button_row.ts
+++ b/chrome/browser/resources/ash/settings/device_page/customize_button_row.ts
@@ -24,7 +24,7 @@
 import {setDataTransferOriginIndex} from './drag_and_drop_manager.js';
 import {FakeInputDeviceSettingsProvider} from './fake_input_device_settings_provider.js';
 import {getInputDeviceSettingsProvider} from './input_device_mojo_interface_provider.js';
-import {ActionChoice, Button, ButtonRemapping, InputDeviceSettingsProviderInterface} from './input_device_settings_types.js';
+import {ActionChoice, Button, ButtonRemapping, InputDeviceSettingsProviderInterface, MetaKey} from './input_device_settings_types.js';
 import {buttonsAreEqual} from './input_device_settings_utils.js';
 
 export interface CustomizeButtonRowElement {
@@ -114,9 +114,7 @@
         value: null,
       },
 
-      hasLauncherButton: {
-        type: Boolean,
-      },
+      metaKey: Object,
     };
   }
 
@@ -129,7 +127,7 @@
   buttonRemappingList: ButtonRemapping[];
   remappingIndex: number;
   actionList: ActionChoice[];
-  hasLauncherButton: boolean;
+  metaKey: MetaKey = MetaKey.kSearch;
   private buttonPressObserverReceiver: ButtonPressObserverReceiver;
   private buttonRemapping_: ButtonRemapping;
   private buttonRemappingName_: string;
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_button_select.html b/chrome/browser/resources/ash/settings/device_page/customize_button_select.html
index 4fcf8d8..c0deeb8 100644
--- a/chrome/browser/resources/ash/settings/device_page/customize_button_select.html
+++ b/chrome/browser/resources/ash/settings/device_page/customize_button_select.html
@@ -45,7 +45,6 @@
         <template is="dom-if" if="[[getIconIdForKey_(item)]]">
           <div aria-label="[[getAriaLabelForIcon(item)]]" role="img">
             <iron-icon icon="[[getIconIdForKey_(item)]]"
-                has-launcher-button="[[hasLauncherButton]]"
                 aria-hidden="true">
             </iron-icon>
           </div>
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_button_select.ts b/chrome/browser/resources/ash/settings/device_page/customize_button_select.ts
index 8d46bed..e233761ef 100644
--- a/chrome/browser/resources/ash/settings/device_page/customize_button_select.ts
+++ b/chrome/browser/resources/ash/settings/device_page/customize_button_select.ts
@@ -173,9 +173,7 @@
         value: undefined,
       },
 
-      hasLauncherButton: {
-        type: Boolean,
-      },
+      metaKey: Object,
     };
   }
 
@@ -192,7 +190,7 @@
   remappingIndex: number;
   actionList: ActionChoice[];
   selectedValue: string;
-  hasLauncherButton: boolean;
+  metaKey: MetaKey = MetaKey.kSearch;
   private isInitialized_: boolean;
   private shouldShowDropdownMenu_: boolean;
   private label_: string;
@@ -460,15 +458,18 @@
 
   private getIconIdForKey_(key: string): string|null {
     if (key === META_KEY || key === LWIN_KEY) {
-      return 'shortcut-input-keys:launcher';
+      // TODO(b/346638451): Update the icon for LauncherRefresh when the asset
+      // is finalized.
+      return this.metaKey === MetaKey.kSearch ? 'shortcut-input-keys:search' :
+                                                'shortcut-input-keys:launcher';
     }
     const iconName = KeyToIconNameMap[key];
     return iconName ? `shortcut-input-keys:${iconName}` : null;
   }
 
   private getAriaLabelForIcon(key: string): string {
-    const ariaLabelStringId = ShortcutInputKeyElement.getAriaLabelStringId(
-        key, this.hasLauncherButton ? MetaKey.kLauncher : MetaKey.kSearch);
+    const ariaLabelStringId =
+        ShortcutInputKeyElement.getAriaLabelStringId(key, this.metaKey);
 
     return this.i18n(ariaLabelStringId);
   }
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_buttons_subsection.html b/chrome/browser/resources/ash/settings/device_page/customize_buttons_subsection.html
index fbe19cb..ea5eab9 100644
--- a/chrome/browser/resources/ash/settings/device_page/customize_buttons_subsection.html
+++ b/chrome/browser/resources/ash/settings/device_page/customize_buttons_subsection.html
@@ -41,7 +41,7 @@
         button-remapping-list="[[buttonRemappingList]]"
         remapping-index="[[index]]"
         action-list$="[[actionList]]"
-        has-launcher-button="[[hasLauncherButton]]">
+        meta-key="[[metaKey]]">
     </customize-button-row>
   </template>
 </div>
@@ -90,6 +90,6 @@
     id="keyCombinationInputDialog"
     button-remapping-list="{{buttonRemappingList}}"
     remapping-index="[[selectedButtonIndex_]]"
-    has-launcher-button="[[hasLauncherButton]]"
+    meta-key="[[metaKey]]"
     on-close="onKeyCombinationDialogClose_">
 </key-combination-input-dialog>
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_buttons_subsection.ts b/chrome/browser/resources/ash/settings/device_page/customize_buttons_subsection.ts
index f599d26..681b598 100644
--- a/chrome/browser/resources/ash/settings/device_page/customize_buttons_subsection.ts
+++ b/chrome/browser/resources/ash/settings/device_page/customize_buttons_subsection.ts
@@ -25,7 +25,7 @@
 import {ReorderButtonEvent, ShowKeyCustomizationDialogEvent, ShowRenamingDialogEvent} from './customize_button_row.js';
 import {getTemplate} from './customize_buttons_subsection.html.js';
 import {DragAndDropManager, OnDropCallback} from './drag_and_drop_manager.js';
-import {ActionChoice, ButtonRemapping} from './input_device_settings_types.js';
+import {ActionChoice, ButtonRemapping, MetaKey} from './input_device_settings_types.js';
 import {KeyCombinationInputDialogElement} from './key_combination_input_dialog.js';
 
 const MAX_INPUT_LENGTH = 32;
@@ -100,9 +100,7 @@
         value: false,
       },
 
-      hasLauncherButton: {
-        type: Boolean,
-      },
+      metaKey: Object,
 
       /** Used to reference the maxInputLength constant in HTML. */
       maxInputLength: {
@@ -115,7 +113,7 @@
 
   buttonRemappingList: ButtonRemapping[];
   actionList: ActionChoice[];
-  hasLauncherButton: boolean;
+  metaKey: MetaKey = MetaKey.kSearch;
   private selectedButton_: ButtonRemapping;
   private selectedButtonIndex_: number;
   private selectedButtonName_: string;
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_mouse_buttons_subpage.html b/chrome/browser/resources/ash/settings/device_page/customize_mouse_buttons_subpage.html
index 00b9dd52..0672ce1a 100644
--- a/chrome/browser/resources/ash/settings/device_page/customize_mouse_buttons_subpage.html
+++ b/chrome/browser/resources/ash/settings/device_page/customize_mouse_buttons_subpage.html
@@ -59,6 +59,6 @@
   <customize-buttons-subsection
     button-remapping-list="{{selectedMouse.settings.buttonRemappings}}"
     action-list$="[[buttonActionList_]]"
-    has-launcher-button="[[hasLauncherButton_]]">
+    meta-key="[[metaKey_]]">
   </customize-buttons-subsection>
 </div>
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_mouse_buttons_subpage.ts b/chrome/browser/resources/ash/settings/device_page/customize_mouse_buttons_subpage.ts
index af1ee07..7d2cc7a 100644
--- a/chrome/browser/resources/ash/settings/device_page/customize_mouse_buttons_subpage.ts
+++ b/chrome/browser/resources/ash/settings/device_page/customize_mouse_buttons_subpage.ts
@@ -23,7 +23,7 @@
 
 import {getTemplate} from './customize_mouse_buttons_subpage.html.js';
 import {getInputDeviceSettingsProvider} from './input_device_mojo_interface_provider.js';
-import {ActionChoice, InputDeviceSettingsProviderInterface, Mouse, MousePolicies} from './input_device_settings_types.js';
+import {ActionChoice, InputDeviceSettingsProviderInterface, MetaKey, Mouse, MousePolicies} from './input_device_settings_types.js';
 import {getPrefPolicyFields} from './input_device_settings_utils.js';
 
 const SettingsCustomizeMouseButtonsSubpageElementBase =
@@ -69,11 +69,9 @@
       },
 
       /**
-       * Use hasLauncherButton to decide which meta key icon to display.
+       * Use metaKey to decide which meta key icon to display.
        */
-      hasLauncherButton_: {
-        type: Boolean,
-      },
+      metaKey_: Object,
     };
   }
 
@@ -94,15 +92,15 @@
   private previousRoute_: Route|null = null;
   private primaryRightPref_: chrome.settingsPrivate.PrefObject;
   private isInitialized_: boolean = false;
-  private hasLauncherButton_: boolean;
+  private metaKey_: MetaKey = MetaKey.kSearch;
 
   override async connectedCallback(): Promise<void> {
     super.connectedCallback();
 
     this.addEventListener('button-remapping-changed', this.onSettingsChanged);
-    this.hasLauncherButton_ =
-        (await this.inputDeviceSettingsProvider_.hasLauncherButton())
-            ?.hasLauncherButton;
+    this.metaKey_ =
+        (await this.inputDeviceSettingsProvider_.getMetaKeyToDisplay())
+            ?.metaKey;
   }
 
   override disconnectedCallback(): void {
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_pen_buttons_subpage.html b/chrome/browser/resources/ash/settings/device_page/customize_pen_buttons_subpage.html
index 969a6ec..9f7ad8e 100644
--- a/chrome/browser/resources/ash/settings/device_page/customize_pen_buttons_subpage.html
+++ b/chrome/browser/resources/ash/settings/device_page/customize_pen_buttons_subpage.html
@@ -50,6 +50,6 @@
   <customize-buttons-subsection
       button-remapping-list="{{selectedTablet.settings.penButtonRemappings}}"
       action-list$="[[buttonActionList_]]"
-      has-launcher-button="[[hasLauncherButton_]]">
+      meta-key="[[metaKey_]]">
   </customize-buttons-subsection>
 </div>
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_pen_buttons_subpage.ts b/chrome/browser/resources/ash/settings/device_page/customize_pen_buttons_subpage.ts
index 26513040..28fc2a6 100644
--- a/chrome/browser/resources/ash/settings/device_page/customize_pen_buttons_subpage.ts
+++ b/chrome/browser/resources/ash/settings/device_page/customize_pen_buttons_subpage.ts
@@ -23,7 +23,7 @@
 
 import {getTemplate} from './customize_pen_buttons_subpage.html.js';
 import {getInputDeviceSettingsProvider} from './input_device_mojo_interface_provider.js';
-import {ActionChoice, GraphicsTablet, InputDeviceSettingsProviderInterface} from './input_device_settings_types.js';
+import {ActionChoice, GraphicsTablet, InputDeviceSettingsProviderInterface, MetaKey} from './input_device_settings_types.js';
 
 const SettingsCustomizePenButtonsSubpageElementBase =
     RouteObserverMixin(I18nMixin(PolymerElement));
@@ -49,11 +49,9 @@
       },
 
       /**
-       * Use hasLauncherButton to decide which meta key icon to display.
+       * Use metaKey to decide which meta key icon to display.
        */
-      hasLauncherButton_: {
-        type: Boolean,
-      },
+      metaKey_: Object,
     };
   }
 
@@ -70,15 +68,15 @@
       getInputDeviceSettingsProvider();
   private previousRoute_: Route|null = null;
   private isInitialized_: boolean = false;
-  private hasLauncherButton_: boolean;
+  private metaKey_: MetaKey = MetaKey.kSearch;
 
   override async connectedCallback(): Promise<void> {
     super.connectedCallback();
 
     this.addEventListener('button-remapping-changed', this.onSettingsChanged);
-    this.hasLauncherButton_ =
-        (await this.inputDeviceSettingsProvider_.hasLauncherButton())
-            ?.hasLauncherButton;
+    this.metaKey_ =
+        (await this.inputDeviceSettingsProvider_.getMetaKeyToDisplay())
+            ?.metaKey;
   }
 
   override disconnectedCallback(): void {
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_tablet_buttons_subpage.html b/chrome/browser/resources/ash/settings/device_page/customize_tablet_buttons_subpage.html
index cc77e39..10a40f34 100644
--- a/chrome/browser/resources/ash/settings/device_page/customize_tablet_buttons_subpage.html
+++ b/chrome/browser/resources/ash/settings/device_page/customize_tablet_buttons_subpage.html
@@ -50,6 +50,6 @@
   <customize-buttons-subsection
       button-remapping-list="{{selectedTablet.settings.tabletButtonRemappings}}"
       action-list$="[[buttonActionList_]]"
-      has-launcher-button="[[hasLauncherButton_]]">
+      meta-key="[[metaKey_]]">
   </customize-buttons-subsection>
 </div>
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_tablet_buttons_subpage.ts b/chrome/browser/resources/ash/settings/device_page/customize_tablet_buttons_subpage.ts
index 8ada8c0..a7243f4 100644
--- a/chrome/browser/resources/ash/settings/device_page/customize_tablet_buttons_subpage.ts
+++ b/chrome/browser/resources/ash/settings/device_page/customize_tablet_buttons_subpage.ts
@@ -22,7 +22,7 @@
 
 import {getTemplate} from './customize_tablet_buttons_subpage.html.js';
 import {getInputDeviceSettingsProvider} from './input_device_mojo_interface_provider.js';
-import {ActionChoice, GraphicsTablet, InputDeviceSettingsProviderInterface} from './input_device_settings_types.js';
+import {ActionChoice, GraphicsTablet, InputDeviceSettingsProviderInterface, MetaKey} from './input_device_settings_types.js';
 
 const SettingsCustomizeTabletButtonsSubpageElementBase =
     RouteObserverMixin(I18nMixin(PolymerElement));
@@ -48,11 +48,9 @@
       },
 
       /**
-       * Use hasLauncherButton to decide which meta key icon to display.
+       * Use metaKey to decide which meta key icon to display.
        */
-      hasLauncherButton_: {
-        type: Boolean,
-      },
+      metaKey_: Object,
     };
   }
 
@@ -69,15 +67,15 @@
       getInputDeviceSettingsProvider();
   private previousRoute_: Route|null = null;
   private isInitialized_: boolean = false;
-  private hasLauncherButton_: boolean;
+  private metaKey_: MetaKey = MetaKey.kSearch;
 
   override async connectedCallback(): Promise<void> {
     super.connectedCallback();
 
     this.addEventListener('button-remapping-changed', this.onSettingsChanged);
-    this.hasLauncherButton_ =
-        (await this.inputDeviceSettingsProvider_.hasLauncherButton())
-            ?.hasLauncherButton;
+    this.metaKey_ =
+        (await this.inputDeviceSettingsProvider_.getMetaKeyToDisplay())
+            ?.metaKey;
   }
 
   override disconnectedCallback(): void {
diff --git a/chrome/browser/resources/ash/settings/device_page/fake_input_device_settings_provider.ts b/chrome/browser/resources/ash/settings/device_page/fake_input_device_settings_provider.ts
index a64562f..18db74d 100644
--- a/chrome/browser/resources/ash/settings/device_page/fake_input_device_settings_provider.ts
+++ b/chrome/browser/resources/ash/settings/device_page/fake_input_device_settings_provider.ts
@@ -21,7 +21,7 @@
   fakeGraphicsTablets: GraphicsTablet[];
   fakeMouseButtonActions: {options: ActionChoice[]};
   fakeGraphicsTabletButtonActions: {options: ActionChoice[]};
-  fakeHasLauncherButton: {hasLauncherButton: boolean};
+  fakeMetaKeyToDisplay: {metaKey: MetaKey};
   fakeHasKeyboardBacklight: {hasKeyboardBacklight: boolean};
   fakeHasAmbientLightSensor: {hasAmbientLightSensor: boolean};
   fakeIsRgbKeyboardSupported: {isRgbKeyboardSupported: boolean};
@@ -114,7 +114,7 @@
     this.methods.register('fakeGraphicsTablets');
     this.methods.register('fakeMouseButtonActions');
     this.methods.register('fakeGraphicsTabletButtonActions');
-    this.methods.register('fakeHasLauncherButton');
+    this.methods.register('fakeMetaKeyToDisplay');
     this.methods.register('fakeHasKeyboardBacklight');
     this.methods.register('fakeHasAmbientLightSensor');
     this.methods.register('fakeIsRgbKeyboardSupported');
@@ -422,13 +422,12 @@
     }
   }
 
-  hasLauncherButton(): Promise<{hasLauncherButton: boolean}> {
-    return this.methods.resolveMethod('fakeHasLauncherButton');
+  getMetaKeyToDisplay(): Promise<{metaKey: MetaKey}> {
+    return this.methods.resolveMethod('fakeMetaKeyToDisplay');
   }
 
-  setFakeHasLauncherButton(hasLauncherButton: boolean): void {
-    this.methods.setResult(
-        'fakeHasLauncherButton', {hasLauncherButton: hasLauncherButton});
+  setFakeMetaKeyToDisplay(metaKey: MetaKey): void {
+    this.methods.setResult('fakeMetaKeyToDisplay', {metaKey: metaKey});
   }
 
   hasKeyboardBacklight(): Promise<{hasKeyboardBacklight: boolean}> {
diff --git a/chrome/browser/resources/ash/settings/device_page/input_device_mojo_interface_provider.ts b/chrome/browser/resources/ash/settings/device_page/input_device_mojo_interface_provider.ts
index 4400f41..dd26819 100644
--- a/chrome/browser/resources/ash/settings/device_page/input_device_mojo_interface_provider.ts
+++ b/chrome/browser/resources/ash/settings/device_page/input_device_mojo_interface_provider.ts
@@ -8,7 +8,7 @@
 
 import {fakeGraphicsTabletButtonActions, fakeGraphicsTablets, fakeKeyboards, fakeMice, fakeMouseButtonActions, fakePointingSticks, fakeStyluses, fakeTouchpads} from './fake_input_device_data.js';
 import {FakeInputDeviceSettingsProvider} from './fake_input_device_settings_provider.js';
-import {InputDeviceSettingsProviderInterface} from './input_device_settings_types.js';
+import {InputDeviceSettingsProviderInterface, MetaKey} from './input_device_settings_types.js';
 
 /**
  * @fileoverview
@@ -34,7 +34,7 @@
   provider.setFakeActionsForGraphicsTabletButtonCustomization(
       fakeGraphicsTabletButtonActions);
   provider.setFakeActionsForMouseButtonCustomization(fakeMouseButtonActions);
-  provider.setFakeHasLauncherButton(true);
+  provider.setFakeMetaKeyToDisplay(MetaKey.kSearch);
   provider.setFakeIsRgbKeyboardSupported(true);
   provider.setFakeHasKeyboardBacklight(true);
   provider.setFakeHasAmbientLightSensor(true);
diff --git a/chrome/browser/resources/ash/settings/device_page/key_combination_input_dialog.html b/chrome/browser/resources/ash/settings/device_page/key_combination_input_dialog.html
index 95c715c..82b0265 100644
--- a/chrome/browser/resources/ash/settings/device_page/key_combination_input_dialog.html
+++ b/chrome/browser/resources/ash/settings/device_page/key_combination_input_dialog.html
@@ -36,7 +36,7 @@
       <shortcut-input id="shortcutInput" aria-describedby="dialogDescription"
           shortcut-input-provider="[[getShortcutProvider()]]"
           show-separator="true"
-          has-launcher-button="[[hasLauncherButton]]"
+          meta-key="[[metaKey]]"
           ignore-blur>
       </shortcut-input>
     </div>
diff --git a/chrome/browser/resources/ash/settings/device_page/key_combination_input_dialog.ts b/chrome/browser/resources/ash/settings/device_page/key_combination_input_dialog.ts
index 03991bf..c0cbea22 100644
--- a/chrome/browser/resources/ash/settings/device_page/key_combination_input_dialog.ts
+++ b/chrome/browser/resources/ash/settings/device_page/key_combination_input_dialog.ts
@@ -10,14 +10,14 @@
 import './input_device_settings_shared.css.js';
 import '../settings_shared.css.js';
 
-import {ShortcutInputElement} from 'chrome://resources/ash/common/shortcut_input_ui/shortcut_input.js';
 import {CrDialogElement} from 'chrome://resources/ash/common/cr_elements/cr_dialog/cr_dialog.js';
 import {I18nMixin} from 'chrome://resources/ash/common/cr_elements/i18n_mixin.js';
+import {ShortcutInputElement} from 'chrome://resources/ash/common/shortcut_input_ui/shortcut_input.js';
 import {EventTracker} from 'chrome://resources/js/event_tracker.js';
 import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {ButtonRemapping, KeyEvent, ShortcutInputProviderInterface} from './input_device_settings_types.js';
+import {ButtonRemapping, KeyEvent, MetaKey, ShortcutInputProviderInterface} from './input_device_settings_types.js';
 import {keyEventsAreEqual} from './input_device_settings_utils.js';
 import {getTemplate} from './key_combination_input_dialog.html.js';
 import {getShortcutInputProvider} from './shortcut_input_mojo_interface_provider.js';
@@ -84,9 +84,7 @@
         type: Object,
       },
 
-      hasLauncherButton: {
-        type: Boolean,
-      },
+      metaKey: Object,
     };
   }
 
@@ -102,7 +100,7 @@
   shortcutInput: ShortcutInputElement;
   inputKeyEvent: KeyEvent|undefined;
   isCapturing: boolean = false;
-  hasLauncherButton: boolean;
+  metaKey: MetaKey = MetaKey.kSearch;
   private buttonRemapping_: ButtonRemapping;
   private eventTracker_: EventTracker = new EventTracker();
 
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/facegaze/facegaze_test.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/facegaze/facegaze_test.js
index 8ea0e98..343a3bdc 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/facegaze/facegaze_test.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/facegaze/facegaze_test.js
@@ -22,15 +22,12 @@
     // this.
     const result = new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
         forehead_x, forehead_y);
-    this.processFaceLandmarkerResult(
-        result, /*triggerMouseControllerInterval=*/ true);
-    const cursorPosition =
-        this.mockAccessibilityPrivate.getLatestCursorPosition();
+    this.processFaceLandmarkerResult(result);
     if (config.cursorControlEnabled) {
-      assertEquals(config.mouseLocation.x, cursorPosition.x);
-      assertEquals(config.mouseLocation.y, cursorPosition.y);
+      this.assertLatestCursorPosition(config.mouseLocation);
     } else {
-      assertEquals(null, cursorPosition);
+      assertEquals(
+          null, this.mockAccessibilityPrivate.getLatestCursorPosition());
     }
   }
 
@@ -81,10 +78,7 @@
   for (let i = 0; i < 3; i++) {
     this.mockAccessibilityPrivate.clearCursorPosition();
     this.triggerMouseControllerInterval();
-    const cursorPosition =
-        this.mockAccessibilityPrivate.getLatestCursorPosition();
-    assertEquals(600, cursorPosition.x);
-    assertEquals(400, cursorPosition.y);
+    this.assertLatestCursorPosition({x: 600, y: 400});
   }
 });
 
@@ -99,13 +93,12 @@
       result, /*triggerMouseControllerInterval=*/ false);
 
   // Cursor position doesn't change on result.
-  let cursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
-  assertEquals(600, cursorPosition.x);
-  assertEquals(400, cursorPosition.y);
+  this.assertLatestCursorPosition({x: 600, y: 400});
 
   // Cursor position does change after interval fired.
   this.triggerMouseControllerInterval();
-  cursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
+  const cursorPosition =
+      this.mockAccessibilityPrivate.getLatestCursorPosition();
   assertNotEquals(600, cursorPosition.x);
   assertNotEquals(400, cursorPosition.y);
 });
@@ -122,49 +115,34 @@
   // downward as expected.
   let result =
       new MockFaceLandmarkerResult().setNormalizedForeheadLocation(0.11, 0.21);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
+  this.processFaceLandmarkerResult(result);
 
-  cursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
-  assertEquals(360, cursorPosition.x);
-  assertEquals(560, cursorPosition.y);
+  this.assertLatestCursorPosition({x: 360, y: 560});
 
   // Move to where we were. Since the buffer size is 1, should end up at the
   // exact same location.
   result =
       new MockFaceLandmarkerResult().setNormalizedForeheadLocation(0.1, 0.2);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
-  cursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
-  assertEquals(600, cursorPosition.x);
-  assertEquals(400, cursorPosition.y);
+  this.processFaceLandmarkerResult(result);
+  this.assertLatestCursorPosition({x: 600, y: 400});
 
   // Try a larger movement, 10% of the screen.
   result =
       new MockFaceLandmarkerResult().setNormalizedForeheadLocation(0.12, 0.22);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
-  cursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
-  assertEquals(120, cursorPosition.x);
-  assertEquals(720, cursorPosition.y);
+  this.processFaceLandmarkerResult(result);
+  this.assertLatestCursorPosition({x: 120, y: 720});
 
   result =
       new MockFaceLandmarkerResult().setNormalizedForeheadLocation(0.1, 0.2);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
-  cursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
-  assertEquals(600, cursorPosition.x);
-  assertEquals(400, cursorPosition.y);
+  this.processFaceLandmarkerResult(result);
+  this.assertLatestCursorPosition({x: 600, y: 400});
 
   // Try a very small movement, 0.5% of the screen, which ends up being about
   // one pixel.
   result = new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
       0.101, 0.201);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
-  cursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
-  assertEquals(580, cursorPosition.x);
-  assertEquals(420, cursorPosition.y);
+  this.processFaceLandmarkerResult(result);
+  this.assertLatestCursorPosition({x: 580, y: 420});
 });
 
 AX_TEST_F(
@@ -179,8 +157,7 @@
       // Move left and down. No events are generated.
       let result = new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
           0.11, 0.21);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
+      this.processFaceLandmarkerResult(result);
 
       assertEquals(
           null, this.mockAccessibilityPrivate.getLatestCursorPosition());
@@ -188,8 +165,7 @@
       // Try moving back. Still nothing.
       result = new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
           0.1, 0.2);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
+      this.processFaceLandmarkerResult(result);
       assertEquals(
           null, this.mockAccessibilityPrivate.getLatestCursorPosition());
 
@@ -201,34 +177,23 @@
       // original mouse location.
       result = new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
           0.11, 0.21);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
-      cursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
-      assertNotNullNorUndefined(cursorPosition);
-      assertEquals(600, cursorPosition.x);
-      assertEquals(400, cursorPosition.y);
+      this.processFaceLandmarkerResult(result);
+      this.assertLatestCursorPosition({x: 600, y: 400});
 
       // Moving the head further should move the mouse away from the original
       // cursor position.
       result = new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
           0.12, 0.22);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
+      this.processFaceLandmarkerResult(result);
 
-      cursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
-      assertNotEquals(null, cursorPosition);
-      assertEquals(360, cursorPosition.x);
-      assertEquals(560, cursorPosition.y);
+      this.assertLatestCursorPosition({x: 360, y: 560});
 
       // Turn it off again and move the mouse further. Nothing should happen.
       await this.setPref(FaceGaze.PREF_CURSOR_CONTROL_ENABLED, false);
       result = new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
           0.13, 0.23);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
-      cursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
-      assertEquals(360, cursorPosition.x);
-      assertEquals(560, cursorPosition.y);
+      this.processFaceLandmarkerResult(result);
+      this.assertLatestCursorPosition({x: 360, y: 560});
     });
 
 // Test that if the forehead location is moving around a different part of
@@ -247,21 +212,15 @@
       // moving left because the image is mirrored.
       let result = new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
           0.61, 0.71);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
-      cursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
-      assertEquals(360, cursorPosition.x);
-      assertEquals(560, cursorPosition.y);
+      this.processFaceLandmarkerResult(result);
+      this.assertLatestCursorPosition({x: 360, y: 560});
 
       // Move to where we were. Since the buffer size is 1, should end up at the
       // exact same location.
       result = new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
           0.6, 0.7);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
-      cursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
-      assertEquals(600, cursorPosition.x);
-      assertEquals(400, cursorPosition.y);
+      this.processFaceLandmarkerResult(result);
+      this.assertLatestCursorPosition({x: 600, y: 400});
     });
 
 // Tests that left/top offsets in ScreenBounds are respected. This should have
@@ -280,23 +239,16 @@
       // downward as expected.
       let result = new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
           0.11, 0.21);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
+      this.processFaceLandmarkerResult(result);
 
-      cursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
-      assertEquals(460, cursorPosition.x);
-      assertEquals(610, cursorPosition.y);
+      this.assertLatestCursorPosition({x: 460, y: 610});
 
       // Move to where we were. Since the buffer size is 1, should end up at the
       // exact same location.
       result = new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
           0.1, 0.2);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
-      this.mockAccessibilityPrivate.getLatestCursorPosition();
-      cursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
-      assertEquals(700, cursorPosition.x);
-      assertEquals(450, cursorPosition.y);
+      this.processFaceLandmarkerResult(result);
+      this.assertLatestCursorPosition({x: 700, y: 450});
     });
 
 AX_TEST_F('FaceGazeTest', 'UpdateMouseLocationWithBuffer', async function() {
@@ -308,9 +260,8 @@
   // moving left because the image is mirrored.
   let result =
       new MockFaceLandmarkerResult().setNormalizedForeheadLocation(0.11, 0.21);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
-  cursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
+  this.processFaceLandmarkerResult(result);
+  let cursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
   assertTrue(cursorPosition.x < 600);
   assertTrue(cursorPosition.y > 400);
 
@@ -318,8 +269,7 @@
   // again, but do get closer to it.
   result =
       new MockFaceLandmarkerResult().setNormalizedForeheadLocation(0.1, 0.2);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
+  this.processFaceLandmarkerResult(result);
   let newCursorPosition =
       this.mockAccessibilityPrivate.getLatestCursorPosition();
   assertTrue(newCursorPosition.x > cursorPosition.x);
@@ -329,8 +279,7 @@
 
   cursorPosition = newCursorPosition;
   // Process the same result again. We move even closer to (600, 400).
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
+  this.processFaceLandmarkerResult(result);
   newCursorPosition = this.mockAccessibilityPrivate.getLatestCursorPosition();
   assertTrue(newCursorPosition.x > cursorPosition.x);
   assertTrue(newCursorPosition.y < cursorPosition.y);
@@ -355,12 +304,8 @@
         const result =
             new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
                 0.1 + px * i, 0.2 + py * i);
-        this.processFaceLandmarkerResult(
-            result, /*triggerMouseControllerInterval=*/ true);
-        const cursorPosition =
-            this.mockAccessibilityPrivate.getLatestCursorPosition();
-        assertEquals(600 - i, cursorPosition.x);
-        assertEquals(400 + i, cursorPosition.y);
+        this.processFaceLandmarkerResult(result);
+        this.assertLatestCursorPosition({x: 600 - i, y: 400 + i});
       }
     });
 
@@ -376,14 +321,11 @@
 
       // Move further. Should get a linear increase in position.
       for (let i = 0; i < 5; i++) {
-        result = new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
-            0.1 + px * i * 5, 0.2 + py * i * 5);
-        this.processFaceLandmarkerResult(
-            result, /*triggerMouseControllerInterval=*/ true);
-        const cursorPosition =
-            this.mockAccessibilityPrivate.getLatestCursorPosition();
-        assertEquals(600 - i * 5, cursorPosition.x);
-        assertEquals(400 + i * 5, cursorPosition.y);
+        const result =
+            new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
+                0.1 + px * i * 5, 0.2 + py * i * 5);
+        this.processFaceLandmarkerResult(result);
+        this.assertLatestCursorPosition({x: 600 - i * 5, y: 400 + i * 5});
       }
     });
 
@@ -399,14 +341,11 @@
 
       // Move even further. Should get a linear increase in position.
       for (let i = 0; i < 5; i++) {
-        result = new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
-            0.1 + px * i * 20, 0.2 + py * i * 20);
-        this.processFaceLandmarkerResult(
-            result, /*triggerMouseControllerInterval=*/ true);
-        const cursorPosition =
-            this.mockAccessibilityPrivate.getLatestCursorPosition();
-        assertEquals(600 - i * 20, cursorPosition.x);
-        assertEquals(400 + i * 20, cursorPosition.y);
+        const result =
+            new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
+                0.1 + px * i * 20, 0.2 + py * i * 20);
+        this.processFaceLandmarkerResult(result);
+        this.assertLatestCursorPosition({x: 600 - i * 20, y: 400 + i * 20});
       }
     });
 
@@ -435,12 +374,8 @@
         const result =
             new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
                 xLocation, yLocation);
-        this.processFaceLandmarkerResult(
-            result, /*triggerMouseControllerInterval=*/ true);
-        const cursorPosition =
-            this.mockAccessibilityPrivate.getLatestCursorPosition();
-        assertEquals(600, cursorPosition.x);
-        assertEquals(400, cursorPosition.y);
+        this.processFaceLandmarkerResult(result);
+        this.assertLatestCursorPosition({x: 600, y: 400});
       }
     });
 
@@ -466,12 +401,8 @@
         const result =
             new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
                 xLocation, yLocation);
-        this.processFaceLandmarkerResult(
-            result, /*triggerMouseControllerInterval=*/ true);
-        const cursorPosition =
-            this.mockAccessibilityPrivate.getLatestCursorPosition();
-        assertEquals(600 - i * 3, cursorPosition.x);
-        assertEquals(400 + i * 3, cursorPosition.y);
+        this.processFaceLandmarkerResult(result);
+        this.assertLatestCursorPosition({x: 600 - i * 3, y: 400 + i * 3});
       }
     });
 
@@ -502,8 +433,7 @@
         const result =
             new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
                 xLocation, yLocation);
-        this.processFaceLandmarkerResult(
-            result, /*triggerMouseControllerInterval=*/ true);
+        this.processFaceLandmarkerResult(result);
         const cursorPosition =
             this.mockAccessibilityPrivate.getLatestCursorPosition();
         assertEquals(-10, cursorPosition.x - initialCursorPosition.x);
@@ -534,8 +464,7 @@
         const result =
             new MockFaceLandmarkerResult().setNormalizedForeheadLocation(
                 xLocation, yLocation);
-        this.processFaceLandmarkerResult(
-            result, /*triggerMouseControllerInterval=*/ true);
+        this.processFaceLandmarkerResult(result);
         const cursorPosition =
             this.mockAccessibilityPrivate.getLatestCursorPosition();
         assertEquals(-24, cursorPosition.x - initialCursorPosition.x);
@@ -563,14 +492,11 @@
               .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0.9)
               .addGestureWithConfidence(
                   MediapipeFacialGesture.BROW_INNER_UP, 0.3);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
+      this.processFaceLandmarkerResult(result);
 
-      assertEquals(
-          2, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
-      const pressEvent = this.mockAccessibilityPrivate.syntheticMouseEvents_[0];
-      const releaseEvent =
-          this.mockAccessibilityPrivate.syntheticMouseEvents_[1];
+      this.assertNumMouseEvents(2);
+      const pressEvent = this.getMouseEvents()[0];
+      const releaseEvent = this.getMouseEvents()[1];
       this.assertMouseClickAt(
           {pressEvent, releaseEvent, isLeft: true, x: 600, y: 400});
 
@@ -580,12 +506,10 @@
               .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0.4)
               .addGestureWithConfidence(
                   MediapipeFacialGesture.BROW_INNER_UP, 0.3);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
+      this.processFaceLandmarkerResult(result);
 
       // No more events are generated.
-      assertEquals(
-          2, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
+      this.assertNumMouseEvents(2);
     });
 
 
@@ -609,12 +533,10 @@
               .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0.9)
               .addGestureWithConfidence(
                   MediapipeFacialGesture.BROW_INNER_UP, 0.3);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
+      this.processFaceLandmarkerResult(result);
 
-      assertEquals(
-          1, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
-      const pressEvent = this.mockAccessibilityPrivate.syntheticMouseEvents_[0];
+      this.assertNumMouseEvents(1);
+      const pressEvent = this.getMouseEvents()[0];
       assertEquals(
           this.mockAccessibilityPrivate.SyntheticMouseEventType.PRESS,
           pressEvent.type);
@@ -630,13 +552,10 @@
               .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0.4)
               .addGestureWithConfidence(
                   MediapipeFacialGesture.BROW_INNER_UP, 0.3);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
+      this.processFaceLandmarkerResult(result);
 
-      assertEquals(
-          2, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
-      const releaseEvent =
-          this.mockAccessibilityPrivate.syntheticMouseEvents_[1];
+      this.assertNumMouseEvents(2);
+      const releaseEvent = this.getMouseEvents()[1];
       assertEquals(
           this.mockAccessibilityPrivate.SyntheticMouseEventType.RELEASE,
           releaseEvent.type);
@@ -666,8 +585,7 @@
           .addGestureWithConfidence(MediapipeFacialGesture.BROW_DOWN_LEFT, 0.3)
           .addGestureWithConfidence(
               MediapipeFacialGesture.BROW_DOWN_RIGHT, 0.3);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
+  this.processFaceLandmarkerResult(result);
   assertEquals(null, this.mockAccessibilityPrivate.getLatestCursorPosition());
 
   result =
@@ -675,10 +593,8 @@
           .addGestureWithConfidence(MediapipeFacialGesture.BROW_DOWN_LEFT, 0.9)
           .addGestureWithConfidence(
               MediapipeFacialGesture.BROW_DOWN_RIGHT, 0.3);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
-  assertEquals(600, this.mockAccessibilityPrivate.getLatestCursorPosition().x);
-  assertEquals(400, this.mockAccessibilityPrivate.getLatestCursorPosition().y);
+  this.processFaceLandmarkerResult(result);
+  this.assertLatestCursorPosition({x: 600, y: 400});
   this.mockAccessibilityPrivate.clearCursorPosition();
   this.clearGestureLastRecognizedTime();
 
@@ -687,10 +603,8 @@
           .addGestureWithConfidence(MediapipeFacialGesture.BROW_DOWN_LEFT, 0.3)
           .addGestureWithConfidence(
               MediapipeFacialGesture.BROW_DOWN_RIGHT, 0.9);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
-  assertEquals(600, this.mockAccessibilityPrivate.getLatestCursorPosition().x);
-  assertEquals(400, this.mockAccessibilityPrivate.getLatestCursorPosition().y);
+  this.processFaceLandmarkerResult(result);
+  this.assertLatestCursorPosition({x: 600, y: 400});
   this.mockAccessibilityPrivate.clearCursorPosition();
   this.clearGestureLastRecognizedTime();
 
@@ -699,10 +613,8 @@
           .addGestureWithConfidence(MediapipeFacialGesture.BROW_DOWN_LEFT, 0.9)
           .addGestureWithConfidence(
               MediapipeFacialGesture.BROW_DOWN_RIGHT, 0.9);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
-  assertEquals(600, this.mockAccessibilityPrivate.getLatestCursorPosition().x);
-  assertEquals(400, this.mockAccessibilityPrivate.getLatestCursorPosition().y);
+  this.processFaceLandmarkerResult(result);
+  this.assertLatestCursorPosition({x: 600, y: 400});
 });
 
 AX_TEST_F(
@@ -728,22 +640,18 @@
               .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0.9)
               .addGestureWithConfidence(
                   MediapipeFacialGesture.BROW_INNER_UP, 0.3);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
+      this.processFaceLandmarkerResult(result);
 
-      assertEquals(
-          0, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
+      this.assertNumMouseEvents(0);
 
       result =
           new MockFaceLandmarkerResult()
               .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0.9)
               .addGestureWithConfidence(
                   MediapipeFacialGesture.BROW_INNER_UP, 0.9);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
+      this.processFaceLandmarkerResult(result);
 
-      assertEquals(
-          0, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
+      this.assertNumMouseEvents(0);
 
       // Enable actions. Now we we should get actions.
       await this.setPref(FaceGaze.PREF_ACTIONS_ENABLED, true);
@@ -753,14 +661,11 @@
               .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0.9)
               .addGestureWithConfidence(
                   MediapipeFacialGesture.BROW_INNER_UP, 0.3);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
+      this.processFaceLandmarkerResult(result);
 
-      assertEquals(
-          2, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
-      const pressEvent = this.mockAccessibilityPrivate.syntheticMouseEvents_[0];
-      const releaseEvent =
-          this.mockAccessibilityPrivate.syntheticMouseEvents_[1];
+      this.assertNumMouseEvents(2);
+      const pressEvent = this.getMouseEvents()[0];
+      const releaseEvent = this.getMouseEvents()[1];
       this.assertMouseClickAt(
           {pressEvent, releaseEvent, isLeft: true, x: 600, y: 400});
     });
@@ -787,14 +692,11 @@
 
       result = new MockFaceLandmarkerResult().addGestureWithConfidence(
           MediapipeFacialGesture.MOUTH_PUCKER, 0.7);
-      this.processFaceLandmarkerResult(
-          result, /*triggerMouseControllerInterval=*/ true);
+      this.processFaceLandmarkerResult(result);
 
-      assertEquals(
-          2, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
-      const pressEvent = this.mockAccessibilityPrivate.syntheticMouseEvents_[0];
-      const releaseEvent =
-          this.mockAccessibilityPrivate.syntheticMouseEvents_[1];
+      this.assertNumMouseEvents(2);
+      const pressEvent = this.getMouseEvents()[0];
+      const releaseEvent = this.getMouseEvents()[1];
       this.assertMouseClickAt(
           {pressEvent, releaseEvent, isLeft: false, x: 350, y: 250});
     });
@@ -822,12 +724,11 @@
             .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0.9)
             .addGestureWithConfidence(
                 MediapipeFacialGesture.BROW_INNER_UP, 0.3);
-    this.processFaceLandmarkerResult(
-        result, /*triggerMouseControllerInterval=*/ true);
+    this.processFaceLandmarkerResult(result);
 
     // 5 times in quick succession still only generates one press.
-    assertEquals(1, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
-    const pressEvent = this.mockAccessibilityPrivate.syntheticMouseEvents_[0];
+    this.assertNumMouseEvents(1);
+    const pressEvent = this.getMouseEvents()[0];
     assertEquals(
         this.mockAccessibilityPrivate.SyntheticMouseEventType.PRESS,
         pressEvent.type);
@@ -841,10 +742,9 @@
       new MockFaceLandmarkerResult()
           .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0.5)
           .addGestureWithConfidence(MediapipeFacialGesture.BROW_INNER_UP, 0.3);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
-  assertEquals(2, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
-  let releaseEvent = this.mockAccessibilityPrivate.syntheticMouseEvents_[1];
+  this.processFaceLandmarkerResult(result);
+  this.assertNumMouseEvents(2);
+  let releaseEvent = this.getMouseEvents()[1];
   assertEquals(
       this.mockAccessibilityPrivate.SyntheticMouseEventType.RELEASE,
       releaseEvent.type);
@@ -859,18 +759,17 @@
                            MediapipeFacialGesture.BROW_DOWN_LEFT, 0.9)
                        .addGestureWithConfidence(
                            MediapipeFacialGesture.BROW_DOWN_RIGHT, 0.9);
-    this.processFaceLandmarkerResult(
-        result, /*triggerMouseControllerInterval=*/ true);
+    this.processFaceLandmarkerResult(result);
 
-    assertEquals(4, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
-    const pressEvent = this.mockAccessibilityPrivate.syntheticMouseEvents_[2];
+    this.assertNumMouseEvents(4);
+    const pressEvent = this.getMouseEvents()[2];
     assertEquals(
         this.mockAccessibilityPrivate.SyntheticMouseEventType.PRESS,
         pressEvent.type);
     assertEquals(
         this.mockAccessibilityPrivate.SyntheticMouseEventButton.RIGHT,
         pressEvent.mouseButton);
-    releaseEvent = this.mockAccessibilityPrivate.syntheticMouseEvents_[3];
+    releaseEvent = this.getMouseEvents()[3];
     assertEquals(
         this.mockAccessibilityPrivate.SyntheticMouseEventType.RELEASE,
         releaseEvent.type);
@@ -885,9 +784,8 @@
           .addGestureWithConfidence(MediapipeFacialGesture.BROW_DOWN_LEFT, 0.4)
           .addGestureWithConfidence(
               MediapipeFacialGesture.BROW_DOWN_RIGHT, 0.3);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
-  assertEquals(4, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
+  this.processFaceLandmarkerResult(result);
+  this.assertNumMouseEvents(4);
 });
 
 AX_TEST_F('FaceGazeTest', 'DoesNotClickDuringLongClick', async function() {
@@ -909,11 +807,10 @@
           .addGestureWithConfidence(MediapipeFacialGesture.EYE_SQUINT_LEFT, 0.3)
           .addGestureWithConfidence(
               MediapipeFacialGesture.EYE_SQUINT_RIGHT, 0.3);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
+  this.processFaceLandmarkerResult(result);
 
-  assertEquals(1, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
-  const pressEvent = this.mockAccessibilityPrivate.syntheticMouseEvents_[0];
+  this.assertNumMouseEvents(1);
+  const pressEvent = this.getMouseEvents()[0];
   assertEquals(
       this.mockAccessibilityPrivate.SyntheticMouseEventType.PRESS,
       pressEvent.type);
@@ -931,20 +828,18 @@
           .addGestureWithConfidence(MediapipeFacialGesture.EYE_SQUINT_LEFT, 0.9)
           .addGestureWithConfidence(
               MediapipeFacialGesture.EYE_SQUINT_RIGHT, 0.3);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
+  this.processFaceLandmarkerResult(result);
   // No more events are generated.
-  assertEquals(1, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
+  this.assertNumMouseEvents(1);
   result =
       new MockFaceLandmarkerResult()
           .addGestureWithConfidence(MediapipeFacialGesture.MOUTH_PUCKER, 0.9)
           .addGestureWithConfidence(MediapipeFacialGesture.EYE_SQUINT_LEFT, 0.3)
           .addGestureWithConfidence(
               MediapipeFacialGesture.EYE_SQUINT_RIGHT, 0.3);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
+  this.processFaceLandmarkerResult(result);
   // No more events are generated.
-  assertEquals(1, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
+  this.assertNumMouseEvents(1);
 
   // Try with short right click gesture while still holding long click left.
   result =
@@ -953,10 +848,9 @@
           .addGestureWithConfidence(MediapipeFacialGesture.EYE_SQUINT_LEFT, 0.3)
           .addGestureWithConfidence(
               MediapipeFacialGesture.EYE_SQUINT_RIGHT, 0.9);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
+  this.processFaceLandmarkerResult(result);
   // No more events are generated.
-  assertEquals(1, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
+  this.assertNumMouseEvents(1);
 
   result =
       new MockFaceLandmarkerResult()
@@ -964,10 +858,9 @@
           .addGestureWithConfidence(MediapipeFacialGesture.EYE_SQUINT_LEFT, 0.3)
           .addGestureWithConfidence(
               MediapipeFacialGesture.EYE_SQUINT_RIGHT, 0.3);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
+  this.processFaceLandmarkerResult(result);
   // No more events are generated.
-  assertEquals(1, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
+  this.assertNumMouseEvents(1);
 
   // Send the end of the long click by stopping mouth pucker.
   result =
@@ -976,10 +869,9 @@
           .addGestureWithConfidence(MediapipeFacialGesture.EYE_SQUINT_LEFT, 0.3)
           .addGestureWithConfidence(
               MediapipeFacialGesture.EYE_SQUINT_RIGHT, 0.3);
-  this.processFaceLandmarkerResult(
-      result, /*triggerMouseControllerInterval=*/ true);
-  assertEquals(2, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
-  const releaseEvent = this.mockAccessibilityPrivate.syntheticMouseEvents_[1];
+  this.processFaceLandmarkerResult(result);
+  this.assertNumMouseEvents(2);
+  const releaseEvent = this.getMouseEvents()[1];
   assertEquals(
       this.mockAccessibilityPrivate.SyntheticMouseEventType.RELEASE,
       releaseEvent.type);
@@ -1048,9 +940,8 @@
                        .addGestureWithConfidence(
                            MediapipeFacialGesture.MOUTH_PUCKER,
                            gestures.mouthPucker ? gestures.mouthPucker : 0.3);
-    this.processFaceLandmarkerResult(
-        result, /*triggerMouseControllerInterval=*/ true);
-    return this.mockAccessibilityPrivate.syntheticKeyEvents_;
+    this.processFaceLandmarkerResult(result);
+    return this.getKeyEvents();
   };
 
   // Squint left for space key press.
@@ -1184,3 +1075,230 @@
       view => view.location.href.includes('camera_stream.html'));
   assertFalse(!!win);
 });
+
+AX_TEST_F('FaceGazeTest', 'ToggleFaceGazeGesturesShort', async function() {
+  const gestureToMacroName =
+      new Map()
+          .set(FacialGesture.JAW_OPEN, MacroName.TOGGLE_FACEGAZE)
+          .set(FacialGesture.BROW_INNER_UP, MacroName.MOUSE_CLICK_LEFT);
+  const gestureToConfidence = new Map()
+                                  .set(FacialGesture.JAW_OPEN, 0.3)
+                                  .set(FacialGesture.BROW_INNER_UP, 0.3);
+  const config = new Config()
+                     .withMouseLocation({x: 600, y: 400})
+                     .withGestureToMacroName(gestureToMacroName)
+                     .withGestureToConfidence(gestureToConfidence)
+                     .withRepeatDelayMs(1);
+  await this.configureFaceGaze(config);
+
+  // Toggle (pause) FaceGaze.
+  result = new MockFaceLandmarkerResult().addGestureWithConfidence(
+      MediapipeFacialGesture.JAW_OPEN, 0.9);
+  this.processFaceLandmarkerResult(
+      result, /*triggerMouseControllerInterval=*/ false);
+  assertTrue(this.getFaceGaze().gestureHandler_.paused_);
+
+  // Try to perform left click.
+  result =
+      new MockFaceLandmarkerResult()
+          .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0)
+          .addGestureWithConfidence(MediapipeFacialGesture.BROW_INNER_UP, 0.9);
+  this.processFaceLandmarkerResult(
+      result, /*triggerMouseControllerInterval=*/ false);
+
+  // No click should be performed.
+  this.assertNumMouseEvents(0);
+
+  // Toggle (resume) FaceGaze and release mouse click gesture.
+  result =
+      new MockFaceLandmarkerResult()
+          .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0.9)
+          .addGestureWithConfidence(MediapipeFacialGesture.BROW_INNER_UP, 0);
+  this.processFaceLandmarkerResult(
+      result, /*triggerMouseControllerInterval=*/ false);
+  assertFalse(this.getFaceGaze().gestureHandler_.paused_);
+  // No click should be performed.
+  this.assertNumMouseEvents(0);
+
+  // Perform left click now that FaceGaze has resumed.
+  result =
+      new MockFaceLandmarkerResult()
+          .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0)
+          .addGestureWithConfidence(MediapipeFacialGesture.BROW_INNER_UP, 0.9);
+  this.processFaceLandmarkerResult(
+      result, /*triggerMouseControllerInterval=*/ false);
+
+  // Synthetic mouse events should have been sent.
+  this.assertNumMouseEvents(2);
+});
+
+AX_TEST_F('FaceGazeTest', 'ToggleFaceGazeGesturesLong', async function() {
+  const gestureToMacroName =
+      new Map()
+          .set(FacialGesture.JAW_OPEN, MacroName.TOGGLE_FACEGAZE)
+          .set(FacialGesture.BROW_INNER_UP, MacroName.MOUSE_LONG_CLICK_LEFT)
+          .set(FacialGesture.EYE_SQUINT_LEFT, MacroName.KEY_PRESS_SPACE);
+  const gestureToConfidence = new Map()
+                                  .set(FacialGesture.JAW_OPEN, 0.3)
+                                  .set(FacialGesture.BROW_INNER_UP, 0.3)
+                                  .set(FacialGesture.EYE_SQUINT_LEFT, 0.3);
+  const config = new Config()
+                     .withMouseLocation({x: 600, y: 400})
+                     .withGestureToMacroName(gestureToMacroName)
+                     .withGestureToConfidence(gestureToConfidence)
+                     .withRepeatDelayMs(1);
+  await this.configureFaceGaze(config);
+
+  // Trigger a mouse press and a key down.
+  let result =
+      new MockFaceLandmarkerResult()
+          .addGestureWithConfidence(MediapipeFacialGesture.BROW_INNER_UP, 0.9)
+          .addGestureWithConfidence(
+              MediapipeFacialGesture.EYE_SQUINT_LEFT, 0.9);
+  this.processFaceLandmarkerResult(
+      result, /*triggerMouseControllerInterval=*/ false);
+
+  // A synthetic mouse event should have been sent.
+  this.assertNumMouseEvents(1);
+  this.assertMousePress(this.getMouseEvents()[0]);
+
+  // A synthetic key event should have been sent.
+  this.assertNumKeyEvents(1);
+  this.assertKeyDown(this.getKeyEvents()[0]);
+
+  // Toggle (pause) FaceGaze in the middle of long actions.
+  result =
+      new MockFaceLandmarkerResult()
+          .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0.9)
+          .addGestureWithConfidence(MediapipeFacialGesture.BROW_INNER_UP, 0.9)
+          .addGestureWithConfidence(
+              MediapipeFacialGesture.EYE_SQUINT_LEFT, 0.9);
+  this.processFaceLandmarkerResult(
+      result, /*triggerMouseControllerInterval=*/ false);
+  assertTrue(this.getFaceGaze().gestureHandler_.paused_);
+
+  // Pausing in the middle of long actions should cause them to be completed.
+  // The purpose of this is to clear state.
+  this.assertNumMouseEvents(2);
+  this.assertMouseRelease(this.getMouseEvents()[1]);
+  this.assertNumKeyEvents(2);
+  this.assertKeyUp(this.getKeyEvents()[1]);
+
+  // Release all gestures.
+  result =
+      new MockFaceLandmarkerResult()
+          .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0)
+          .addGestureWithConfidence(MediapipeFacialGesture.BROW_INNER_UP, 0)
+          .addGestureWithConfidence(MediapipeFacialGesture.EYE_SQUINT_LEFT, 0);
+  this.processFaceLandmarkerResult(
+      result, /*triggerMouseControllerInterval=*/ false);
+  // No extra mouse or key events should have come through.
+  this.assertNumMouseEvents(2);
+  this.assertNumKeyEvents(2);
+
+  // Toggle (resume) FaceGaze.
+  result = new MockFaceLandmarkerResult().addGestureWithConfidence(
+      MediapipeFacialGesture.JAW_OPEN, 0.9);
+  this.processFaceLandmarkerResult(
+      result, /*triggerMouseControllerInterval=*/ false);
+  assertFalse(this.getFaceGaze().gestureHandler_.paused_);
+  // No extra mouse or key events should come through.
+  this.assertNumMouseEvents(2);
+  this.assertNumKeyEvents(2);
+
+  // Confirm that long actions work as expected.
+  result =
+      new MockFaceLandmarkerResult()
+          .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0)
+          .addGestureWithConfidence(MediapipeFacialGesture.BROW_INNER_UP, 0.9)
+          .addGestureWithConfidence(
+              MediapipeFacialGesture.EYE_SQUINT_LEFT, 0.9);
+  this.processFaceLandmarkerResult(
+      result, /*triggerMouseControllerInterval=*/ false);
+
+  // A mouse press should have been sent.
+  this.assertNumMouseEvents(3);
+  this.assertMousePress(this.getMouseEvents()[2]);
+
+  // A key down should have been sent.
+  this.assertNumKeyEvents(3);
+  this.assertKeyDown(this.getKeyEvents()[2]);
+
+  // Release gestures to get the mouse release and the key up events.
+  result =
+      new MockFaceLandmarkerResult()
+          .addGestureWithConfidence(MediapipeFacialGesture.BROW_INNER_UP, 0)
+          .addGestureWithConfidence(MediapipeFacialGesture.EYE_SQUINT_LEFT, 0);
+  this.processFaceLandmarkerResult(
+      result, /*triggerMouseControllerInterval=*/ false);
+
+  // Confirm that the mouse release was sent.
+  this.assertNumMouseEvents(4);
+  this.assertMouseRelease(this.getMouseEvents()[3]);
+
+  // Confirm that the key up event was sent.
+  this.assertNumKeyEvents(4);
+  this.assertKeyUp(this.getKeyEvents()[3]);
+});
+
+AX_TEST_F('FaceGazeTest', 'ToggleFaceGazeMouseMovement', async function() {
+  const gestureToMacroName =
+      new Map().set(FacialGesture.JAW_OPEN, MacroName.TOGGLE_FACEGAZE);
+  const gestureToConfidence = new Map().set(FacialGesture.JAW_OPEN, 0.3);
+  const config = new Config()
+                     .withMouseLocation({x: 600, y: 400})
+                     .withBufferSize(1)
+                     .withCursorControlEnabled(true)
+                     .withGestureToMacroName(gestureToMacroName)
+                     .withGestureToConfidence(gestureToConfidence)
+                     .withRepeatDelayMs(1);
+  await this.startFacegazeWithConfigAndForeheadLocation_(config, 0.1, 0.2);
+
+  // Move the mouse.
+  let result =
+      new MockFaceLandmarkerResult().setNormalizedForeheadLocation(0.11, 0.21);
+  this.processFaceLandmarkerResult(result);
+  this.assertLatestCursorPosition({x: 360, y: 560});
+
+  // Toggle (pause) FaceGaze.
+  result = new MockFaceLandmarkerResult().addGestureWithConfidence(
+      MediapipeFacialGesture.JAW_OPEN, 0.9);
+  this.processFaceLandmarkerResult(result);
+  assertTrue(this.getFaceGaze().mouseController_.paused_);
+
+  // Try to move the mouse.
+  result = new MockFaceLandmarkerResult()
+               .setNormalizedForeheadLocation(0.50, 0.50)
+               .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0);
+  this.processFaceLandmarkerResult(result);
+  // Cursor position should remain the same.
+  this.assertLatestCursorPosition({x: 360, y: 560});
+
+  // Toggle (resume) FaceGaze.
+  result = new MockFaceLandmarkerResult().addGestureWithConfidence(
+      MediapipeFacialGesture.JAW_OPEN, 0.9);
+  // Don't trigger a mouse interval here because starting the MouseController
+  // is an asynchronous operation and will cause flakes otherwise.
+  this.processFaceLandmarkerResult(
+      result, /*triggerMouseControllerInterval=*/ false);
+  assertFalse(this.getFaceGaze().mouseController_.paused_);
+  // Wait for the MouseController to fully start.
+  await this.waitForValidMouseInterval();
+
+  // TODO(b/330766904): Move the mouse physically and ensure FaceGaze starts
+  // from that location when it's unpaused.
+  // Try to move the mouse. Since the MouseController was just freshly
+  // initialized, the cursor position won't change after processing this result.
+  result = new MockFaceLandmarkerResult()
+               .setNormalizedForeheadLocation(0.1, 0.2)
+               .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0);
+  this.processFaceLandmarkerResult(result);
+  this.assertLatestCursorPosition({x: 360, y: 560});
+
+  // The second result should move the mouse.
+  result = new MockFaceLandmarkerResult()
+               .setNormalizedForeheadLocation(0.11, 0.21)
+               .addGestureWithConfidence(MediapipeFacialGesture.JAW_OPEN, 0);
+  this.processFaceLandmarkerResult(result);
+  this.assertLatestCursorPosition({x: 120, y: 720});
+});
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/facegaze/facegaze_test_base.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/facegaze/facegaze_test_base.js
index 2ae60c8a..d931f0a 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/facegaze/facegaze_test_base.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/facegaze/facegaze_test_base.js
@@ -168,6 +168,11 @@
       this.intervalCallbacks_ = {};
       this.nextCallbackId_ = 1;
 
+      // Save the original set and clear interval functions so they can be used
+      // in this file.
+      window.setIntervalOriginal = window.setInterval;
+      window.clearIntervalOriginal = window.clearInterval;
+
       window.setInterval = (callback, timeout) => {
         const id = this.nextCallbackId_;
         this.nextCallbackId_++;
@@ -286,7 +291,8 @@
 
   triggerMouseControllerInterval() {
     const intervalId = this.getFaceGaze().mouseController_.mouseInterval_;
-    if (this.getFaceGaze().cursorControlEnabled_) {
+    if (this.getFaceGaze().cursorControlEnabled_ &&
+        !this.getFaceGaze().mouseController_.paused_) {
       assertNotEquals(-1, intervalId);
       assertNotNullNorUndefined(this.intervalCallbacks_[intervalId]);
       this.intervalCallbacks_[intervalId]();
@@ -300,7 +306,7 @@
    * @param {!MockFaceLandmarkerResult} result
    * @param {boolean} triggerMouseControllerInterval
    */
-  processFaceLandmarkerResult(result, triggerMouseControllerInterval) {
+  processFaceLandmarkerResult(result, triggerMouseControllerInterval = true) {
     this.getFaceGaze().processFaceLandmarkerResult_(result);
 
     if (triggerMouseControllerInterval) {
@@ -322,4 +328,76 @@
     this.getFaceGaze().mouseController_.onMouseMovedHandler_.handleEvent_(
         mockEvent);
   }
+
+  /** @param {!{x: number, y: number}} expected */
+  assertLatestCursorPosition(expected) {
+    const actual = this.mockAccessibilityPrivate.getLatestCursorPosition();
+    assertEquals(expected.x, actual.x);
+    assertEquals(expected.y, actual.y);
+  }
+
+  /** @param {number} num */
+  assertNumMouseEvents(num) {
+    assertEquals(
+        num, this.mockAccessibilityPrivate.syntheticMouseEvents_.length);
+  }
+
+  /** @param {number} num */
+  assertNumKeyEvents(num) {
+    assertEquals(num, this.mockAccessibilityPrivate.syntheticKeyEvents_.length);
+  }
+
+  /** @param {!chrome.accessibilityPrivate.SyntheticMouseEvent} event */
+  assertMousePress(event) {
+    assertEquals(
+        this.mockAccessibilityPrivate.SyntheticMouseEventType.PRESS,
+        event.type);
+  }
+
+  /** @param {!chrome.accessibilityPrivate.SyntheticMouseEvent} event */
+  assertMouseRelease(event) {
+    assertEquals(
+        this.mockAccessibilityPrivate.SyntheticMouseEventType.RELEASE,
+        event.type);
+  }
+
+  /** @param {!chrome.accessibilityPrivate.SyntheticKeyboardEvent} event */
+  assertKeyDown(event) {
+    assertEquals(
+        chrome.accessibilityPrivate.SyntheticKeyboardEventType.KEYDOWN,
+        event.type);
+  }
+
+  /** @param {!chrome.accessibilityPrivate.SyntheticKeyboardEvent} event */
+  assertKeyUp(event) {
+    assertEquals(
+        chrome.accessibilityPrivate.SyntheticKeyboardEventType.KEYUP,
+        event.type);
+  }
+
+  /** @return {!Array<!chrome.accessibilityPrivate.SyntheticMouseEvent>} */
+  getMouseEvents() {
+    return this.mockAccessibilityPrivate.syntheticMouseEvents_;
+  }
+
+  /** @return {!Array<!chrome.accessibilityPrivate.SyntheticKeyboardEvent>} */
+  getKeyEvents() {
+    return this.mockAccessibilityPrivate.syntheticKeyEvents_;
+  }
+
+  /** Waits for the mouse controller to initialize its interval function. */
+  async waitForValidMouseInterval() {
+    if (this.getFaceGaze().mouseController_.mouseInterval_ !== -1) {
+      return;
+    }
+
+    await new Promise((resolve) => {
+      const intervalId = setIntervalOriginal(() => {
+        if (this.getFaceGaze().mouseController_.mouseInterval_ !== -1) {
+          clearIntervalOriginal(intervalId);
+          resolve();
+        }
+      }, 300);
+    });
+  }
 };
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/facegaze/gesture_handler.ts b/chrome/browser/resources/chromeos/accessibility/accessibility_common/facegaze/gesture_handler.ts
index d08d36ff..a733e229 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/facegaze/gesture_handler.ts
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/facegaze/gesture_handler.ts
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {CustomCallbackMacro} from '/common/action_fulfillment/macros/custom_callback_macro.js';
 import {KeyPressMacro} from '/common/action_fulfillment/macros/key_press_macro.js';
 import {Macro} from '/common/action_fulfillment/macros/macro.js';
 import {MacroName} from '/common/action_fulfillment/macros/macro_names.js';
@@ -31,6 +32,7 @@
   // has ended.
   private previousGestures_: FacialGesture[] = [];
   private macrosToCompleteLater_: Map<FacialGesture, Macro> = new Map();
+  private paused_ = false;
 
   constructor(mouseController: MouseController) {
     this.mouseController_ = mouseController;
@@ -38,17 +40,21 @@
   }
 
   start(): void {
+    this.paused_ = false;
     chrome.settingsPrivate.getAllPrefs(prefs => this.updateFromPrefs_(prefs));
     chrome.settingsPrivate.onPrefsChanged.addListener(this.prefsListener_);
   }
 
   stop(): void {
+    this.paused_ = false;
     chrome.settingsPrivate.onPrefsChanged.removeListener(this.prefsListener_);
     this.previousGestures_ = [];
     this.gestureLastRecognized_.clear();
-    // TODO(b:341770655): Executing these macros clears their state, so that we
-    // aren't left in a mouse down or key down state. However, that could have
-    // other side effects. It would be best to send a synthetic cancel event.
+    // Executing these macros clears their state, so that we aren't left in a
+    // mouse down or key down state.
+    this.macrosToCompleteLater_.forEach((macro) => {
+      macro.run();
+    });
     this.macrosToCompleteLater_.clear();
   }
 
@@ -107,6 +113,14 @@
     return macros;
   }
 
+  togglePaused(): void {
+    const newPaused = !this.paused_;
+    // Run start/stop before assigning the new pause value, since start/stop
+    // will modify the pause value.
+    newPaused ? this.stop() : this.start();
+    this.paused_ = newPaused;
+  }
+
   private gesturesToMacros_(gestures: FacialGesture[]): Macro[] {
     const macroNames: Map<MacroName, FacialGesture> = new Map();
     for (const gesture of gestures) {
@@ -181,6 +195,10 @@
   }
 
   private macroFromName_(name: MacroName): Macro|undefined {
+    if (this.paused_ && name !== MacroName.TOGGLE_FACEGAZE) {
+      return;
+    }
+
     switch (name) {
       case MacroName.TOGGLE_DICTATION:
         return new ToggleDictationMacro();
@@ -203,6 +221,11 @@
       case MacroName.KEY_PRESS_TOGGLE_OVERVIEW:
       case MacroName.KEY_PRESS_MEDIA_PLAY_PAUSE:
         return new KeyPressMacro(name);
+      case MacroName.TOGGLE_FACEGAZE:
+        return new CustomCallbackMacro(MacroName.TOGGLE_FACEGAZE, () => {
+          this.mouseController_.togglePaused();
+          this.togglePaused();
+        });
       default:
         return;
     }
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/facegaze/mouse_controller.ts b/chrome/browser/resources/chromeos/accessibility/accessibility_common/facegaze/mouse_controller.ts
index 8ff260e..b869330 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/facegaze/mouse_controller.ts
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/facegaze/mouse_controller.ts
@@ -55,6 +55,7 @@
   private mouseInterval_: number = -1;
   private lastMouseMovedTime_: number = 0;
   private landmarkWeights_: Map<string, number>;
+  private paused_ = false;
 
   constructor() {
     this.onMouseMovedHandler_ = new EventHandler(
@@ -85,6 +86,7 @@
   }
 
   async start(): Promise<void> {
+    this.paused_ = false;
     chrome.settingsPrivate.getAllPrefs(prefs => this.updateFromPrefs_(prefs));
     chrome.settingsPrivate.onPrefsChanged.addListener(this.prefsListener_);
 
@@ -121,10 +123,8 @@
    * Update the current location of the tracked face landmark.
    */
   onFaceLandmarkerResult(result: FaceLandmarkerResult): void {
-    if (!this.screenBounds_) {
-      return;
-    }
-    if (!result.faceLandmarks || !result.faceLandmarks[0]) {
+    if (this.paused_ || !this.screenBounds_ || !result.faceLandmarks ||
+        !result.faceLandmarks[0]) {
       return;
     }
 
@@ -186,7 +186,7 @@
    * to its previous location.
    */
   private updateMouseLocation_(): void {
-    if (!this.lastLandmarkLocation_ || !this.mouseLocation_ ||
+    if (this.paused_ || !this.lastLandmarkLocation_ || !this.mouseLocation_ ||
         !this.screenBounds_) {
       return;
     }
@@ -260,7 +260,7 @@
   }
 
   resetLocation(): void {
-    if (!this.screenBounds_) {
+    if (this.paused_ || !this.screenBounds_) {
       return;
     }
     const x =
@@ -286,9 +286,18 @@
     this.previousSmoothedLocation_ = undefined;
     this.lastMouseMovedTime_ = 0;
     this.buffer_ = [];
+    this.paused_ = false;
     chrome.settingsPrivate.onPrefsChanged.removeListener(this.prefsListener_);
   }
 
+  togglePaused(): void {
+    const newPaused = !this.paused_;
+    // Run start/stop before assigning the new pause value, since start/stop
+    // will modify the pause value.
+    newPaused ? this.stop() : this.start();
+    this.paused_ = newPaused;
+  }
+
   /** Listener for when the mouse position changes. */
   private onMouseMovedOrDragged_(event: chrome.automation.AutomationEvent):
       void {
diff --git a/chrome/browser/resources/chromeos/accessibility/common/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/common/BUILD.gn
index 7782e81..8573521 100644
--- a/chrome/browser/resources/chromeos/accessibility/common/BUILD.gn
+++ b/chrome/browser/resources/chromeos/accessibility/common/BUILD.gn
@@ -39,19 +39,20 @@
 ts_modules = [
   "action_fulfillment/context_checker.ts",
   "action_fulfillment/input_controller.ts",
-  "action_fulfillment/macros/mouse_click_macro.ts",
+  "action_fulfillment/macros/custom_callback_macro.ts",
   "action_fulfillment/macros/delete_prev_sent_macro.ts",
-  "action_fulfillment/macros/toggle_dictation_macro.ts",
   "action_fulfillment/macros/input_text_view_macro.ts",
-  "action_fulfillment/macros/macro.ts",
-  "action_fulfillment/macros/nav_sent_macro.ts",
   "action_fulfillment/macros/key_press_macro.ts",
+  "action_fulfillment/macros/macro.ts",
+  "action_fulfillment/macros/mouse_click_macro.ts",
+  "action_fulfillment/macros/nav_sent_macro.ts",
   "action_fulfillment/macros/repeat_macro.ts",
   "action_fulfillment/macros/repeatable_key_press_macro.ts",
   "action_fulfillment/macros/smart_delete_phrase_macro.ts",
   "action_fulfillment/macros/smart_insert_before_macro.ts",
   "action_fulfillment/macros/smart_replace_phrase_macro.ts",
   "action_fulfillment/macros/smart_select_between_macro.ts",
+  "action_fulfillment/macros/toggle_dictation_macro.ts",
   "array_util.ts",
   "automation_predicate.ts",
   "automation_util.ts",
diff --git a/chrome/browser/resources/chromeos/accessibility/common/action_fulfillment/macros/custom_callback_macro.ts b/chrome/browser/resources/chromeos/accessibility/common/action_fulfillment/macros/custom_callback_macro.ts
new file mode 100644
index 0000000..0a9c94d3
--- /dev/null
+++ b/chrome/browser/resources/chromeos/accessibility/common/action_fulfillment/macros/custom_callback_macro.ts
@@ -0,0 +1,21 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {Macro, RunMacroResult} from './macro.js';
+import {MacroName} from './macro_names.js';
+
+/** Class that implements a macro that runs the supplied callback. */
+export class CustomCallbackMacro extends Macro {
+  private callback_: () => void;
+
+  constructor(macroName: MacroName, callback: () => void) {
+    super(macroName);
+    this.callback_ = callback;
+  }
+
+  override run(): RunMacroResult {
+    this.callback_();
+    return this.createRunMacroResult_(/*isSuccess=*/ true);
+  }
+}
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ta.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ta.xtb
index a4f44f1..e8274860 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ta.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_ta.xtb
@@ -230,7 +230,7 @@
 <translation id="2592212930811759050">திருத்துவதற்கு, இருமுறை தட்டவும்</translation>
 <translation id="2598495320872286378">இலக்கணப் பிழை</translation>
 <translation id="2603828437139726540">முந்தைய எழுத்துக்குச் செல்</translation>
-<translation id="2619052155095999743">செருகு</translation>
+<translation id="2619052155095999743">சேர்</translation>
 <translation id="2619344480613750862">திரையில் உள்ள பிரிவுகளுக்கு இடையேயும் மாறலாம். எடுத்துக்காட்டு: தொடக்கி, ஷெல்ஃப், Chrome தாவல்கள் ஆகியவற்றுக்கு இடையே மாறலாம். அடுத்த பிரிவுக்குச் செல்ல, நான்கு விரல்களால் இடதுபுறத்திலிருந்து வலதுபுறம் ஸ்வைப் செய்யலாம். தொடர, இப்போதே செய்து பாருங்கள்.</translation>
 <translation id="2624431853467395961">கற்றல் பயன்முறையைத் திறக்கவும்</translation>
 <translation id="2626530649491650971">கிளிக் செய்யத்தக்கது</translation>
diff --git a/chrome/browser/resources/downloads/item.html b/chrome/browser/resources/downloads/item.html
index 191ce3b..c82b314 100644
--- a/chrome/browser/resources/downloads/item.html
+++ b/chrome/browser/resources/downloads/item.html
@@ -201,7 +201,7 @@
   }
 
   @media (prefers-color-scheme: light) {
-    .is-active :-webkit-any(#file-link, #show) {
+    .is-active :-webkit-any(#file-link) {
       color: var(--google-blue-600);
     }
 
@@ -291,10 +291,6 @@
     }
   }
 
-  #show {
-    margin: .7em 0;
-  }
-
   #controlled-by,
   #controlled-by a {
     color: var(--controlled-by-inactive-color);
@@ -342,9 +338,6 @@
     width: 16px;
   }
 
-  #pauseOrResume,
-  #dangerous .action-button,
-  #openNow,
   #deepScan {
     margin-inline-end: 8px;
   }
@@ -363,14 +356,12 @@
         aria-hidden="[[computeIconAriaHidden_(iconAriaLabel_)]]">
       <img class="icon" id="file-icon" alt="" hidden="[[!useFileIcon_]]"
           icon-color$="[[computeIconColor_(isDangerous_, data.dangerType,
-          useFileIcon_, improvedDownloadWarningsUx_,
-          displayType_)]]">
+          useFileIcon_, displayType_)]]">
       <iron-icon class="icon" hidden="[[useFileIcon_]]"
           icon$="[[computeIcon_(isDangerous_, data.dangerType, useFileIcon_,
-              improvedDownloadWarningsUx_, displayType_)]]"
+              displayType_)]]"
           icon-color$="[[computeIconColor_(isDangerous_, data.dangerType,
-              useFileIcon_, improvedDownloadWarningsUx_,
-              displayType_)]]"></iron-icon>
+              useFileIcon_, displayType_)]]"></iron-icon>
     </div>
 
     <div id="details">
@@ -398,17 +389,14 @@
       </div>
 
       <div class="description" role="gridcell"
-          description-color$="[[iconAndDescriptionColor_(displayType_,
-              improvedDownloadWarningsUx_)]]"
-          hidden$="[[!computeDescriptionVisible_(data.*, displayType_,
-              improvedDownloadWarningsUx_)]]">
+          description-color$="[[iconAndDescriptionColor_(displayType_)]]"
+          hidden$="[[!computeDescriptionVisible_(data.*, displayType_)]]">
         [[computeDescription_(
             data.state,
             data.dangerType,
             data.fileName,
             data.progressStatusText,
-            displayType_,
-            improvedDownloadWarningsUx_)]]
+            displayType_)]]
       </div>
 
       <div class="description" role="gridcell"
@@ -425,240 +413,103 @@
         </div>
       </template>
 
-      <!-- Show most of the safe control buttons in the old UX only. -->
-      <template is="dom-if" if="[[!improvedDownloadWarningsUx_]]">
-        <div id="safe" class="controls" hidden="[[isDangerous_]]">
-          <span role="gridcell" hidden="[[!hasShowInFolderLink_]]">
-            <a is="action-link" id="show" on-click="onShowClick_"
-                focus-row-control
-                focus-type="show"
-                title="[[data.filePath]]">
-              [[data.showInFolderText]]
-            </a>
-          </span>
-          <template is="dom-if" if="[[data.retry]]">
-            <span role="gridcell">
-              <cr-button class="action-button" on-click="onRetryClick_"
-                  focus-row-control focus-type="retry">
-                $i18n{controlRetry}
-              </cr-button>
-            </span>
-          </template>
-          <template is="dom-if" if="[[pauseOrResumeText_]]">
-            <span role="gridcell">
-              <cr-button on-click="onPauseOrResumeClick_" id="pauseOrResume"
-                  focus-row-control focus-type="pauseOrResume">
-                [[pauseOrResumeText_]]
-              </cr-button>
-            </span>
-          </template>
-          <template is="dom-if" if="[[showDeepScan_]]" restamp>
-            <span role="gridcell">
-              <cr-button on-click="onDeepScanClick_" id="deepScan"
-                  class="action-button" focus-row-control focus-type="open">
-                [[computeDeepScanControlText_(data.state)]]
-              </cr-button>
-            </span>
-            <span role="gridcell">
-              <cr-button on-click="onBypassDeepScanClick_" id="bypassDeepScan"
-                        focus-row-control focus-type="open">
-                $i18n{controlBypassDeepScan}
-              </cr-button>
-            </span>
-          </template>
-          <template is="dom-if" if="[[showCancel_]]">
-            <span role="gridcell">
-              <cr-button on-click="onCancelClick_" focus-row-control
-                  focus-type="cancel">
-                $i18n{controlCancel}
-              </cr-button>
-            </span>
-          </template>
-          <template is="dom-if" if="[[showOpenAnyway_]]">
-            <span role="gridcell">
-              <cr-button on-click="onOpenAnywayClick_" id="openAnyway"
-                  focus-row-control focus-type="open">
-                $i18n{controlOpenAnyway}
-              </cr-button>
-            </span>
-          </template>
-        </div>
-      </template>
-      <!-- Only this button should appear for improvedDownloadWarningsUx. -->
-      <template is="dom-if" if="[[improvedDownloadWarningsUx_]]">
-        <div id="safe" class="controls" hidden="[[isDangerous_]]">
-          <template is="dom-if" if="[[showDeepScan_]]" restamp>
-            <span role="gridcell">
-              <cr-button on-click="onDeepScanClick_" id="deepScan"
-                  class="action-button" focus-row-control focus-type="open">
-                [[computeDeepScanControlText_(data.state)]]
-              </cr-button>
-            </span>
-          </template>
-        </div>
-      </template>
+      <div id="safe" class="controls" hidden="[[isDangerous_]]">
+        <span role="gridcell" hidden="[[!showDeepScan_]]">
+          <cr-button on-click="onDeepScanClick_" id="deepScan"
+              class="action-button" focus-row-control focus-type="open">
+            [[computeDeepScanControlText_(data.state)]]
+          </cr-button>
+        </span>
+      </div>
       <div id="controlled-by" hidden="[[isDangerous_]]"><!--
         Text populated dynamically.
       --></div>
-
-      <!-- Show the dangerous control buttons in the old UX only. -->
-      <template is="dom-if"
-          if="[[computeShowButtonsForDangerous_(isDangerous_,
-              improvedDownloadWarningsUx_)]]">
-        <div id="dangerous" class="controls">
-          <!-- Files that enterprise policies allow to be reviewed. -->
-          <template is="dom-if" if="[[isReviewable_]]">
-            <span role="gridcell">
-              <cr-button on-click="onDiscardDangerousClick_"
-                  class="action-button" focus-row-control
-                  focus-type="discard">
-                $i18n{dangerDiscard}
-              </cr-button>
-            </span>
-            <span role="gridcell">
-              <cr-button on-click="onReviewDangerousClick_" focus-row-control
-                  focus-type="save">
-                $i18n{dangerReview}
-              </cr-button>
-            </span>
-          </template>
-
-          <template is="dom-if" if="[[!isReviewable_]]">
-            <!-- Dangerous file types (e.g. .exe, .jar). -->
-            <template is="dom-if" if="[[!isMalware_]]">
-              <span role="gridcell">
-                <cr-button on-click="onDiscardDangerousClick_"
-                    class="action-button" focus-row-control
-                    focus-type="discard">
-                  $i18n{dangerDiscard}
-                </cr-button>
-              </span>
-              <span role="gridcell">
-                <cr-button on-click="onSaveDangerousClick_" focus-row-control
-                    focus-type="save">
-                  $i18n{dangerSave}
-                </cr-button>
-              </span>
-            </template>
-
-            <!-- Things that safe browsing has determined to be dangerous. -->
-            <template is="dom-if" if="[[isMalware_]]">
-              <span role="gridcell">
-                <cr-button on-click="onDiscardDangerousClick_"
-                    class="action-button"
-                    focus-row-control focus-type="discard">
-                  $i18n{controlRemoveFromList}
-                </cr-button>
-              </span>
-              <span role="gridcell">
-                <cr-button on-click="onSaveDangerousClick_" focus-row-control
-                    focus-type="save">
-                  $i18n{dangerRestore}
-                </cr-button>
-              </span>
-            </template>
-          </template>
-        </div>
-      </template>
     </div>
     <div class="more-options">
-      <!-- Only show the "x" button in the old UX. -->
-      <template is="dom-if" if="[[!improvedDownloadWarningsUx_]]">
-        <div role="gridcell">
-          <cr-icon-button class="icon-clear"
-              style$="[[computeRemoveStyle_(isDangerous_, showCancel_)]]"
-              id="remove-old" title="$i18n{controlRemoveFromList}"
-              aria-label$="[[controlRemoveFromListAriaLabel_]]"
-              on-click="onRemoveClick_" focus-row-control focus-type="remove">
-          </cr-icon-button>
-        </div>
-      </template>
-      <!-- In improvedDownloadWarnings, show menu and/or quick action(s). -->
-      <template is="dom-if" if="[[improvedDownloadWarningsUx_]]">
-        <div role="gridcell" id="action-icon-buttons">
-          <cr-icon-button id="more-actions" iron-icon="cr:more-vert"
-              hidden="[[!computeShowActionMenu_(pauseOrResumeText_,
-                  isDangerous_, isReviewable_, showDeepScan_, showCancel_,
-                  showOpenAnyway_, data.state, data.retry, data.dangerType)]]"
-              class="dropdown-trigger" title="$i18n{moreActions}"
-              on-click="onMoreActionsClick_" aria-haspopup="menu"
-              focus-row-control focus-type="actionMenuButton">
-          </cr-icon-button>
-          <cr-icon-button id="quick-show-in-folder" class="icon-folder-open"
-              hidden="[[!computeShowQuickShow_(hasShowInFolderLink_,
-                  pauseOrResumeText_, isDangerous_, isReviewable_,
-                  showDeepScan_, showCancel_, showOpenAnyway_, data.state,
-                  data.retry, data.dangerType)]]"
-              title="[[data.showInFolderText]]"
-              aria-label$="[[data.showInFolderText]]" on-click="onShowClick_"
-              focus-row-control focus-type="quickShow">
-          </cr-icon-button>
-          <cr-icon-button id="quick-remove" class="icon-clear"
-              hidden="[[!computeShowQuickRemove_(isDangerous_, showCancel_,
-                  isReviewable_)]]"
-              title="$i18n{controlDeleteFromHistory}"
-              aria-label$="$i18n{controlDeleteFromHistory}"
-              on-click="onQuickRemoveClick_"
-              focus-row-control focus-type="quickRemove">
-          </cr-icon-button>
-        </div>
-        <cr-action-menu id="more-actions-menu"
-            role-description="$i18n{actionMenuDescription}">
-          <button class="dropdown-item" on-click="onShowClick_"
-              hidden="[[!hasShowInFolderLink_]]" id="show-in-folder">
-            [[data.showInFolderText]]
-          </button>
-          <button class="dropdown-item" on-click="onPauseOrResumeClick_"
-              hidden="[[!pauseOrResumeText_]]" id="pause-or-resume">
-            [[pauseOrResumeText_]]
-          </button>
-          <button class="dropdown-item" on-click="onRemoveClick_"
-              hidden="[[!computeShowRemove_(isDangerous_, showCancel_)]]"
-              id="remove">
-            $i18n{controlDeleteFromHistory}
-          </button>
-          <button class="dropdown-item" on-click="onDiscardDangerousClick_"
-              hidden="[[!computeShowControlsForDangerous_(isDangerous_,
-                      isReviewable_)]]"
-              id="discard-dangerous">
-            $i18n{controlDeleteFromHistory}
-          </button>
-          <button class="dropdown-item" on-click="onRetryClick_"
-              hidden="[[!data.retry]]" id="retry">
-            $i18n{controlRetry}
-          </button>
-          <button class="dropdown-item" on-click="onDeepScanClick_"
-              hidden="[[!showDeepScan_]]" id="deep-scan">
-            $i18n{controlDeepScan}
-          </button>
-          <button class="dropdown-item" on-click="onBypassDeepScanClick_"
-              hidden="[[!showDeepScan_]]" id="bypass-deep-scan">
-            [[computeSaveDangerousLabel_(displayType_)]]
-          </button>
-          <button class="dropdown-item" on-click="onCancelClick_"
-              hidden="[[!showCancel_]]" id="cancel">
-            $i18n{controlCancel}
-          </button>
-          <button class="dropdown-item" on-click="onOpenAnywayClick_"
-              hidden="[[!showOpenAnyway_]]" id="open-anyway">
-            $i18n{controlOpenAnyway}
-          </button>
-          <button class="dropdown-item" on-click="onDiscardDangerousClick_"
-              hidden="[[!isReviewable_]]" id="reviewable-discard-dangerous">
-            $i18n{dangerDiscard}
-          </button>
-          <button class="dropdown-item" on-click="onReviewDangerousClick_"
-              hidden="[[!isReviewable_]]" id="review-dangerous">
-            $i18n{dangerReview}
-          </button>
-          <button class="dropdown-item" on-click="onSaveDangerousClick_"
-              hidden="[[!computeShowControlsForDangerous_(isDangerous_,
-                      isReviewable_)]]"
-              id="save-dangerous">
-            [[computeSaveDangerousLabel_(displayType_)]]
-          </button>
-        </cr-action-menu>
-      </template>
+      <!-- Menu and/or quick action(s). -->
+      <div role="gridcell" id="action-icon-buttons">
+        <cr-icon-button id="more-actions" iron-icon="cr:more-vert"
+            hidden="[[!computeShowActionMenu_(pauseOrResumeText_,
+                isDangerous_, isReviewable_, showDeepScan_, showCancel_,
+                showOpenAnyway_, data.state, data.retry, data.dangerType)]]"
+            class="dropdown-trigger" title="$i18n{moreActions}"
+            on-click="onMoreActionsClick_" aria-haspopup="menu"
+            focus-row-control focus-type="actionMenuButton">
+        </cr-icon-button>
+        <cr-icon-button id="quick-show-in-folder" class="icon-folder-open"
+            hidden="[[!computeShowQuickShow_(hasShowInFolderLink_,
+                pauseOrResumeText_, isDangerous_, isReviewable_,
+                showDeepScan_, showCancel_, showOpenAnyway_, data.state,
+                data.retry, data.dangerType)]]"
+            title="[[data.showInFolderText]]"
+            aria-label$="[[data.showInFolderText]]" on-click="onShowClick_"
+            focus-row-control focus-type="quickShow">
+        </cr-icon-button>
+        <cr-icon-button id="quick-remove" class="icon-clear"
+            hidden="[[!computeShowQuickRemove_(isDangerous_, showCancel_,
+                isReviewable_)]]"
+            title="$i18n{controlDeleteFromHistory}"
+            aria-label$="$i18n{controlDeleteFromHistory}"
+            on-click="onQuickRemoveClick_"
+            focus-row-control focus-type="quickRemove">
+        </cr-icon-button>
+      </div>
+      <cr-action-menu id="more-actions-menu"
+          role-description="$i18n{actionMenuDescription}">
+        <button class="dropdown-item" on-click="onShowClick_"
+            hidden="[[!hasShowInFolderLink_]]" id="show-in-folder">
+          [[data.showInFolderText]]
+        </button>
+        <button class="dropdown-item" on-click="onPauseOrResumeClick_"
+            hidden="[[!pauseOrResumeText_]]" id="pause-or-resume">
+          [[pauseOrResumeText_]]
+        </button>
+        <button class="dropdown-item" on-click="onRemoveClick_"
+            hidden="[[!computeShowRemove_(isDangerous_, showCancel_)]]"
+            id="remove">
+          $i18n{controlDeleteFromHistory}
+        </button>
+        <button class="dropdown-item" on-click="onDiscardDangerousClick_"
+            hidden="[[!computeShowControlsForDangerous_(isDangerous_,
+                    isReviewable_)]]"
+            id="discard-dangerous">
+          $i18n{controlDeleteFromHistory}
+        </button>
+        <button class="dropdown-item" on-click="onRetryClick_"
+            hidden="[[!data.retry]]" id="retry">
+          $i18n{controlRetry}
+        </button>
+        <button class="dropdown-item" on-click="onDeepScanClick_"
+            hidden="[[!showDeepScan_]]" id="deep-scan">
+          $i18n{controlDeepScan}
+        </button>
+        <button class="dropdown-item" on-click="onBypassDeepScanClick_"
+            hidden="[[!showDeepScan_]]" id="bypass-deep-scan">
+          [[computeSaveDangerousLabel_(displayType_)]]
+        </button>
+        <button class="dropdown-item" on-click="onCancelClick_"
+            hidden="[[!showCancel_]]" id="cancel">
+          $i18n{controlCancel}
+        </button>
+        <button class="dropdown-item" on-click="onOpenAnywayClick_"
+            hidden="[[!showOpenAnyway_]]" id="open-anyway">
+          $i18n{controlOpenAnyway}
+        </button>
+        <button class="dropdown-item" on-click="onDiscardDangerousClick_"
+            hidden="[[!isReviewable_]]" id="reviewable-discard-dangerous">
+          $i18n{dangerDiscard}
+        </button>
+        <button class="dropdown-item" on-click="onReviewDangerousClick_"
+            hidden="[[!isReviewable_]]" id="review-dangerous">
+          $i18n{dangerReview}
+        </button>
+        <button class="dropdown-item" on-click="onSaveDangerousClick_"
+            hidden="[[!computeShowControlsForDangerous_(isDangerous_,
+                    isReviewable_)]]"
+            id="save-dangerous">
+          [[computeSaveDangerousLabel_(displayType_)]]
+        </button>
+      </cr-action-menu>
       <div id="incognito" title="$i18n{inIncognito}" hidden="[[!data.otr]]">
       </div>
     </div>
diff --git a/chrome/browser/resources/downloads/item.ts b/chrome/browser/resources/downloads/item.ts
index 3325885f..f241930 100644
--- a/chrome/browser/resources/downloads/item.ts
+++ b/chrome/browser/resources/downloads/item.ts
@@ -34,7 +34,7 @@
 import {sanitizeInnerHtml} from 'chrome://resources/js/parse_html_subset.js';
 import {htmlEscape} from 'chrome://resources/js/util.js';
 import type {String16} from 'chrome://resources/mojo/mojo/public/mojom/base/string16.mojom-webui.js';
-import {beforeNextRender, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {BrowserProxy} from './browser_proxy.js';
 import type {MojomData} from './data.js';
@@ -108,15 +108,9 @@
         value: '',
       },
 
-      controlRemoveFromListAriaLabel_: {
-        type: String,
-        computed: 'computeControlRemoveFromListAriaLabel_(data.fileName)',
-      },
-
       iconAriaLabel_: {
         type: String,
-        computed: 'computeIconAriaLabel_(' +
-            'displayType_, improvedDownloadWarningsUx_)',
+        computed: 'computeIconAriaLabel_(displayType_)',
       },
 
       isActive_: {
@@ -187,11 +181,6 @@
         value: DisplayType.NORMAL,
       },
 
-      improvedDownloadWarningsUx_: {
-        type: Boolean,
-        value: () => loadTimeData.getBoolean('improvedDownloadWarningsUX'),
-      },
-
       // <if expr="_google_chrome">
       showEsbPromotion: {
         type: Boolean,
@@ -215,7 +204,6 @@
       'observeControlledBy_(controlledBy_)',
       'observeDisplayType_(displayType_, isDangerous_, data.*)',
       'restoreFocusAfterCancelIfNeeded_(data)',
-      'updatePauseOrResumeClass_(pauseOrResumeText_, improvedDownloadWarningsUx_)',
     ];
   }
 
@@ -238,7 +226,6 @@
   private useFileIcon_: boolean;
   private restoreFocusAfterCancel_: boolean = false;
   private displayType_: DisplayType;
-  private improvedDownloadWarningsUx_: boolean;
   private completelyOnDisk_: boolean;
   override overrideCustomEquivalent: boolean;
 
@@ -272,14 +259,12 @@
   }
 
   getMoreActionsButton(): CrIconButtonElement|null {
-    assert(this.improvedDownloadWarningsUx_);
     const button =
         this.shadowRoot!.querySelector<CrIconButtonElement>('#more-actions');
     return button || null;
   }
 
   getMoreActionsMenu(): CrActionMenuElement {
-    assert(this.improvedDownloadWarningsUx_);
     const menu = this.shadowRoot!.querySelector<CrActionMenuElement>(
         '#more-actions-menu');
     assert(!!menu);
@@ -344,11 +329,6 @@
     return loadTimeData.getStringF('controlledByUrl', url, htmlEscape(name));
   }
 
-  private computeControlRemoveFromListAriaLabel_(): string {
-    return loadTimeData.getStringF(
-        'controlRemoveFromListAriaLabel', this.data.fileName);
-  }
-
   private computeDate_(): string {
     assert(typeof this.data.hideDate === 'boolean');
     if (this.data.hideDate) {
@@ -534,51 +514,46 @@
   }
 
   private computeIconAriaLabel_(): string {
-    if (this.improvedDownloadWarningsUx_) {
-      switch (this.displayType_) {
-        case DisplayType.DANGEROUS:
-          return this.i18n('accessibleLabelDangerous');
-        case DisplayType.INSECURE:
-          return this.i18n('accessibleLabelInsecure');
-        case DisplayType.UNVERIFIED:
-          return this.i18n('accessibleLabelUnverified');
-        case DisplayType.SUSPICIOUS:
-          return this.i18n('accessibleLabelSuspicious');
-      }
+    switch (this.displayType_) {
+      case DisplayType.DANGEROUS:
+        return this.i18n('accessibleLabelDangerous');
+      case DisplayType.INSECURE:
+        return this.i18n('accessibleLabelInsecure');
+      case DisplayType.UNVERIFIED:
+        return this.i18n('accessibleLabelUnverified');
+      case DisplayType.SUSPICIOUS:
+        return this.i18n('accessibleLabelSuspicious');
     }
     return '';
   }
 
   private iconAndDescriptionColor_(): string {
-    if (this.improvedDownloadWarningsUx_) {
-      switch (this.displayType_) {
-        case DisplayType.DANGEROUS:
-        case DisplayType.ERROR:
-          return 'red';
-        case DisplayType.INSECURE:
-        case DisplayType.UNVERIFIED:
-        case DisplayType.SUSPICIOUS:
-          return 'grey';
-      }
+    switch (this.displayType_) {
+      case DisplayType.DANGEROUS:
+      case DisplayType.ERROR:
+        return 'red';
+      case DisplayType.INSECURE:
+      case DisplayType.UNVERIFIED:
+      case DisplayType.SUSPICIOUS:
+        return 'grey';
     }
     return '';
   }
 
   private computeIcon_(): string {
     if (this.data) {
-      if (this.improvedDownloadWarningsUx_) {
-        switch (this.displayType_) {
-          case DisplayType.DANGEROUS:
-            return 'downloads:dangerous';
-          case DisplayType.INSECURE:
-          case DisplayType.UNVERIFIED:
-          case DisplayType.SUSPICIOUS:
-            return 'cr:warning';
-          case DisplayType.ERROR:
-            return 'cr:error';
-        }
+      switch (this.displayType_) {
+        case DisplayType.DANGEROUS:
+          return 'downloads:dangerous';
+        case DisplayType.INSECURE:
+        case DisplayType.UNVERIFIED:
+        case DisplayType.SUSPICIOUS:
+          return 'cr:warning';
+        case DisplayType.ERROR:
+          return 'cr:error';
       }
 
+      assert(this.displayType_ === DisplayType.NORMAL);
       const dangerType = this.data.dangerType as DangerType;
       if ((loadTimeData.getBoolean('requestsApVerdicts') &&
            dangerType === DangerType.kUncommonContent) ||
@@ -606,8 +581,7 @@
       }
     }
     if (this.isDangerous_) {
-      return this.improvedDownloadWarningsUx_ ? 'downloads:dangerous' :
-                                                'cr:error';
+      return 'downloads:dangerous';
     }
     if (!this.useFileIcon_) {
       return 'cr:insert-drive-file';
@@ -617,31 +591,7 @@
 
   private computeIconColor_(): string {
     if (this.data) {
-      if (this.improvedDownloadWarningsUx_) {
-        return this.iconAndDescriptionColor_();
-      }
-      const dangerType = this.data.dangerType as DangerType;
-      if ((loadTimeData.getBoolean('requestsApVerdicts') &&
-           dangerType === DangerType.kUncommonContent) ||
-          dangerType === DangerType.kSensitiveContentWarning ||
-          dangerType === DangerType.kDeepScannedFailed) {
-        return 'yellow';
-      }
-
-      const WARNING_TYPES = [
-        DangerType.kSensitiveContentBlock,
-        DangerType.kBlockedTooLarge,
-        DangerType.kBlockedPasswordProtected,
-      ];
-      if (WARNING_TYPES.includes(dangerType)) {
-        return 'red';
-      }
-
-      if (this.data.state === State.kAsyncScanning ||
-          this.data.state === State.kPromptForScanning ||
-          this.data.state === State.kPromptForLocalPasswordScanning) {
-        return 'yellow';
-      }
+      return this.iconAndDescriptionColor_();
     }
     if (this.isDangerous_) {
       return 'red';
@@ -679,22 +629,6 @@
     return this.data.isReviewable;
   }
 
-  private toggleButtonClass_() {
-    this.shadowRoot!.querySelector('#pauseOrResume')!.classList.toggle(
-        'action-button',
-        this.pauseOrResumeText_ === loadTimeData.getString('controlResume'));
-  }
-
-  private updatePauseOrResumeClass_() {
-    if (!this.pauseOrResumeText_ || this.improvedDownloadWarningsUx_) {
-      return;
-    }
-
-    // Wait for dom-if to switch to true, in case the text has just changed
-    // from empty.
-    beforeNextRender(this, () => this.toggleButtonClass_());
-  }
-
   private computePauseOrResumeText_(): string {
     if (this.data === undefined) {
       return '';
@@ -723,10 +657,6 @@
     return !this.isReviewable_ && this.isDangerous_;
   }
 
-  private computeShowButtonsForDangerous_(): boolean {
-    return !this.improvedDownloadWarningsUx_ && this.isDangerous_;
-  }
-
   private computeShowCancel_(): boolean {
     return !!this.data &&
         (this.data.state === State.kInProgress ||
@@ -853,36 +783,12 @@
     // Returns whether to use the file icon, and additionally clears file url
     // links if necessary.
     const mayUseFileIcon = () => {
-      if (this.improvedDownloadWarningsUx_) {
-        const use = this.displayType_ === DisplayType.NORMAL;
-        if (!use) {
-          removeFileUrlLinks();
-          updateReferrerUrlLinkHref();
-        }
-        return use;
-      }
-
-      // Handle various dangerous cases.
-      const OVERRIDDEN_ICON_TYPES = [
-        DangerType.kSensitiveContentBlock,
-        DangerType.kBlockedTooLarge,
-        DangerType.kBlockedPasswordProtected,
-        DangerType.kDeepScannedFailed,
-      ];
-      if (this.isDangerous_) {
+      const use = this.displayType_ === DisplayType.NORMAL;
+      if (!use) {
         removeFileUrlLinks();
         updateReferrerUrlLinkHref();
-        return false;
       }
-      if (OVERRIDDEN_ICON_TYPES.includes(this.data.dangerType as DangerType)) {
-        return false;
-      }
-      if (this.data.state === State.kAsyncScanning ||
-          this.data.state === State.kPromptForScanning ||
-          this.data.state === State.kPromptForLocalPasswordScanning) {
-        return false;
-      }
-      return true;
+      return use;
     };
 
     this.useFileIcon_ = mayUseFileIcon();
@@ -925,7 +831,6 @@
   // </if>
 
   private onMoreActionsClick_() {
-    assert(this.improvedDownloadWarningsUx_);
     const button = this.getMoreActionsButton();
     // The menu button is not always shown, but if this handler is invoked, then
     // it must be.
@@ -936,7 +841,6 @@
   // Handles the "x" remove button which can be different actions depending on
   // the state of the download.
   private onQuickRemoveClick_(e: Event) {
-    assert(this.improvedDownloadWarningsUx_);
     if (this.isReviewable_ || this.computeShowControlsForDangerous_()) {
       this.onDiscardDangerousClick_(e);
       return;
@@ -949,55 +853,41 @@
     this.restoreFocusAfterCancel_ = true;
     assert(!!this.mojoHandler_);
     this.mojoHandler_.cancel(this.data.id);
-    if (this.improvedDownloadWarningsUx_) {
-      getAnnouncerInstance().announce(
-          loadTimeData.getString('screenreaderCanceled'));
-      this.getMoreActionsMenu().close();
-    }
+    getAnnouncerInstance().announce(
+        loadTimeData.getString('screenreaderCanceled'));
+    this.getMoreActionsMenu().close();
   }
 
   private onDiscardDangerousClick_(e: Event) {
     assert(!!this.mojoHandler_);
     this.mojoHandler_.discardDangerous(this.data.id);
-    if (this.improvedDownloadWarningsUx_) {
-      this.displayRemovedToast_(/*canUndo=*/ false, e);
-      this.getMoreActionsMenu().close();
-    }
+    this.displayRemovedToast_(/*canUndo=*/ false, e);
+    this.getMoreActionsMenu().close();
   }
 
   private onOpenNowClick_() {
     this.mojoHandler_!.openDuringScanningRequiringGesture(this.data.id);
-    if (this.improvedDownloadWarningsUx_) {
-      this.getMoreActionsMenu().close();
-    }
+    this.getMoreActionsMenu().close();
   }
 
   private onDeepScanClick_() {
     this.mojoHandler_!.deepScan(this.data.id);
-    if (this.improvedDownloadWarningsUx_) {
-      this.getMoreActionsMenu().close();
-    }
+    this.getMoreActionsMenu().close();
   }
 
   private onBypassDeepScanClick_() {
     this.mojoHandler_!.bypassDeepScanRequiringGesture(this.data.id);
-    if (this.improvedDownloadWarningsUx_) {
-      this.getMoreActionsMenu().close();
-    }
+    this.getMoreActionsMenu().close();
   }
 
   private onReviewDangerousClick_() {
     this.mojoHandler_!.reviewDangerousRequiringGesture(this.data.id);
-    if (this.improvedDownloadWarningsUx_) {
-      this.getMoreActionsMenu().close();
-    }
+    this.getMoreActionsMenu().close();
   }
 
   private onOpenAnywayClick_() {
     this.mojoHandler_!.openFileRequiringGesture(this.data.id);
-    if (this.improvedDownloadWarningsUx_) {
-      this.getMoreActionsMenu().close();
-    }
+    this.getMoreActionsMenu().close();
   }
 
   private onDragStart_(e: Event) {
@@ -1021,19 +911,15 @@
   private doPause_() {
     assert(!!this.mojoHandler_);
     this.mojoHandler_.pause(this.data.id);
-    if (this.improvedDownloadWarningsUx_) {
-      getAnnouncerInstance().announce(
-          loadTimeData.getString('screenreaderPaused'));
-    }
+    getAnnouncerInstance().announce(
+        loadTimeData.getString('screenreaderPaused'));
   }
 
   private doResume_() {
     assert(!!this.mojoHandler_);
     this.mojoHandler_.resume(this.data.id);
-    if (this.improvedDownloadWarningsUx_) {
-      getAnnouncerInstance().announce(
-          loadTimeData.getString('screenreaderResumed'));
-    }
+    getAnnouncerInstance().announce(
+        loadTimeData.getString('screenreaderResumed'));
   }
 
   private onPauseOrResumeClick_() {
@@ -1042,17 +928,14 @@
     } else {
       this.doResume_();
     }
-    if (this.improvedDownloadWarningsUx_) {
-      this.getMoreActionsMenu().close();
-    }
+    this.getMoreActionsMenu().close();
   }
 
   private displayRemovedToast_(canUndo: boolean, e: Event) {
-    const templateStringId = this.improvedDownloadWarningsUx_ ?
-        (this.displayType_ === DisplayType.NORMAL && this.completelyOnDisk_ ?
-             'toastDeletedFromHistoryStillOnDevice' :
-             'toastDeletedFromHistory') :
-        'toastRemovedFromList';
+    const templateStringId =
+        (this.displayType_ === DisplayType.NORMAL && this.completelyOnDisk_) ?
+        'toastDeletedFromHistoryStillOnDevice' :
+        'toastDeletedFromHistory';
     const pieces =
         loadTimeData.getSubstitutedStringPieces(
             loadTimeData.getString(templateStringId), this.data.fileName) as
@@ -1074,17 +957,12 @@
     this.mojoHandler_.remove(this.data.id);
     const canUndo = !this.data.isDangerous && !this.data.isInsecure;
     this.displayRemovedToast_(canUndo, e);
-
-    if (this.improvedDownloadWarningsUx_) {
-      this.getMoreActionsMenu().close();
-    }
+    this.getMoreActionsMenu().close();
   }
 
   private onRetryClick_() {
     this.mojoHandler_!.retryDownload(this.data.id);
-    if (this.improvedDownloadWarningsUx_) {
-      this.getMoreActionsMenu().close();
-    }
+    this.getMoreActionsMenu().close();
   }
 
   private notifySaveDangerousClick_() {
@@ -1096,12 +974,6 @@
   }
 
   private onSaveDangerousClick_() {
-    // TODO(chlily): Remove this branch. It is only reachable in tests while
-    // cleanup is in progress.
-    if (!this.improvedDownloadWarningsUx_) {
-      return;
-    }
-
     this.getMoreActionsMenu().close();
 
     if (this.displayType_ === DisplayType.DANGEROUS) {
@@ -1127,9 +999,7 @@
 
   private onShowClick_() {
     this.mojoHandler_!.show(this.data.id);
-    if (this.improvedDownloadWarningsUx_) {
-      this.getMoreActionsMenu().close();
-    }
+    this.getMoreActionsMenu().close();
   }
 
   private restoreFocusAfterCancelIfNeeded_() {
diff --git a/chrome/browser/resources/lens/overlay/BUILD.gn b/chrome/browser/resources/lens/overlay/BUILD.gn
index 83a50c1..18abdf17 100644
--- a/chrome/browser/resources/lens/overlay/BUILD.gn
+++ b/chrome/browser/resources/lens/overlay/BUILD.gn
@@ -32,6 +32,7 @@
     "learn_more.svg",
     "lens_overlay.html",
     "side_panel/side_panel.html",
+    "sparkles.svg",
   ]
 
   if (is_chrome_branded) {
diff --git a/chrome/browser/resources/lens/overlay/object_layer.ts b/chrome/browser/resources/lens/overlay/object_layer.ts
index 82a26a9..2fd0dae 100644
--- a/chrome/browser/resources/lens/overlay/object_layer.ts
+++ b/chrome/browser/resources/lens/overlay/object_layer.ts
@@ -405,10 +405,12 @@
       return;
     }
 
-    let leftMostPoint = 0;
-    let rightMostPoint = 0;
-    let topMostPoint = 0;
-    let bottomMostPoint = 0;
+    const firstVertex = polygons[0].vertex[0];
+    let topMostPoint = firstVertex.y;
+    let bottomMostPoint = firstVertex.y;
+    let leftMostPoint = firstVertex.x;
+    let rightMostPoint = firstVertex.x;
+
     for (const polygon of polygons) {
       // TODO(b/330183480): Currently, we are assuming that polygon
       // coordinates are normalized. We should still implement
@@ -417,12 +419,6 @@
         continue;
       }
 
-      const firstVertex = polygon.vertex[0];
-      topMostPoint = firstVertex.y;
-      bottomMostPoint = firstVertex.y;
-      leftMostPoint = firstVertex.x;
-      rightMostPoint = firstVertex.x;
-
       for (const vertex of polygon.vertex.slice(1)) {
         topMostPoint = Math.min(topMostPoint, vertex.y);
         bottomMostPoint = Math.max(bottomMostPoint, vertex.y);
diff --git a/chrome/browser/resources/lens/overlay/overlay_shimmer_canvas.html b/chrome/browser/resources/lens/overlay/overlay_shimmer_canvas.html
index 87f1b39..ea258334e 100644
--- a/chrome/browser/resources/lens/overlay/overlay_shimmer_canvas.html
+++ b/chrome/browser/resources/lens/overlay/overlay_shimmer_canvas.html
@@ -8,6 +8,14 @@
     height: 100%;
     width: 100%;
   }
+
+  #sparklesImgContainer {
+    display: none;
+  }
 </style>
 <canvas id="shaderCanvas"
     style$="height: [[canvasHeight]]px; width: [[canvasWidth]]px;"></canvas>
+<!-- Provides image source for canvas; element is not displayed. -->
+<div id="sparklesImgContainer">
+  <image id="sparklesSvg" src="sparkles.svg" on-load="onSparklesLoad">
+</div>
diff --git a/chrome/browser/resources/lens/overlay/overlay_shimmer_canvas.ts b/chrome/browser/resources/lens/overlay/overlay_shimmer_canvas.ts
index 7ef2110c..d43dd9f 100644
--- a/chrome/browser/resources/lens/overlay/overlay_shimmer_canvas.ts
+++ b/chrome/browser/resources/lens/overlay/overlay_shimmer_canvas.ts
@@ -4,6 +4,7 @@
 
 import {assert, assertNotReached} from '//resources/js/assert.js';
 import {EventTracker} from '//resources/js/event_tracker.js';
+import {loadTimeData} from '//resources/js/load_time_data.js';
 import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {BrowserProxyImpl} from './browser_proxy.js';
@@ -95,6 +96,11 @@
 // selection state.
 const REGION_SELECTION_TRANSITION_DURATION = 750;
 
+// The opacity of the sparkles. The sparkles opacity also is dictated by the
+// circle pixel opacity below it. Meaning, the true opacity value is
+// SPARKLES_OPACITY * CIRCLE_OPACITY.
+const SPARKLES_OPACITY = 1;
+
 // Specifies the current animation state of the shader canvas.
 enum ShimmerState {
   NONE = 0,
@@ -195,6 +201,7 @@
 export interface OverlayShimmerCanvasElement {
   $: {
     shaderCanvas: HTMLCanvasElement,
+    sparklesSvg: SVGImageElement,
   };
 }
 
@@ -278,6 +285,18 @@
   private regionWidth: number;
   private regionHeight: number;
 
+  // The sparkles pattern used for rendering the sparkling animation. Created
+  // when the sparkles PNG is loaded in. Null otherwise.
+  private sparklesPattern: CanvasPattern|null = null;
+  // A randomized value every 100ms to transform the sparkles to create
+  // movement.
+  private sparklesOffset: number = 0;
+  // The ID of the setInterval call that updates the sparklesOffset.
+  private sparklesIntervalId?: number;
+  // Whether the sparkles are enabled or not.
+  private enableSparkles: boolean =
+      loadTimeData.getBoolean('enableShimmerSparkles');
+
   // The current shimmer state.
   private shimmerState: ShimmerState = ShimmerState.NONE;
   // The start time of the current animation. When undefined, it will be set at
@@ -321,6 +340,27 @@
         id => assert(
             BrowserProxyImpl.getInstance().callbackRouter.removeListener(id)));
     this.listenerIds = [];
+
+    // Stop updating the sparkles if they are currently updating.
+    if (this.sparklesIntervalId) {
+      clearInterval(this.sparklesIntervalId);
+      this.sparklesIntervalId = undefined;
+    }
+  }
+
+  private onSparklesLoad() {
+    // If the flag to enable sparkles is off, ignore the SVG loading in which
+    // will cause skip initializing sparklesPattern so no sparkles appear.
+    if (!this.enableSparkles) {
+      return;
+    }
+
+    this.sparklesPattern =
+        this.context.createPattern(this.$.sparklesSvg, 'repeat');
+
+    this.sparklesIntervalId = setInterval(() => {
+      this.sparklesOffset = Math.round(Math.random() * 500);
+    }, 100);
   }
 
   /** Starts the invocation animation into the steady state. */
@@ -384,6 +424,7 @@
     this.resetCanvasPixelRatioIfNeeded();
 
     this.drawCircles(timeMs);
+    this.drawSparkles();
     requestAnimationFrame(this.stepAnimation.bind(this));
   }
 
@@ -579,6 +620,31 @@
     this.finishAnimationIfNeeded(elapsed);
   }
 
+  // Draws sparkles on the canvas using circles as an alpha mask.
+  private drawSparkles(): void {
+    if (!this.sparklesPattern) {
+      return;
+    }
+
+    // Update the sparkles position to use across the circles.
+    this.sparklesPattern!.setTransform(new DOMMatrixReadOnly().translate(
+        this.sparklesOffset, this.sparklesOffset));
+
+    this.context.save();
+
+    // Draw a path over the entire canvas.
+    this.context.beginPath();
+    this.context.rect(0, 0, this.canvasWidth, this.canvasHeight);
+    this.context.closePath();
+
+    this.context.globalCompositeOperation = 'source-atop';
+    this.context.globalAlpha = SPARKLES_OPACITY;
+    this.context.fillStyle = this.sparklesPattern;
+    this.context.fill();
+
+    this.context.restore();
+  }
+
   // Checks the set canvas size and if it has changed, resets it on the canvas.
   // Returns false if no changes were made.
   private resetCanvasSizeIfNeeded(): boolean {
diff --git a/chrome/browser/resources/lens/overlay/sparkles.svg b/chrome/browser/resources/lens/overlay/sparkles.svg
new file mode 100644
index 0000000..a2d26737
--- /dev/null
+++ b/chrome/browser/resources/lens/overlay/sparkles.svg
@@ -0,0 +1,19 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" fill="none" viewBox="0 0 400 400">
+    <defs>
+        <filter id="sparkles" color-interpolation-filters="auto">
+        <feTurbulence id="turbulance" baseFrequency="0.5" numOctaves="4"></feTurbulence>
+        <feColorMatrix values="
+            0 0 0 1 -.4
+            0 0 0 1 -.3
+            0 0 0 1 -.5
+            0 0 0 0 1"></feColorMatrix>
+        <feColorMatrix values="
+            0 0 0 0 1
+            0 0 0 0 1
+            0 0 0 0 1
+            1 1 1 0 0" result="grain"></feColorMatrix>
+        </filter>
+    </defs>
+    <rect xmlns="http://www.w3.org/2000/svg" width="400px" height="400px"
+    filter="url(#sparkles)" fill="black"/>
+</svg>
\ No newline at end of file
diff --git a/chrome/browser/resources/new_tab_page/modules/v2/most_relevant_tab_resumption/module.html b/chrome/browser/resources/new_tab_page/modules/v2/most_relevant_tab_resumption/module.html
index 2e071527..257e0dc 100644
--- a/chrome/browser/resources/new_tab_page/modules/v2/most_relevant_tab_resumption/module.html
+++ b/chrome/browser/resources/new_tab_page/modules/v2/most_relevant_tab_resumption/module.html
@@ -128,10 +128,23 @@
   .tab:hover cr-icon-button {
       display: block;
   }
+
+  #see-more-button-container {
+    color: var(--color-new-tab-page-link);
+    font-size: 13px;
+    line-height: 20px;
+    margin: 0 0 8px 8px;
+    padding: 8px 16px 8px 16px;
+    width: fit-content;
+  }
+
+  #see-more-button {
+    text-decoration: none;
+  }
 </style>
 <ntp-module-header-v2
     id="moduleHeaderElementV2"
-    header-text="[[i18n('modulesTabResumptionTitle')]]"
+    header-text="[[i18n('modulesMostRelevantTabResumptionTitle')]]"
     menu-item-groups="[[getMenuItemGroups_()]]"
     more-actions-text="[[i18nRecursive('',
                                   'modulesMoreActions',
@@ -173,6 +186,12 @@
     </a>
   </template>
 </div>
+<div id="see-more-button-container">
+  <a id="see-more-button" href="chrome://history/syncedTabs">
+    $i18n{modulesMostRelevantTabResumptionSeeMore}
+  </a>
+</div>
+
 <cr-lazy-render id="infoDialogRender">
   <template>
     <ntp-info-dialog
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.ts b/chrome/browser/resources/settings/site_settings_page/site_settings_page.ts
index 2d902fe..669273a 100644
--- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.ts
+++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.ts
@@ -654,7 +654,9 @@
       return;
     }
 
-    this.showUnusedSitePermissions_ = this.unusedSitePermissionsEnabled_ &&
+    this.showUnusedSitePermissions_ =
+        (this.unusedSitePermissionsEnabled_ ||
+         this.safetyHubAbusiveNotificationRevocationEnabled_) &&
         permissions.length > 0 && !loadTimeData.getBoolean('isGuest');
     this.unusedSitePermissionsHeader_ =
         await PluralStringProxyImpl.getInstance().getPluralString(
diff --git a/chrome/browser/resources/side_panel/read_anything/app.ts b/chrome/browser/resources/side_panel/read_anything/app.ts
index 825d7f9..e58ce309 100644
--- a/chrome/browser/resources/side_panel/read_anything/app.ts
+++ b/chrome/browser/resources/side_panel/read_anything/app.ts
@@ -14,10 +14,8 @@
 import type {CrToastElement} from '//resources/cr_elements/cr_toast/cr_toast.js';
 import {WebUiListenerMixin} from '//resources/cr_elements/web_ui_listener_mixin.js';
 import {assert} from '//resources/js/assert.js';
-import {rgbToSkColor, skColorToRgba} from '//resources/js/color_utils.js';
 import {loadTimeData} from '//resources/js/load_time_data.js';
 import {listenOnce} from '//resources/js/util.js';
-import type {SkColor} from '//resources/mojo/skia/public/mojom/skcolor.mojom-webui.js';
 import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {getTemplate} from './app.html.js';
@@ -29,11 +27,6 @@
 
 const ReadAnythingElementBase = WebUiListenerMixin(PolymerElement);
 
-interface LinkColor {
-  default: string;
-  visited: string;
-}
-
 interface UtteranceSettings {
   lang: string;
   volume: number;
@@ -41,32 +34,8 @@
   rate: number;
 }
 
-// TODO(crbug.com/40275871): Remove colors defined here once the Views toolbar
-// is removed.
-const style = getComputedStyle(document.body);
-const darkThemeBackgroundSkColor =
-    rgbToSkColor(style.getPropertyValue('--google-grey-900-rgb'));
-const lightThemeBackgroundSkColor =
-    rgbToSkColor(style.getPropertyValue('--google-grey-50-rgb'));
-const yellowThemeBackgroundSkColor =
-    rgbToSkColor(style.getPropertyValue('--google-yellow-100-rgb'));
 const darkThemeEmptyStateBodyColor = 'var(--google-grey-500)';
 const defaultThemeEmptyStateBodyColor = 'var(--google-grey-700)';
-const darkThemeLinkColors: LinkColor = {
-  default: 'var(--google-blue-300)',
-  visited: 'var(--google-purple-200)',
-};
-const defaultLinkColors: LinkColor = {
-  default: 'var(--google-blue-900)',
-  visited: 'var(--google-purple-900)',
-};
-const lightThemeLinkColors: LinkColor = {
-  default: 'var(--google-blue-800)',
-  visited: 'var(--google-purple-900)',
-};
-const darkThemeSelectionColor = 'var(--google-blue-200)';
-const defaultSelectionColor = 'var(--google-yellow-100)';
-const yellowThemeSelectionColor = 'var(--google-blue-100)';
 
 export const previousReadHighlightClass = 'previous-read-highlight';
 export const currentReadHighlightClass = 'current-read-highlight';
@@ -160,12 +129,6 @@
         }
       };
 
-  chrome.readingMode.updateTheme = () => {
-    const readAnythingApp = document.querySelector('read-anything-app');
-    assert(readAnythingApp, 'no app');
-    readAnythingApp.updateTheme();
-  };
-
   chrome.readingMode.showLoading = () => {
     const readAnythingApp = document.querySelector('read-anything-app');
     assert(readAnythingApp, 'no app');
@@ -313,9 +276,6 @@
   private isHighlightOn_: boolean = true;
   private previousRootId_: number;
 
-  // If the WebUI toolbar should be shown. This happens when the WebUI feature
-  // flag is enabled.
-  private isWebUIToolbarVisible_: boolean;
   private isReadAloudEnabled_: boolean;
 
   // If the speech engine is considered "loaded." If it is, we should display
@@ -409,11 +369,8 @@
         (this.constructorTime - this.startTime),
         'Accessibility.ReadAnything.TimeFromAppStartedToConstructor');
     this.isReadAloudEnabled_ = chrome.readingMode.isReadAloudEnabled;
-    this.isWebUIToolbarVisible_ = chrome.readingMode.isWebUIToolbarVisible;
     this.speechSynthesisLanguage = chrome.readingMode.baseLanguageForSpeech;
-    if (chrome.readingMode && chrome.readingMode.isWebUIToolbarVisible) {
-      ColorChangeUpdater.forDocument().start();
-    }
+    ColorChangeUpdater.forDocument().start();
   }
 
   override connectedCallback() {
@@ -2190,49 +2147,12 @@
     }
   }
 
-  // TODO(b/1465029): Once the IsReadAnythingWebUIEnabled flag is removed
-  // this should be removed
-  private validatedFontName_(): string {
-    return validatedFontName(chrome.readingMode.fontName);
-  }
-
-  private getLinkColor_(backgroundSkColor: SkColor): LinkColor {
-    switch (backgroundSkColor.value) {
-      case darkThemeBackgroundSkColor.value:
-        return darkThemeLinkColors;
-      case lightThemeBackgroundSkColor.value:
-        return lightThemeLinkColors;
-      default:
-        return defaultLinkColors;
-    }
-  }
-
-  private getEmptyStateBodyColor_(backgroundSkColor: SkColor): string {
-    const isDark = backgroundSkColor.value === darkThemeBackgroundSkColor.value;
-    return isDark ? darkThemeEmptyStateBodyColor :
-                    defaultThemeEmptyStateBodyColor;
-  }
-
-  // TODO(crbug.com/40275871): This method should be renamed to
-  // getEmptyStateBodyColor_() and replace the one above once we've removed the
-  // Views toolbar.
-  private getEmptyStateBodyColorFromWebUi_(colorSuffix: string): string {
+  private getEmptyStateBodyColor_(colorSuffix: string): string {
     const isDark = colorSuffix.includes('dark');
     return isDark ? darkThemeEmptyStateBodyColor :
                     defaultThemeEmptyStateBodyColor;
   }
 
-  private getSelectionColor_(backgroundSkColor: SkColor): string {
-    switch (backgroundSkColor.value) {
-      case darkThemeBackgroundSkColor.value:
-        return darkThemeSelectionColor;
-      case yellowThemeBackgroundSkColor.value:
-        return yellowThemeSelectionColor;
-      default:
-        return defaultSelectionColor;
-    }
-  }
-
   // This must be called BEFORE calling
   // chrome.readingMode.movePositionToPreviousGranularity so we can accurately
   // determine what's currently being highlighted.
@@ -2294,7 +2214,7 @@
         // Do nothing
     }
     if (colorSuffix !== undefined) {
-      this.updateThemeFromWebUi_(colorSuffix);
+      this.updateTheme_(colorSuffix);
     }
     // TODO(crbug.com/40927698): investigate using parent/child relationshiop
     // instead of element by id.
@@ -2418,7 +2338,7 @@
   }
 
   private onThemeChange_(event: CustomEvent<{data: string}>) {
-    this.updateThemeFromWebUi_(event.detail.data);
+    this.updateTheme_(event.detail.data);
   }
 
   private onResetToolbar_() {
@@ -2440,12 +2360,10 @@
     });
   }
 
-  // TODO(crbug.com/40275871): This method should be renamed to updateTheme()
-  // and replace the one below once we've removed the Views toolbar.
-  private updateThemeFromWebUi_(colorSuffix: string) {
+  private updateTheme_(colorSuffix: string) {
     this.currentColorSuffix_ = colorSuffix;
     const emptyStateBodyColor = colorSuffix ?
-        this.getEmptyStateBodyColorFromWebUi_(colorSuffix) :
+        this.getEmptyStateBodyColor_(colorSuffix) :
         'var(--color-side-panel-card-secondary-foreground)';
     this.updateStyles({
       '--background-color': this.getBackgroundColorVar(colorSuffix),
@@ -2520,38 +2438,6 @@
     return `var(--google-grey-800)`;
   }
 
-  updateTheme() {
-    const foregroundColor:
-        SkColor = {value: chrome.readingMode.foregroundColor};
-    const backgroundColor:
-        SkColor = {value: chrome.readingMode.backgroundColor};
-    const linkColor = this.getLinkColor_(backgroundColor);
-
-    this.updateStyles({
-      '--background-color': skColorToRgba(backgroundColor),
-      '--font-family': this.validatedFontName_(),
-      '--font-size': chrome.readingMode.fontSize + 'em',
-      '--foreground-color': skColorToRgba(foregroundColor),
-      '--letter-spacing': chrome.readingMode.letterSpacing + 'em',
-      '--line-height': chrome.readingMode.lineSpacing,
-      '--link-color': linkColor.default,
-      '--selection-color': this.getSelectionColor_(backgroundColor),
-      '--sp-empty-state-heading-color': skColorToRgba(foregroundColor),
-      '--sp-empty-state-body-color':
-          this.getEmptyStateBodyColor_(backgroundColor),
-      '--visited-link-color': linkColor.visited,
-    });
-    if (!chrome.readingMode.isWebUIToolbarVisible) {
-      document.body.style.background = skColorToRgba(backgroundColor);
-    }
-
-    document.documentElement.style.setProperty(
-        '--selection-color', this.getSelectionColor_(backgroundColor));
-    document.documentElement.style.setProperty(
-        '--selection-text-color',
-        this.getSelectionTextColorVar(skColorToRgba(backgroundColor)));
-  }
-
   // If the screen is locked during speech, we should stop speaking.
   onLockScreen() {
     if (!this.speechPlayingState.paused) {
diff --git a/chrome/browser/resources/side_panel/read_anything/read_anything.d.ts b/chrome/browser/resources/side_panel/read_anything/read_anything.d.ts
index 56556f3..17b7aef 100644
--- a/chrome/browser/resources/side_panel/read_anything/read_anything.d.ts
+++ b/chrome/browser/resources/side_panel/read_anything/read_anything.d.ts
@@ -28,18 +28,14 @@
     let endNodeId: number;
     let endOffset: number;
 
-    // Items in the ReadAnythingTheme struct, see read_anything.mojom for info.
+    // The current style theme values.
     let fontName: string;
     let fontSize: number;
     let linksEnabled: boolean;
     let imagesEnabled: boolean;
     let imagesFeatureEnabled: boolean;
-    let foregroundColor: number;
-    let backgroundColor: number;
     let lineSpacing: number;
     let letterSpacing: number;
-
-    // The current color theme value.
     let colorTheme: number;
 
     // Current audio settings values.
@@ -59,9 +55,6 @@
     let yellowTheme: number;
     let blueTheme: number;
 
-    // Whether the WebUI toolbar feature flag is enabled.
-    let isWebUIToolbarVisible: boolean;
-
     // Whether the Read Aloud feature flag is enabled.
     let isReadAloudEnabled: boolean;
 
@@ -285,10 +278,6 @@
     // Ping that the selection has been updated.
     function updateSelection(): void;
 
-    // Ping that the theme choices of the user have been changed using the
-    // toolbar and are ready to consume.
-    function updateTheme(): void;
-
     // Read Aloud state should be updated if the lock screen state changes.
     function onLockScreen(): void;
 
diff --git a/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin_app.html b/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin_app.html
index efddbe17..9a82d92 100644
--- a/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin_app.html
+++ b/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin_app.html
@@ -18,6 +18,7 @@
   color: var(--cr-primary-text-color);
   font-weight: 500;
   line-height: 24px;
+  margin-bottom: 0px;
   margin-top: 8px;
 }
 
@@ -89,7 +90,7 @@
               chrome://theme/current-channel-logo@2x 2x"
       role="presentation">
 
-    <div id="title">$i18n{chromeSigninTitle}</div>
+    <h1 id="title">$i18n{chromeSigninTitle}</h1>
     <div id="subtitle">$i18n{chromeSigninSubtitle}</div>
 
   </div>
@@ -105,6 +106,7 @@
 
       <div id="button-container">
         <cr-button id="accept-button" class="action-button"
+            aria-label$="[[getAcceptButtonAriaLabel_(interceptionParameters_)]]"
             on-click="onAccept_">
             <div id="acceppt-button-content">
               [[i18n('chromeSigninAcceptText',
diff --git a/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin_app.ts b/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin_app.ts
index e2d31f4..7b71cb6 100644
--- a/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin_app.ts
+++ b/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin_app.ts
@@ -75,6 +75,14 @@
   private onAccept_() {
     this.diceWebSigninInterceptBrowserProxy_.accept();
   }
+
+  private getAcceptButtonAriaLabel_() {
+    if (!this.interceptionParameters_) {
+      return null;
+    }
+    return this.i18n(
+        'acceptButtonAriaLabel', this.interceptionParameters_.email);
+  }
 }
 
 declare global {
diff --git a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_browsertest.cc b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_browsertest.cc
index 2a0f44c3..984a445 100644
--- a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_browsertest.cc
@@ -810,31 +810,20 @@
 // enabled.
 class
     ExtensionTelemetryServiceBrowserTestWithInterceptRemoteHostsContactedInRendererEnabled
-    : public ExtensionTelemetryServiceBrowserTest,
-      public testing::WithParamInterface<bool> {
+    : public ExtensionTelemetryServiceBrowserTest {
  public:
   ExtensionTelemetryServiceBrowserTestWithInterceptRemoteHostsContactedInRendererEnabled() {
     scoped_feature_list_.Reset();
-    std::vector<base::test::FeatureRef> enabled_features = {
-        kExtensionTelemetryInterceptRemoteHostsContactedInRenderer,
-        kExtensionTelemetryReportContactedHosts,
-        kExtensionTelemetryReportHostsContactedViaWebSocket};
-    std::vector<base::test::FeatureRef> disabled_features = {};
-    if (GetParam()) {
-      enabled_features.push_back(kSafeBrowsingSkipSubresources2);
-    } else {
-      disabled_features.push_back(kSafeBrowsingSkipSubresources2);
-    }
-    scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
+    scoped_feature_list_.InitWithFeatures(
+        /*enabled_features=*/
+        {kExtensionTelemetryInterceptRemoteHostsContactedInRenderer,
+         kExtensionTelemetryReportContactedHosts,
+         kExtensionTelemetryReportHostsContactedViaWebSocket},
+        /*disabled_features=*/{});
   }
 };
 
-INSTANTIATE_TEST_SUITE_P(
-    All,
-    ExtensionTelemetryServiceBrowserTestWithInterceptRemoteHostsContactedInRendererEnabled,
-    testing::Bool());
-
-IN_PROC_BROWSER_TEST_P(
+IN_PROC_BROWSER_TEST_F(
     ExtensionTelemetryServiceBrowserTestWithInterceptRemoteHostsContactedInRendererEnabled,
     InterceptsRemoteHostContactedSignalInRenderer) {
   base::HistogramTester histogram_tester;
@@ -920,7 +909,7 @@
       true, 1);
 }
 
-IN_PROC_BROWSER_TEST_P(
+IN_PROC_BROWSER_TEST_F(
     ExtensionTelemetryServiceBrowserTestWithInterceptRemoteHostsContactedInRendererEnabled,
     DetectsWebRequestFromContentScript) {
   SetSafeBrowsingState(browser()->profile()->GetPrefs(),
diff --git a/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win_unittest.cc
index dc3552dd..0ac11777 100644
--- a/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win_unittest.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win_unittest.cc
@@ -18,6 +18,7 @@
 #include "base/files/file_path.h"
 #include "base/files/memory_mapped_file.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_span.h"
 #include "base/native_library.h"
 #include "base/ranges/algorithm.h"
 #include "base/scoped_native_library.h"
@@ -68,7 +69,7 @@
   }
 
  private:
-  base::span<uint8_t> modification_region_;
+  base::raw_span<uint8_t> modification_region_;
 };
 
 }  // namespace
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
index 0254856..307ae732 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -887,7 +887,7 @@
       public V4SafeBrowsingServiceTest {};
 
 IN_PROC_BROWSER_TEST_P(V4SafeBrowsingServiceJsRequestNoInterstitialTest,
-                       MalwareBlocked) {
+                       MalwareNotBlocked) {
   GURL base_url = embedded_test_server()->GetURL(kMalwareJsRequestPage);
   JsRequestTestParam param = GetParam();
   MarkUrlForMalwareUnexpired(
@@ -897,22 +897,10 @@
   auto new_title = JsRequestTestNavigateAndWaitForTitle(
       browser(), AddJsRequestParam(base_url, param));
 
-  // When |kSafeBrowsingSkipSubresources2| is disabled and request_type is
-  // |JsRequestType::kWebSocket|, show a warning.
-  if (!base::FeatureList::IsEnabled(kSafeBrowsingSkipSubresources2) &&
-      param.request_type == JsRequestType::kWebSocket) {
-    EXPECT_EQ("ERROR", new_title);
-    EXPECT_FALSE(ShowingInterstitialPage());
-
-    // got_hit_report() is only set when an interstitial is shown.
-    EXPECT_FALSE(got_hit_report());
-    EXPECT_FALSE(got_warning_shown_report());
-  } else {
-    EXPECT_EQ("NOT BLOCKED", new_title);
-    EXPECT_FALSE(ShowingInterstitialPage());
-    EXPECT_FALSE(got_hit_report());
-    EXPECT_FALSE(got_warning_shown_report());
-  }
+  EXPECT_EQ("NOT BLOCKED", new_title);
+  EXPECT_FALSE(ShowingInterstitialPage());
+  EXPECT_FALSE(got_hit_report());
+  EXPECT_FALSE(got_warning_shown_report());
 }
 
 INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/safe_browsing/url_checker_delegate_impl.cc b/chrome/browser/safe_browsing/url_checker_delegate_impl.cc
index 1cd0d03c..c3b1522 100644
--- a/chrome/browser/safe_browsing/url_checker_delegate_impl.cc
+++ b/chrome/browser/safe_browsing/url_checker_delegate_impl.cc
@@ -55,7 +55,6 @@
 
 void CreateSafeBrowsingUserInteractionObserver(
     const security_interstitials::UnsafeResource& resource,
-    bool is_main_frame,
     scoped_refptr<SafeBrowsingUIManager> ui_manager) {
   content::WebContents* web_contents =
       unsafe_resource_util::GetWebContentsForResource(resource);
@@ -75,7 +74,7 @@
   }
 #endif
   SafeBrowsingUserInteractionObserver::CreateForWebContents(
-      web_contents, resource, is_main_frame, ui_manager);
+      web_contents, resource, ui_manager);
 }
 
 }  // namespace
@@ -112,7 +111,6 @@
     const security_interstitials::UnsafeResource& resource,
     const std::string& method,
     const net::HttpRequestHeaders& headers,
-    bool is_main_frame,
     bool has_user_gesture) {
   // Keep a post task here to avoid possible reentrancy into safe browsing
   // code if it is running on the UI thread.
@@ -125,13 +123,12 @@
 // Starts displaying the SafeBrowsing interstitial page.
 void UrlCheckerDelegateImpl::
     StartObservingInteractionsForDelayedBlockingPageHelper(
-        const security_interstitials::UnsafeResource& resource,
-        bool is_main_frame) {
+        const security_interstitials::UnsafeResource& resource) {
   // Keep a post task here to avoid possible reentrancy into safe browsing
   // code if it is running on the UI thread.
   content::GetUIThreadTaskRunner({})->PostTask(
       FROM_HERE, base::BindOnce(&CreateSafeBrowsingUserInteractionObserver,
-                                resource, is_main_frame, ui_manager_));
+                                resource, ui_manager_));
 }
 
 bool UrlCheckerDelegateImpl::IsUrlAllowlisted(const GURL& url) {
diff --git a/chrome/browser/safe_browsing/url_checker_delegate_impl.h b/chrome/browser/safe_browsing/url_checker_delegate_impl.h
index 3b9567d..a48b6724 100644
--- a/chrome/browser/safe_browsing/url_checker_delegate_impl.h
+++ b/chrome/browser/safe_browsing/url_checker_delegate_impl.h
@@ -33,11 +33,9 @@
       const security_interstitials::UnsafeResource& resource,
       const std::string& method,
       const net::HttpRequestHeaders& headers,
-      bool is_main_frame,
       bool has_user_gesture) override;
   void StartObservingInteractionsForDelayedBlockingPageHelper(
-      const security_interstitials::UnsafeResource& resource,
-      bool is_main_frame) override;
+      const security_interstitials::UnsafeResource& resource) override;
 
   bool IsUrlAllowlisted(const GURL& url) override;
   void SetPolicyAllowlistDomains(
diff --git a/chrome/browser/safe_browsing/user_interaction_observer.cc b/chrome/browser/safe_browsing/user_interaction_observer.cc
index 74ef730e..54ea6f23 100644
--- a/chrome/browser/safe_browsing/user_interaction_observer.cc
+++ b/chrome/browser/safe_browsing/user_interaction_observer.cc
@@ -28,7 +28,6 @@
 SafeBrowsingUserInteractionObserver::SafeBrowsingUserInteractionObserver(
     content::WebContents* web_contents,
     const security_interstitials::UnsafeResource& resource,
-    bool is_main_frame,
     scoped_refptr<SafeBrowsingUIManager> ui_manager)
     : content::WebContentsUserData<SafeBrowsingUserInteractionObserver>(
           *web_contents),
@@ -82,7 +81,6 @@
 void SafeBrowsingUserInteractionObserver::CreateForWebContents(
     content::WebContents* web_contents,
     const security_interstitials::UnsafeResource& resource,
-    bool is_main_frame,
     scoped_refptr<SafeBrowsingUIManager> ui_manager) {
   // This method is called for all unsafe resources on |web_contents|. Only
   // create an observer if there isn't one.
@@ -91,7 +89,6 @@
   content::WebContentsUserData<
       SafeBrowsingUserInteractionObserver>::CreateForWebContents(web_contents,
                                                                  resource,
-                                                                 is_main_frame,
                                                                  ui_manager);
 }
 
diff --git a/chrome/browser/safe_browsing/user_interaction_observer.h b/chrome/browser/safe_browsing/user_interaction_observer.h
index 821a7b4a..de9bd5b 100644
--- a/chrome/browser/safe_browsing/user_interaction_observer.h
+++ b/chrome/browser/safe_browsing/user_interaction_observer.h
@@ -70,13 +70,10 @@
  public:
   // Creates an observer for given |web_contents|. |resource| is the unsafe
   // resource for which a delayed interstitial will be displayed.
-  // |is_main_frame| is true if the interstitial is for the top frame. If false,
-  // it's for a subresource / subframe.
   // |ui_manager| is the UIManager that shows the actual warning.
   static void CreateForWebContents(
       content::WebContents* web_contents,
       const security_interstitials::UnsafeResource& resource,
-      bool is_main_frame,
       scoped_refptr<SafeBrowsingUIManager> ui_manager);
 
   ~SafeBrowsingUserInteractionObserver() override;
@@ -116,7 +113,6 @@
   SafeBrowsingUserInteractionObserver(
       content::WebContents* web_contents,
       const security_interstitials::UnsafeResource& resource,
-      bool is_main_frame,
       scoped_refptr<SafeBrowsingUIManager> ui_manager);
 
   bool HandleKeyPress(const input::NativeWebKeyboardEvent& event);
diff --git a/chrome/browser/screen_ai/optical_character_recognizer_browsertest.cc b/chrome/browser/screen_ai/optical_character_recognizer_browsertest.cc
index e58d20f..5a7c71a 100644
--- a/chrome/browser/screen_ai/optical_character_recognizer_browsertest.cc
+++ b/chrome/browser/screen_ai/optical_character_recognizer_browsertest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/screen_ai/public/optical_character_recognizer.h"
 
 #include "base/files/file_util.h"
+#include "base/notreached.h"
 #include "base/path_service.h"
 #include "base/scoped_observation.h"
 #include "base/strings/stringprintf.h"
@@ -124,8 +125,13 @@
     InProcessBrowserTest::SetUpOnMainThread();
 
     if (IsLibraryAvailable()) {
+#if BUILDFLAG(ENABLE_SCREEN_AI_BROWSERTESTS)
       ScreenAIInstallState::GetInstance()->SetComponentFolder(
           GetComponentBinaryPathForTests().DirName());
+#else
+      NOTREACHED_NORETURN()
+          << "Test library is used on a not-suppported platform.";
+#endif
     } else {
       // Set an observer to reply download failed, when download requested.
       component_download_observer_.Observe(ScreenAIInstallState::GetInstance());
diff --git a/chrome/browser/screen_ai/screen_ai_service_router_browsertest.cc b/chrome/browser/screen_ai/screen_ai_service_router_browsertest.cc
index a12b580a..bbec8e3 100644
--- a/chrome/browser/screen_ai/screen_ai_service_router_browsertest.cc
+++ b/chrome/browser/screen_ai/screen_ai_service_router_browsertest.cc
@@ -72,6 +72,14 @@
   base::WeakPtrFactory<ResultsWaiter> weak_ptr_factory_{this};
 };
 
+base::FilePath GetComponentBinaryPath() {
+#if BUILDFLAG(ENABLE_SCREEN_AI_BROWSERTESTS)
+  return screen_ai::GetComponentBinaryPathForTests();
+#else
+  NOTREACHED_NORETURN() << "Test library is used on a not-suppported platform.";
+#endif
+}
+
 }  // namespace
 
 namespace screen_ai {
@@ -130,7 +138,7 @@
   // InProcessBrowserTest:
   void SetUpOnMainThread() override {
     if (IsLibraryAvailableAtStartUp()) {
-      base::FilePath library_path = screen_ai::GetComponentBinaryPathForTests();
+      base::FilePath library_path = GetComponentBinaryPath();
       CHECK(!library_path.empty());
       CHECK(base::PathExists(library_path));
       ScreenAIInstallState::GetInstance()->SetComponentFolder(
@@ -162,7 +170,7 @@
         base::ThreadPool::PostTaskAndReplyWithResult(
             FROM_HERE,
             {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
-            base::BindOnce(&screen_ai::GetComponentBinaryPathForTests),
+            base::BindOnce(&GetComponentBinaryPath),
             base::BindOnce([](const base::FilePath component_path) {
               ScreenAIInstallState::GetInstance()->SetComponentFolder(
                   component_path.DirName());
diff --git a/chrome/browser/serial/serial_chooser_context_unittest.cc b/chrome/browser/serial/serial_chooser_context_unittest.cc
index 7f71e61..ead3070 100644
--- a/chrome/browser/serial/serial_chooser_context_unittest.cc
+++ b/chrome/browser/serial/serial_chooser_context_unittest.cc
@@ -43,6 +43,7 @@
 
 namespace {
 
+using ::base::test::InvokeFuture;
 using ::base::test::ParseJson;
 using ::base::test::TestFuture;
 using ::content_settings::SettingSource;
@@ -784,9 +785,7 @@
   // is notified that the port is now disconnected.
   TestFuture<const device::mojom::SerialPortInfo&> port_future;
   EXPECT_CALL(port_observer(), OnPortConnectedStateChanged)
-      .WillOnce([&port_future](const device::mojom::SerialPortInfo& port) {
-        port_future.SetValue(port);
-      });
+      .WillOnce(InvokeFuture(port_future));
   auto disconnected_port = port.Clone();
   disconnected_port->connected = false;
   context()->OnPortConnectedStateChanged(std::move(disconnected_port));
diff --git a/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/SigninMetricsUtils.java b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/SigninMetricsUtils.java
index eda9eff..6f75b46 100644
--- a/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/SigninMetricsUtils.java
+++ b/chrome/browser/signin/services/android/java/src/org/chromium/chrome/browser/signin/services/SigninMetricsUtils.java
@@ -91,6 +91,8 @@
     public static void logSigninStartAccessPoint(@SigninAccessPoint int accessPoint) {
         RecordHistogram.recordEnumeratedHistogram(
                 "Signin.SigninStartedAccessPoint", accessPoint, SigninAccessPoint.MAX);
+        RecordHistogram.recordEnumeratedHistogram(
+                "Signin.SignIn.Started", accessPoint, SigninAccessPoint.MAX);
     }
 
     /** Logs signin user action for a given {@link SigninAccessPoint}. */
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc
index 97bf6b58..87caac5 100644
--- a/chrome/browser/ssl/ssl_browsertest.cc
+++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -5689,13 +5689,9 @@
   raw_ptr<Profile> profile_2_;
 
   // The NSSCertDatabase for |profile_1_|.
-  // This field is not a raw_ptr<> because it was filtered by the rewriter
-  // for: #addr-of
   raw_ptr<net::NSSCertDatabase> profile_1_cert_db_;
 
   // The NSSCertDatabase for |profile_2_|.
-  // This field is not a raw_ptr<> because it was filtered by the rewriter
-  // for: #addr-of
   raw_ptr<net::NSSCertDatabase> profile_2_cert_db_;
 
   // Policy provider for |profile_2_|. Overrides any other policy providers.
diff --git a/chrome/browser/tab/BUILD.gn b/chrome/browser/tab/BUILD.gn
index 376f08b..39c94a23 100644
--- a/chrome/browser/tab/BUILD.gn
+++ b/chrome/browser/tab/BUILD.gn
@@ -90,6 +90,7 @@
     "//components/commerce/core:proto_java",
     "//components/commerce/core/android:core_java",
     "//components/embedder_support/android:content_view_java",
+    "//components/embedder_support/android:context_menu_java",
     "//components/embedder_support/android:util_java",
     "//components/embedder_support/android:web_contents_delegate_java",
     "//components/external_intents/android:java",
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabDelegateFactory.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabDelegateFactory.java
index f6685dd..52885e0d 100644
--- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabDelegateFactory.java
+++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabDelegateFactory.java
@@ -6,10 +6,10 @@
 
 import androidx.annotation.Nullable;
 
-import org.chromium.chrome.browser.contextmenu.ContextMenuPopulatorFactory;
 import org.chromium.chrome.browser.pdf.PdfInfo;
 import org.chromium.chrome.browser.ui.native_page.NativePage;
 import org.chromium.components.browser_ui.util.BrowserControlsVisibilityDelegate;
+import org.chromium.components.embedder_support.contextmenu.ContextMenuPopulatorFactory;
 import org.chromium.components.embedder_support.delegate.WebContentsDelegateAndroid;
 import org.chromium.components.external_intents.ExternalNavigationHandler;
 import org.chromium.components.navigation_interception.InterceptNavigationDelegate;
diff --git a/chrome/browser/tab/web_contents_state.h b/chrome/browser/tab/web_contents_state.h
index c82bafb..d298a7a 100644
--- a/chrome/browser/tab/web_contents_state.h
+++ b/chrome/browser/tab/web_contents_state.h
@@ -8,6 +8,7 @@
 #include "base/android/scoped_java_ref.h"
 #include "base/containers/span.h"
 #include "base/functional/callback.h"
+#include "base/memory/raw_span.h"
 #include "content/public/browser/web_contents.h"
 
 namespace sessions {
@@ -58,7 +59,7 @@
   // TODO(ellyjones): is it necessary to cache this view of the buffer? It is
   // very cheap to recompute on the fly as needed, as long as we have the
   // JNIEnv* ready to hand.
-  base::span<const uint8_t> backing_buffer;
+  base::raw_span<const uint8_t> backing_buffer;
   int state_version;
   base::android::ScopedJavaGlobalRef<jobject> java_buffer;
 };
diff --git a/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelper.java b/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelper.java
index dbb3fc6..211197e9 100644
--- a/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelper.java
+++ b/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelper.java
@@ -134,6 +134,10 @@
         int rootId = TabGroupSyncUtils.getRootId(mTabGroupModelFilter, tabGroup.localId);
         List<Tab> tabs = mTabGroupModelFilter.getRelatedTabListForRootId(rootId);
         assert !tabs.isEmpty();
+        if (tabs.isEmpty()) {
+            LogUtils.log(TAG, "Found no tabs in the local group");
+            return;
+        }
 
         // We want to reconcile the local group with the synced group.
         // The algorithm is different depending on whether we are running this on startup or for a
@@ -145,11 +149,7 @@
                 tabsToClose = tabs.subList(tabGroup.savedTabs.size(), tabs.size());
             }
         } else {
-            tabsToClose = findLocalTabsNotInSync(tabGroup);
-        }
-
-        if (!tabsToClose.isEmpty()) {
-            getTabModel().closeMultipleTabs(tabsToClose, /* canUndo= */ false);
+            tabsToClose = findLocalTabsNotInSyncPostStartup(tabGroup);
         }
 
         // Update the remaining tabs. If the tab is already there, ensure its URL is up-to-date.
@@ -186,6 +186,9 @@
             getTabModel().moveTab(localTab.getId(), desiredTabModelIndex);
         }
 
+        if (!tabsToClose.isEmpty()) {
+            getTabModel().closeMultipleTabs(tabsToClose, /* canUndo= */ false);
+        }
         updateTabGroupVisuals(tabGroup, rootId);
         // TODO(crbug.com/346406221): This currently causes the layout strip to flicker as events
         // still escape the filter and kick off animations. Rework somehow to avoid.
@@ -227,9 +230,12 @@
         mTabGroupSyncService.removeLocalTabGroupMapping(tabGroupId);
     }
 
-    private List<Tab> findLocalTabsNotInSync(SavedTabGroup savedTabGroup) {
+    private List<Tab> findLocalTabsNotInSyncPostStartup(SavedTabGroup savedTabGroup) {
         assert savedTabGroup.localId != null;
 
+        // We have been through startup reconcile earlier, so the tabs should have IDs mapped
+        // already.
+        // Find the ones that are not in sync. These are the ones that should be closed.
         Set<Integer> savedTabIds = new HashSet<>();
         for (SavedTabGroupTab savedTab : savedTabGroup.savedTabs) {
             if (savedTab.localId == null) continue;
diff --git a/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelperUnitTest.java b/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelperUnitTest.java
index ed7f33f..30544c95 100644
--- a/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelperUnitTest.java
+++ b/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelperUnitTest.java
@@ -199,17 +199,16 @@
         mLocalMutationHelper.updateTabGroup(savedTabGroup);
 
         // Collapsed must be re-set after the merge.
-        InOrder inOrder = inOrder(mTabGroupModelFilter);
+        InOrder inOrder = inOrder(mTabGroupModelFilter, mTabModel, mTabGroupSyncService);
+        verify(mTabCreationDelegate, times(2))
+                .createBackgroundTab(any(), anyString(), any(), anyInt());
         inOrder.verify(mTabGroupModelFilter, times(2))
                 .mergeListOfTabsToGroup(
                         anyList(), argThat(tab -> tab.getId() == ROOT_ID_1), eq(false));
-        inOrder.verify(mTabGroupModelFilter).setTabGroupCollapsed(ROOT_ID_1, true);
-
         verify(mTabGroupSyncService, times(1))
                 .updateLocalTabId(eq(LOCAL_TAB_GROUP_ID_1), any(), eq(TAB_ID_1));
-        verify(mTabModel).closeMultipleTabs(argThat(tabs -> tabs.size() == 1), eq(false));
-        verify(mTabCreationDelegate, times(2))
-                .createBackgroundTab(any(), anyString(), any(), anyInt());
+        inOrder.verify(mTabModel).closeMultipleTabs(argThat(tabs -> tabs.size() == 1), eq(false));
+        inOrder.verify(mTabGroupModelFilter).setTabGroupCollapsed(ROOT_ID_1, true);
     }
 
     @Test
diff --git a/chrome/browser/tab_resumption/java/src/org/chromium/chrome/browser/tab_resumption/SyncDerivedSuggestionEntrySource.java b/chrome/browser/tab_resumption/java/src/org/chromium/chrome/browser/tab_resumption/SyncDerivedSuggestionEntrySource.java
index 58841a9..40be0db 100644
--- a/chrome/browser/tab_resumption/java/src/org/chromium/chrome/browser/tab_resumption/SyncDerivedSuggestionEntrySource.java
+++ b/chrome/browser/tab_resumption/java/src/org/chromium/chrome/browser/tab_resumption/SyncDerivedSuggestionEntrySource.java
@@ -17,6 +17,7 @@
 import org.chromium.components.signin.identitymanager.IdentityManager;
 import org.chromium.components.sync.SyncService;
 import org.chromium.components.sync.SyncService.SyncStateChangedListener;
+import org.chromium.components.sync.UserSelectableType;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -76,7 +77,7 @@
         mSigninManager.addSignInStateObserver(this);
         mSyncService.addSyncStateChangedListener(this);
         mIsSignedIn = identityManager.hasPrimaryAccount(ConsentLevel.SIGNIN);
-        mIsSynced = mSyncService.hasKeepEverythingSynced();
+        mIsSynced = mSyncService.getSelectedTypes().contains(UserSelectableType.TABS);
 
         mPassUseCachedResults = false;
         mCachedSuggestionEntries = new ArrayList<SuggestionEntry>();
@@ -138,7 +139,7 @@
     @Override
     public void syncStateChanged() {
         boolean oldIsSynced = mIsSynced;
-        mIsSynced = mSyncService.hasKeepEverythingSynced();
+        mIsSynced = mSyncService.getSelectedTypes().contains(UserSelectableType.TABS);
         if (oldIsSynced != mIsSynced) {
             dispatchSourceDataChangedObservers(true);
         }
diff --git a/chrome/browser/tab_resumption/java/src/org/chromium/chrome/browser/tab_resumption/TabResumptionModuleEnablement.java b/chrome/browser/tab_resumption/java/src/org/chromium/chrome/browser/tab_resumption/TabResumptionModuleEnablement.java
index bcec8fa..4d63405e 100644
--- a/chrome/browser/tab_resumption/java/src/org/chromium/chrome/browser/tab_resumption/TabResumptionModuleEnablement.java
+++ b/chrome/browser/tab_resumption/java/src/org/chromium/chrome/browser/tab_resumption/TabResumptionModuleEnablement.java
@@ -16,6 +16,7 @@
 import org.chromium.chrome.browser.sync.SyncServiceFactory;
 import org.chromium.chrome.browser.tab_resumption.TabResumptionModuleMetricsUtils.ModuleNotShownReason;
 import org.chromium.components.signin.identitymanager.ConsentLevel;
+import org.chromium.components.sync.UserSelectableType;
 
 /** Utility class for the decision funnel on showing or hiding the tab resumption module. */
 public class TabResumptionModuleEnablement {
@@ -52,11 +53,13 @@
         static boolean isSignedIn(Profile profile) {
             return IdentityServicesProvider.get()
                     .getIdentityManager(profile)
-                    .hasPrimaryAccount(ConsentLevel.SYNC);
+                    .hasPrimaryAccount(ConsentLevel.SIGNIN);
         }
 
         static boolean isSyncEnabled(Profile profile) {
-            return SyncServiceFactory.getForProfile(profile).hasKeepEverythingSynced();
+            return SyncServiceFactory.getForProfile(profile)
+                    .getSelectedTypes()
+                    .contains(UserSelectableType.TABS);
         }
 
         static boolean isV2Enabled() {
diff --git a/chrome/browser/tab_resumption/junit/src/org/chromium/chrome/browser/tab_resumption/SyncDerivedSuggestionEntrySourceTest.java b/chrome/browser/tab_resumption/junit/src/org/chromium/chrome/browser/tab_resumption/SyncDerivedSuggestionEntrySourceTest.java
index 07c5347..f2ff2e58 100644
--- a/chrome/browser/tab_resumption/junit/src/org/chromium/chrome/browser/tab_resumption/SyncDerivedSuggestionEntrySourceTest.java
+++ b/chrome/browser/tab_resumption/junit/src/org/chromium/chrome/browser/tab_resumption/SyncDerivedSuggestionEntrySourceTest.java
@@ -26,6 +26,7 @@
 import org.robolectric.annotation.Config;
 
 import org.chromium.base.Callback;
+import org.chromium.base.CollectionUtil;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper.ForeignSession;
 import org.chromium.chrome.browser.signin.services.SigninManager;
@@ -34,8 +35,10 @@
 import org.chromium.components.signin.identitymanager.IdentityManager;
 import org.chromium.components.sync.SyncService;
 import org.chromium.components.sync.SyncService.SyncStateChangedListener;
+import org.chromium.components.sync.UserSelectableType;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
@@ -278,7 +281,12 @@
 
     private void createEntrySource(boolean isSignedIn, boolean isSynced, boolean servesLocalTabs) {
         when(mIdentityManager.hasPrimaryAccount(anyInt())).thenReturn(isSignedIn);
-        when(mSyncService.hasKeepEverythingSynced()).thenReturn(isSynced);
+        if (isSynced) {
+            when(mSyncService.getSelectedTypes())
+                    .thenReturn(CollectionUtil.newHashSet(UserSelectableType.TABS));
+        } else {
+            when(mSyncService.getSelectedTypes()).thenReturn(new HashSet<>());
+        }
         mSource =
                 new SyncDerivedSuggestionEntrySource(
                         /* signinManager= */ mSigninManager,
@@ -308,7 +316,12 @@
     }
 
     private void toggleIsSyncedThenNotify(boolean isSynced) {
-        when(mSyncService.hasKeepEverythingSynced()).thenReturn(isSynced);
+        if (isSynced) {
+            when(mSyncService.getSelectedTypes())
+                    .thenReturn(CollectionUtil.newHashSet(UserSelectableType.TABS));
+        } else {
+            when(mSyncService.getSelectedTypes()).thenReturn(new HashSet<>());
+        }
         // For simplicity, call handlers directly instead of using `mSyncService`.
         mSyncStateChangedListenerCaptor.getValue().syncStateChanged();
     }
diff --git a/chrome/browser/tab_resumption/junit/src/org/chromium/chrome/browser/tab_resumption/TabResumptionModuleEnablementUnitTest.java b/chrome/browser/tab_resumption/junit/src/org/chromium/chrome/browser/tab_resumption/TabResumptionModuleEnablementUnitTest.java
index 265e0ac9..1f6da93 100644
--- a/chrome/browser/tab_resumption/junit/src/org/chromium/chrome/browser/tab_resumption/TabResumptionModuleEnablementUnitTest.java
+++ b/chrome/browser/tab_resumption/junit/src/org/chromium/chrome/browser/tab_resumption/TabResumptionModuleEnablementUnitTest.java
@@ -19,6 +19,7 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.annotation.Config;
 
+import org.chromium.base.CollectionUtil;
 import org.chromium.base.FeatureList;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Features.DisableFeatures;
@@ -30,6 +31,9 @@
 import org.chromium.chrome.browser.tab_resumption.TabResumptionModuleMetricsUtils.ModuleNotShownReason;
 import org.chromium.components.signin.identitymanager.IdentityManager;
 import org.chromium.components.sync.SyncService;
+import org.chromium.components.sync.UserSelectableType;
+
+import java.util.HashSet;
 
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
@@ -55,15 +59,17 @@
     @DisableFeatures({ChromeFeatureList.TAB_RESUMPTION_MODULE_ANDROID})
     public void testEnablementWithoutForeignSessionFeature() {
         when(mIdentityManager.hasPrimaryAccount(anyInt())).thenReturn(false);
-        when(mSyncService.hasKeepEverythingSynced()).thenReturn(false);
+        when(mSyncService.getSelectedTypes()).thenReturn(new HashSet<>());
         Assert.assertEquals(ModuleNotShownReason.FEATURE_DISABLED, getNotShownReason().intValue());
-        when(mSyncService.hasKeepEverythingSynced()).thenReturn(true);
+        when(mSyncService.getSelectedTypes())
+                .thenReturn(CollectionUtil.newHashSet(UserSelectableType.TABS));
         Assert.assertEquals(ModuleNotShownReason.FEATURE_DISABLED, getNotShownReason().intValue());
 
         when(mIdentityManager.hasPrimaryAccount(anyInt())).thenReturn(true);
-        when(mSyncService.hasKeepEverythingSynced()).thenReturn(false);
+        when(mSyncService.getSelectedTypes()).thenReturn(new HashSet<>());
         Assert.assertEquals(ModuleNotShownReason.FEATURE_DISABLED, getNotShownReason().intValue());
-        when(mSyncService.hasKeepEverythingSynced()).thenReturn(true);
+        when(mSyncService.getSelectedTypes())
+                .thenReturn(CollectionUtil.newHashSet(UserSelectableType.TABS));
         Assert.assertEquals(ModuleNotShownReason.FEATURE_DISABLED, getNotShownReason().intValue());
     }
 
@@ -72,15 +78,17 @@
     @EnableFeatures({ChromeFeatureList.TAB_RESUMPTION_MODULE_ANDROID})
     public void testEnablementWithForeignSessionFeature() {
         when(mIdentityManager.hasPrimaryAccount(anyInt())).thenReturn(false);
-        when(mSyncService.hasKeepEverythingSynced()).thenReturn(false);
+        when(mSyncService.getSelectedTypes()).thenReturn(new HashSet<>());
         Assert.assertEquals(ModuleNotShownReason.NOT_SIGNED_IN, getNotShownReason().intValue());
-        when(mSyncService.hasKeepEverythingSynced()).thenReturn(true);
+        when(mSyncService.getSelectedTypes())
+                .thenReturn(CollectionUtil.newHashSet(UserSelectableType.TABS));
         Assert.assertEquals(ModuleNotShownReason.NOT_SIGNED_IN, getNotShownReason().intValue());
 
         when(mIdentityManager.hasPrimaryAccount(anyInt())).thenReturn(true);
-        when(mSyncService.hasKeepEverythingSynced()).thenReturn(false);
+        when(mSyncService.getSelectedTypes()).thenReturn(new HashSet<>());
         Assert.assertEquals(ModuleNotShownReason.NOT_SYNC, getNotShownReason().intValue());
-        when(mSyncService.hasKeepEverythingSynced()).thenReturn(true);
+        when(mSyncService.getSelectedTypes())
+                .thenReturn(CollectionUtil.newHashSet(UserSelectableType.TABS));
         Assert.assertNull(getNotShownReason());
     }
 
diff --git a/chrome/browser/tabpersistence/android/java/src/org/chromium/chrome/browser/tabpersistence/TabStateFileManagerUnitTest.java b/chrome/browser/tabpersistence/android/java/src/org/chromium/chrome/browser/tabpersistence/TabStateFileManagerUnitTest.java
index bfed008..ee0f03c4 100644
--- a/chrome/browser/tabpersistence/android/java/src/org/chromium/chrome/browser/tabpersistence/TabStateFileManagerUnitTest.java
+++ b/chrome/browser/tabpersistence/android/java/src/org/chromium/chrome/browser/tabpersistence/TabStateFileManagerUnitTest.java
@@ -28,6 +28,7 @@
 import org.chromium.chrome.browser.tab.flatbuffer.TabLaunchTypeAtCreation;
 import org.chromium.chrome.browser.tab.flatbuffer.UserAgentType;
 import org.chromium.chrome.browser.tabpersistence.FlatBufferTabStateSerializer.TabStateFlatBufferDeserializeResult;
+import org.chromium.chrome.test.util.ByteBufferTestUtils;
 
 import java.io.DataOutputStream;
 import java.io.File;
@@ -52,6 +53,9 @@
     private static final @TabUserAgent int USER_AGENT = TabUserAgent.MOBILE;
     private static final long TAB_GROUP_ID_TOKEN_HIGH = 0x1234567890L;
     private static final long TAB_GROUP_ID_TOKEN_LOW = 0xABCDEF1234L;
+    private static final Token TAB_GROUP_ID =
+            new Token(TAB_GROUP_ID_TOKEN_HIGH, TAB_GROUP_ID_TOKEN_LOW);
+    private static final int LARGE_BYTE_BUFFER_SIZE = Integer.MAX_VALUE / 4;
 
     @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
 
@@ -77,6 +81,22 @@
     }
 
     @Test
+    public void testLargeContentsState() throws IOException {
+        File file = createTestTabStateFile();
+        ByteBuffer buffer = ByteBuffer.allocateDirect(LARGE_BYTE_BUFFER_SIZE);
+        for (int i = 0; i < LARGE_BYTE_BUFFER_SIZE; i++) {
+            buffer.put((byte) (i % Byte.MAX_VALUE));
+        }
+        WebContentsState contentsState = new WebContentsState(buffer);
+        contentsState.setVersion(WebContentsState.CONTENTS_STATE_CURRENT_VERSION);
+        TabState state = createTabState(contentsState);
+        TabStateFileManager.saveStateInternal(file, state, /* encrypted= */ false);
+        validateTestTabState(
+                TabStateFileManager.restoreTabStateInternal(file, /* isEncrypted= */ false),
+                contentsState);
+    }
+
+    @Test
     public void testInvalidBuffer() {
         byte[] bytes = new byte[5000];
         for (int i = 0; i < bytes.length; i++) {
@@ -439,36 +459,58 @@
 
     private TabState createTabStateWithMappedByteBuffer(File file, @Nullable Token tabGroupId)
             throws IOException {
-        TabState state = new TabState();
         FileInputStream fileInputStream = null;
-
         try {
             fileInputStream = new FileInputStream(file);
-            state.contentsState =
+            return createTabState(
                     new WebContentsState(
                             fileInputStream
                                     .getChannel()
                                     .map(
                                             FileChannel.MapMode.READ_ONLY,
                                             fileInputStream.getChannel().position(),
-                                            file.length()));
-            state.contentsState.setVersion(VERSION);
-            state.timestampMillis = TIMESTAMP;
-            state.parentId = PARENT_ID;
-            state.themeColor = THEME_COLOR;
-            state.openerAppId = OPENER_APP_ID;
-            state.tabLaunchTypeAtCreation = LAUNCH_TYPE_AT_CREATION;
-            state.rootId = ROOT_ID;
-            state.userAgent = USER_AGENT;
-            state.lastNavigationCommittedTimestampMillis = TIMESTAMP;
-            state.tabGroupId = tabGroupId;
+                                            file.length())),
+                    tabGroupId);
         } finally {
             StreamUtil.closeQuietly(fileInputStream);
         }
+    }
+
+    private static TabState createTabState(
+            WebContentsState contentsState, @Nullable Token tabGroupId) {
+        TabState state = new TabState();
+        state.contentsState = contentsState;
+        state.contentsState.setVersion(VERSION);
+        state.timestampMillis = TIMESTAMP;
+        state.parentId = PARENT_ID;
+        state.themeColor = THEME_COLOR;
+        state.openerAppId = OPENER_APP_ID;
+        state.tabLaunchTypeAtCreation = LAUNCH_TYPE_AT_CREATION;
+        state.rootId = ROOT_ID;
+        state.userAgent = USER_AGENT;
+        state.lastNavigationCommittedTimestampMillis = TIMESTAMP;
+        state.tabGroupId = tabGroupId;
         return state;
     }
 
+    private static TabState createTabState(WebContentsState contentsState) {
+        return createTabState(contentsState, TAB_GROUP_ID);
+    }
+
     private void validateTestTabState(TabState state, @Nullable Token tabGroupId) {
+        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(CONTENTS_STATE_BYTES.length);
+        for (int i = 0; i < CONTENTS_STATE_BYTES.length; i++) {
+            byteBuffer.put(CONTENTS_STATE_BYTES[i]);
+        }
+        validateTestTabState(state, tabGroupId, new WebContentsState(byteBuffer));
+    }
+
+    private static void validateTestTabState(TabState state, WebContentsState contentsState) {
+        validateTestTabState(state, TAB_GROUP_ID, contentsState);
+    }
+
+    private static void validateTestTabState(
+            TabState state, @Nullable Token tabGroupId, WebContentsState contentsState) {
         assertEquals(TIMESTAMP, state.timestampMillis);
         assertEquals(PARENT_ID, state.parentId);
         assertEquals(OPENER_APP_ID, state.openerAppId);
@@ -476,7 +518,6 @@
         assertEquals(THEME_COLOR, state.getThemeColor());
         assertEquals(LAUNCH_TYPE_AT_CREATION, state.tabLaunchTypeAtCreation);
         assertEquals(ROOT_ID, state.rootId);
-        assertEquals(CONTENTS_STATE_BYTES.length, state.contentsState.buffer().remaining());
         assertEquals(USER_AGENT, state.userAgent);
         assertEquals(TIMESTAMP, state.lastNavigationCommittedTimestampMillis);
         if (tabGroupId == null) {
@@ -484,13 +525,7 @@
         } else {
             assertEquals(tabGroupId, state.tabGroupId);
         }
-
-        byte[] bytesFromFile = new byte[CONTENTS_STATE_BYTES.length];
-        state.contentsState.buffer().get(bytesFromFile);
-
-        for (int i = 0; i < CONTENTS_STATE_BYTES.length; i++) {
-            assertEquals(bytesFromFile[i], CONTENTS_STATE_BYTES[i]);
-        }
+        ByteBufferTestUtils.verifyByteBuffer(state.contentsState.buffer(), contentsState.buffer());
     }
 
     private File createTestTabStateFile() throws IOException {
diff --git a/chrome/browser/top_level_storage_access_api/top_level_storage_access_permission_context.cc b/chrome/browser/top_level_storage_access_api/top_level_storage_access_permission_context.cc
index b33b1aeb..8e48257 100644
--- a/chrome/browser/top_level_storage_access_api/top_level_storage_access_permission_context.cc
+++ b/chrome/browser/top_level_storage_access_api/top_level_storage_access_permission_context.cc
@@ -211,34 +211,23 @@
   CHECK(settings_map);
   CHECK(persist);
 
-  // This permission was allowed, so store it. Because this is a superset of the
-  // regular storage access permission, we also store that one.
-  const net::SchemefulSite embedding_site(embedding_origin);
-  const GURL embedding_site_as_url = embedding_site.GetURL();
-  ContentSettingsPattern secondary_site_pattern =
-      ContentSettingsPattern::CreateBuilder()
-          ->WithScheme(embedding_site_as_url.scheme())
-          ->WithDomainWildcard()
-          ->WithHost(embedding_site_as_url.host())
-          ->WithPathWildcard()
-          ->WithPortWildcard()
-          ->Build();
-
   content_settings::ContentSettingConstraints constraints;
   constraints.set_lifetime(
       permissions::kStorageAccessAPIRelatedWebsiteSetsLifetime);
   constraints.set_session_model(
       content_settings::mojom::SessionModel::NON_RESTORABLE_USER_SESSION);
 
-  settings_map->SetContentSettingCustomScope(
-      ContentSettingsPattern::FromURLNoWildcard(requesting_origin),
-      secondary_site_pattern, ContentSettingsType::TOP_LEVEL_STORAGE_ACCESS,
-      content_setting, constraints);
+  settings_map->SetContentSettingDefaultScope(
+      requesting_origin, embedding_origin,
+      ContentSettingsType::TOP_LEVEL_STORAGE_ACCESS, content_setting,
+      constraints);
 
+  // Because this is a superset of the regular storage access permission, we
+  // also store that one.
   settings_map->SetContentSettingCustomScope(
       ContentSettingsPattern::FromURLNoWildcard(requesting_origin),
-      secondary_site_pattern, ContentSettingsType::STORAGE_ACCESS,
-      content_setting, constraints);
+      ContentSettingsPattern::FromURLToSchemefulSitePattern(embedding_origin),
+      ContentSettingsType::STORAGE_ACCESS, content_setting, constraints);
 
   ContentSettingsForOneType top_level_grants =
       settings_map->GetSettingsForOneType(
diff --git a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl.cc b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl.cc
index 62ec45d3..5d9fc0f 100644
--- a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl.cc
+++ b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl.cc
@@ -161,10 +161,10 @@
   // Fetch all complete valid credit cards on file.
   // Complete = contains number, expiration date and name on card.
   // Valid = unexpired with valid number format.
-  // TODO(b/40227496): `*field` must contain the updated field information.
-  std::vector<CreditCard> cards_to_suggest =
-      PaymentsSuggestionGenerator().GetTouchToFillCardsToSuggest(
-          manager_->client(), field, field.Type().GetStorableType());
+  // TODO(crbug.com/40227496): `*field` must contain the updated field
+  // information.
+  std::vector<CreditCard> cards_to_suggest = GetTouchToFillCardsToSuggest(
+      manager_->client(), field, field.Type().GetStorableType());
   return cards_to_suggest.empty()
              ? DryRunResult(TriggerOutcome::kNoValidPaymentMethods, {})
              : DryRunResult(TriggerOutcome::kShown,
@@ -408,16 +408,14 @@
     base::span<const CreditCard> credit_cards) {
   std::vector<bool> card_acceptabilities;
   card_acceptabilities.reserve(credit_cards.size());
-  PaymentsSuggestionGenerator autofill_suggestion_generator;
 
-  std::transform(
-      credit_cards.begin(), credit_cards.end(),
-      std::back_inserter(card_acceptabilities),
-      [this, &autofill_suggestion_generator](const CreditCard& credit_card) {
-        return autofill_suggestion_generator.IsCardAcceptable(
-            credit_card, manager_->client(),
-            /*is_manual_fallback=*/false);
-      });
+  std::transform(credit_cards.begin(), credit_cards.end(),
+                 std::back_inserter(card_acceptabilities),
+                 [this](const CreditCard& credit_card) {
+                   return IsCardSuggestionAcceptable(
+                       credit_card, manager_->client(),
+                       /*is_manual_fallback=*/false);
+                 });
   return card_acceptabilities;
 }
 
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index a8726dd..67dad73 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -3537,6 +3537,8 @@
       "webui/ash/print_preview_cros/print_preview_cros_dialog.h",
       "webui/ash/remote_maintenance_curtain_ui.cc",
       "webui/ash/remote_maintenance_curtain_ui.h",
+      "webui/ash/sanitize_dialog.cc",
+      "webui/ash/sanitize_dialog.h",
       "webui/ash/scalable_iph/scalable_iph_debug_ui.cc",
       "webui/ash/scalable_iph/scalable_iph_debug_ui.h",
       "webui/ash/sensor_info/sensor_info_ui.cc",
diff --git a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/BottomBarConfig.java b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/BottomBarConfig.java
index 2546be0..0a566fa 100644
--- a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/BottomBarConfig.java
+++ b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/BottomBarConfig.java
@@ -7,11 +7,13 @@
 import android.app.PendingIntent;
 import android.graphics.drawable.Drawable;
 
+import androidx.annotation.IntDef;
 import androidx.annotation.Nullable;
 
 import org.chromium.chrome.browser.browserservices.intents.CustomButtonParams;
-import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
 /**
@@ -20,6 +22,35 @@
  */
 class BottomBarConfig {
 
+    /**
+     * Each button is encoded as: 1 - Page Insights Hub with basic icon 2 - Chrome Share 3 - Save 4
+     * - Add notes 5 - Chrome Refresh 6 - Page Insights Hub with coloured icon 7 - Page Insights Hub
+     * with expanded icon 8 - Custom button
+     */
+    @IntDef({
+        ButtonId.PIH_BASIC,
+        ButtonId.SHARE,
+        ButtonId.SAVE,
+        ButtonId.ADD_NOTES,
+        ButtonId.REFRESH,
+        ButtonId.PIH_COLORED,
+        ButtonId.PIH_EXPANDED,
+        ButtonId.CUSTOM,
+        ButtonId.MAX_BUTTON_ID,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ButtonId {
+        int PIH_BASIC = 1;
+        int SHARE = 2;
+        int SAVE = 3;
+        int ADD_NOTES = 4;
+        int REFRESH = 5;
+        int PIH_COLORED = 6;
+        int PIH_EXPANDED = 7;
+        int CUSTOM = 8;
+        int MAX_BUTTON_ID = CUSTOM;
+    }
+
     private final @Nullable @ButtonId Integer mSpotlightId;
     private final List<ButtonConfig> mButtonList;
 
diff --git a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/BottomBarConfigCreator.java b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/BottomBarConfigCreator.java
index f0a4e319..a55e511 100644
--- a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/BottomBarConfigCreator.java
+++ b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/BottomBarConfigCreator.java
@@ -6,16 +6,17 @@
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 
-import androidx.annotation.IntDef;
 import androidx.annotation.Nullable;
 
 import org.chromium.base.Log;
+import org.chromium.base.cached_flags.StringCachedFieldTrialParameter;
 import org.chromium.chrome.browser.browserservices.intents.CustomButtonParams;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonConfig;
+import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId;
+import org.chromium.chrome.browser.ui.google_bottom_bar.proto.IntentParams.GoogleBottomBarIntentParams;
 import org.chromium.ui.UiUtils;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -26,6 +27,7 @@
 /** This class creates a {@link BottomBarConfig} based on provided params. */
 public class BottomBarConfigCreator {
     private static final String TAG = "GoogleBottomBar";
+    private static final String BUTTON_LIST_PARAM = "google_bottom_bar_button_list";
     private static final Map<Integer, Integer> CUSTOM_BUTTON_PARAM_ID_TO_BUTTON_ID_MAP =
             Map.of(
                     100,
@@ -40,8 +42,17 @@
                     ButtonId.CUSTOM);
     private static final List<Integer> DEFAULT_BUTTON_ID_LIST =
             List.of(ButtonId.SAVE, ButtonId.PIH_BASIC, ButtonId.SHARE);
+
     private final Context mContext;
 
+    /**
+     * A cached parameter representing the order of Google Bottom Bar buttons based on experiment
+     * configuration.
+     */
+    public static final StringCachedFieldTrialParameter GOOGLE_BOTTOM_BAR_PARAM_BUTTON_LIST =
+            ChromeFeatureList.newStringCachedFieldTrialParameter(
+                    ChromeFeatureList.CCT_GOOGLE_BOTTOM_BAR, BUTTON_LIST_PARAM, "");
+
     /** Returns true if the id of the custom button param is supported. */
     static boolean shouldAddToGoogleBottomBar(int customButtonParamsId) {
         return CUSTOM_BUTTON_PARAM_ID_TO_BUTTON_ID_MAP.containsKey(customButtonParamsId);
@@ -64,72 +75,33 @@
     }
 
     /**
-     * @param encodedLayout String with the following representation: "5,1,2,3,4,5", where the first
-     *     item represents the spotlight button and the rest of the list the order of the buttons in
-     *     the bottom bar.
-     * @param customButtonParams Parameters for custom buttons provided by the client
-     * @return {@link BottomBarConfig} that contains an ordered list of the buttons and the
-     *     spotlight if available
-     */
-    BottomBarConfig create(String encodedLayout, List<CustomButtonParams> customButtonParams) {
-        List<Integer> encodedList = getEncodedListFromString(encodedLayout);
-
-        return create(encodedList, customButtonParams);
-    }
-
-    /**
-     * @param encodedLayoutList Integer list with the following representation [5,1,2,3,4,5], where
-     *     the first item represents the spotlight button and the rest of the list the order of the
-     *     buttons in the bottom bar.
-     * @param customButtonParams Parameters for custom buttons provided by the client
-     * @return {@link BottomBarConfig} that contains an ordered list of the buttons and the
-     *     spotlight if available
+     * @param intentParams that optionally contains:
+     *     <p>Integer list with the following representation [5,1,2,3,4,5], where the first item
+     *     represents the spotlight button and the rest of the list the order of the buttons in the
+     *     bottom bar.
+     *     <p>Variant layout type that specifies variation of the layout that should be used
+     * @param customButtonParamsList Parameters for custom buttons provided by the client
+     * @return {@link BottomBarConfig} that contains an ordered list of the buttons, the
+     *     spotlight(if available) and variant layout type(if available)
      */
     BottomBarConfig create(
-            List<Integer> encodedLayoutList, List<CustomButtonParams> customButtonParams) {
-        if (encodedLayoutList.isEmpty()) {
-            Log.e(TAG, "The list is empty or has wrong format");
-            return createDefaultConfig(customButtonParams);
-        }
+            GoogleBottomBarIntentParams intentParams,
+            List<CustomButtonParams> customButtonParamsList) {
 
-        if (encodedLayoutList.size() < 2) {
-            Log.e(TAG, "The list doesn't have enough parameters");
-            return createDefaultConfig(customButtonParams);
-        }
-
-        List<Integer> buttonIdList =
-                encodedLayoutList.subList(1, encodedLayoutList.size()); // remove spotlight
-
-        long validButtonListSize =
-                buttonIdList.stream().filter(BottomBarConfigCreator::isValidButtonId).count();
-
-        if (validButtonListSize != buttonIdList.size()) {
-            Log.e(TAG, "The list has non-valid button ids");
-            return createDefaultConfig(customButtonParams);
-        }
-
-        // 0 aka no spotlight is not encoded in ButtonId so it must be checked separately
-        int spotlitButton = encodedLayoutList.get(0);
-
-        if (!isValidButtonId(spotlitButton) && spotlitButton != 0) {
-            Log.e(TAG, "The spotlight button id is not supported");
-            return createDefaultConfig(customButtonParams);
-        }
-
-        return new BottomBarConfig(
-                createSpotlight(spotlitButton),
-                createButtonConfigList(buttonIdList, customButtonParams));
+        List<Integer> encodedLayoutList =
+                intentParams.getEncodedButtonCount() != 0
+                        // Encoded button list provided in intent from embedder
+                        ? intentParams.getEncodedButtonList()
+                        :
+                        // Fall back on encoded string provided in Finch param
+                        getEncodedListFromString(GOOGLE_BOTTOM_BAR_PARAM_BUTTON_LIST.getValue());
+        return create(encodedLayoutList, customButtonParamsList);
     }
 
     BottomBarConfigCreator(Context context) {
         mContext = context;
     }
 
-    @Nullable
-    private static @ButtonId Integer createSpotlight(int code) {
-        return code != 0 ? code : null;
-    }
-
     private List<ButtonConfig> createButtonConfigList(
             List<Integer> buttonIdList, List<CustomButtonParams> customButtonParams) {
         List<ButtonConfig> buttonConfigs = new ArrayList<>();
@@ -160,26 +132,6 @@
         return null;
     }
 
-    private static List<Integer> getEncodedListFromString(String encodedConfig) {
-        List<Integer> result;
-
-        try {
-            result =
-                    Arrays.stream(encodedConfig.split(","))
-                            .mapToInt(Integer::parseInt)
-                            .boxed()
-                            .collect(Collectors.toList());
-        } catch (NumberFormatException e) {
-            result = Collections.emptyList();
-        }
-
-        return result;
-    }
-
-    private static @ButtonId Integer getButtonId(int customButtonParamId) {
-        return CUSTOM_BUTTON_PARAM_ID_TO_BUTTON_ID_MAP.get(customButtonParamId);
-    }
-
     /** Create default {@link ButtonConfig} for the given ID. */
     private @Nullable ButtonConfig createButtonConfigFromId(@ButtonId int id) {
         switch (id) {
@@ -228,32 +180,72 @@
     }
 
     /**
-     * Each button is encoded as: 1 - Page Insights Hub with basic icon 2 - Chrome Share 3 - Save 4
-     * - Add notes 5 - Chrome Refresh 6 - Page Insights Hub with coloured icon 7 - Page Insights Hub
-     * with expanded icon 8 - Custom button
+     * @param encodedLayoutList Integer list with the following representation [5,1,2,3,4,5], where
+     *     the first item represents the spotlight button and the rest of the list the order of the
+     *     buttons in the bottom bar.
+     * @param customButtonParams Parameters for custom buttons provided by the client
+     * @return {@link BottomBarConfig} that contains an ordered list of the buttons and the
+     *     spotlight if available
      */
-    @IntDef({
-        ButtonId.PIH_BASIC,
-        ButtonId.SHARE,
-        ButtonId.SAVE,
-        ButtonId.ADD_NOTES,
-        ButtonId.REFRESH,
-        ButtonId.PIH_COLORED,
-        ButtonId.PIH_EXPANDED,
-        ButtonId.CUSTOM,
-        ButtonId.MAX_BUTTON_ID,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ButtonId {
-        int PIH_BASIC = 1;
-        int SHARE = 2;
-        int SAVE = 3;
-        int ADD_NOTES = 4;
-        int REFRESH = 5;
-        int PIH_COLORED = 6;
-        int PIH_EXPANDED = 7;
-        int CUSTOM = 8;
-        int MAX_BUTTON_ID = CUSTOM;
+    private BottomBarConfig create(
+            List<Integer> encodedLayoutList, List<CustomButtonParams> customButtonParams) {
+        if (encodedLayoutList.isEmpty()) {
+            Log.e(TAG, "The list is empty or has wrong format");
+            return createDefaultConfig(customButtonParams);
+        }
+
+        if (encodedLayoutList.size() < 2) {
+            Log.e(TAG, "The list doesn't have enough parameters");
+            return createDefaultConfig(customButtonParams);
+        }
+
+        List<Integer> buttonIdList =
+                encodedLayoutList.subList(1, encodedLayoutList.size()); // remove spotlight
+
+        long validButtonListSize =
+                buttonIdList.stream().filter(BottomBarConfigCreator::isValidButtonId).count();
+
+        if (validButtonListSize != buttonIdList.size()) {
+            Log.e(TAG, "The list has non-valid button ids");
+            return createDefaultConfig(customButtonParams);
+        }
+
+        // 0 aka no spotlight is not encoded in ButtonId so it must be checked separately
+        int spotlightButton = encodedLayoutList.get(0);
+
+        if (!isValidButtonId(spotlightButton) && spotlightButton != 0) {
+            Log.e(TAG, "The spotlight button id is not supported");
+            return createDefaultConfig(customButtonParams);
+        }
+
+        return new BottomBarConfig(
+                createSpotlight(spotlightButton),
+                createButtonConfigList(buttonIdList, customButtonParams));
+    }
+
+    @Nullable
+    private static @ButtonId Integer createSpotlight(int code) {
+        return code != 0 ? code : null;
+    }
+
+    private static List<Integer> getEncodedListFromString(String encodedConfig) {
+        List<Integer> result;
+
+        try {
+            result =
+                    Arrays.stream(encodedConfig.split(","))
+                            .mapToInt(Integer::parseInt)
+                            .boxed()
+                            .collect(Collectors.toList());
+        } catch (NumberFormatException e) {
+            result = Collections.emptyList();
+        }
+
+        return result;
+    }
+
+    private static @ButtonId Integer getButtonId(int customButtonParamId) {
+        return CUSTOM_BUTTON_PARAM_ID_TO_BUTTON_ID_MAP.get(customButtonParamId);
     }
 
     /**
diff --git a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/BottomBarConfigCreatorTest.java b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/BottomBarConfigCreatorTest.java
index 4b5e5fd..b20b1a3 100644
--- a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/BottomBarConfigCreatorTest.java
+++ b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/BottomBarConfigCreatorTest.java
@@ -11,11 +11,11 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId.ADD_NOTES;
-import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId.PIH_BASIC;
-import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId.REFRESH;
-import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId.SAVE;
-import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId.SHARE;
+import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId.ADD_NOTES;
+import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId.PIH_BASIC;
+import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId.REFRESH;
+import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId.SAVE;
+import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId.SHARE;
 
 import android.app.PendingIntent;
 import android.content.Context;
@@ -37,7 +37,7 @@
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Batch;
 import org.chromium.chrome.browser.browserservices.intents.CustomButtonParams;
-import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId;
+import org.chromium.chrome.browser.ui.google_bottom_bar.proto.IntentParams.GoogleBottomBarIntentParams;
 import org.chromium.ui.UiUtils;
 import org.chromium.ui.base.TestActivity;
 
@@ -69,27 +69,46 @@
 
     @Test
     public void emptyString_returnsDefaultConfig() {
-        assertDefaultConfig(mConfigCreator.create("", List.of()));
+        GoogleBottomBarIntentParams params = GoogleBottomBarIntentParams.getDefaultInstance();
+        assertDefaultConfig(mConfigCreator.create(params, List.of()));
     }
 
     @Test
     public void onlyOneItem_returnsDefaultConfig() {
-        assertDefaultConfig(mConfigCreator.create("1", List.of()));
+        GoogleBottomBarIntentParams params =
+                GoogleBottomBarIntentParams.newBuilder().addEncodedButton(1).build();
+
+        assertDefaultConfig(mConfigCreator.create(params, List.of()));
     }
 
     @Test
     public void invalidButtonIdInList_returnsDefaultConfig() {
-        assertDefaultConfig(mConfigCreator.create("0,10,1", List.of()));
+        GoogleBottomBarIntentParams params =
+                GoogleBottomBarIntentParams.newBuilder()
+                        .addAllEncodedButton(List.of(0, 10, 1))
+                        .build();
+
+        assertDefaultConfig(mConfigCreator.create(params, List.of()));
     }
 
     @Test
     public void invalidSpotlightButton_returnsDefaultConfig() {
-        assertDefaultConfig(mConfigCreator.create("10,1,2,3", List.of()));
+        GoogleBottomBarIntentParams params =
+                GoogleBottomBarIntentParams.newBuilder()
+                        .addAllEncodedButton(List.of(10, 1, 2, 3))
+                        .build();
+
+        assertDefaultConfig(mConfigCreator.create(params, List.of()));
     }
 
     @Test
     public void noSpotlightParamList_nullSpotlight_correctButtonList() {
-        BottomBarConfig buttonConfig = mConfigCreator.create("0,1,2,3", List.of());
+        GoogleBottomBarIntentParams params =
+                GoogleBottomBarIntentParams.newBuilder()
+                        .addAllEncodedButton(List.of(0, 1, 2, 3))
+                        .build();
+
+        BottomBarConfig buttonConfig = mConfigCreator.create(params, List.of());
 
         assertNull(buttonConfig.getSpotlightId());
         assertEquals(3, buttonConfig.getButtonList().size());
@@ -98,7 +117,12 @@
 
     @Test
     public void withSpotlightParamList_correctSpotlightSet_correctButtonList() {
-        BottomBarConfig buttonConfig = mConfigCreator.create("1,1,2,3", List.of());
+        GoogleBottomBarIntentParams params =
+                GoogleBottomBarIntentParams.newBuilder()
+                        .addAllEncodedButton(List.of(1, 1, 2, 3))
+                        .build();
+
+        BottomBarConfig buttonConfig = mConfigCreator.create(params, List.of());
         Integer spotlight = buttonConfig.getSpotlightId();
 
         assertNotNull(spotlight);
@@ -109,9 +133,11 @@
     @Test
     public void createButtonConfigList_emptyCustomButtonParamsList() {
         List<Integer> buttonIdList = List.of(PIH_BASIC, PIH_BASIC, SHARE, SAVE, ADD_NOTES, REFRESH);
+        GoogleBottomBarIntentParams params =
+                GoogleBottomBarIntentParams.newBuilder().addAllEncodedButton(buttonIdList).build();
 
         // empty customButtonParamsList - SAVE and ADD_NOTES are not included in the final list
-        BottomBarConfig buttonConfig = mConfigCreator.create(buttonIdList, new ArrayList<>());
+        BottomBarConfig buttonConfig = mConfigCreator.create(params, new ArrayList<>());
         assertEquals(3, buttonConfig.getButtonList().size());
     }
 
@@ -121,25 +147,27 @@
                 List.of(
                         PIH_BASIC, PIH_BASIC, SHARE, SAVE, ADD_NOTES,
                         REFRESH); // PIH_BASIC, SHARE, SAVE, ADD_NOTES, REFRESH
+        GoogleBottomBarIntentParams params =
+                GoogleBottomBarIntentParams.newBuilder().addAllEncodedButton(buttonIdList).build();
         Drawable drawable = mock(Drawable.class);
         when(mCustomButtonParams.getId()).thenReturn(100); // SAVE
         when(mCustomButtonParams.getIcon(mContext)).thenReturn(drawable);
 
         // ADD_NOTES and REFRESH are not included in the final list as they are not supported
-        BottomBarConfig buttonConfig =
-                mConfigCreator.create(buttonIdList, List.of(mCustomButtonParams));
+        BottomBarConfig buttonConfig = mConfigCreator.create(params, List.of(mCustomButtonParams));
         assertEquals(3, buttonConfig.getButtonList().size());
     }
 
     @Test
     public void createButtonConfigList_buttonIdListWithoutCustomParamId() {
         List<Integer> buttonIdList = List.of(PIH_BASIC, PIH_BASIC, SHARE); // PIH_BASIC, SHARE
+        GoogleBottomBarIntentParams params =
+                GoogleBottomBarIntentParams.newBuilder().addAllEncodedButton(buttonIdList).build();
 
         when(mCustomButtonParams.getId()).thenReturn(100); // SAVE
 
         // SAVE is not included in the final list
-        BottomBarConfig buttonConfig =
-                mConfigCreator.create(buttonIdList, List.of(mCustomButtonParams));
+        BottomBarConfig buttonConfig = mConfigCreator.create(params, List.of(mCustomButtonParams));
         assertEquals(2, buttonConfig.getButtonList().size());
     }
 
@@ -150,10 +178,13 @@
         when(mCustomButtonParams.getIcon(mContext)).thenReturn(drawable);
         var pendingIntent = mock(PendingIntent.class);
         when(mCustomButtonParams.getPendingIntent()).thenReturn(pendingIntent);
-
         // PIH_BASIC, SHARE, SAVE, REFRESH
-        BottomBarConfig buttonConfig =
-                mConfigCreator.create("1,1,2,3,5", List.of(mCustomButtonParams));
+        GoogleBottomBarIntentParams params =
+                GoogleBottomBarIntentParams.newBuilder()
+                        .addAllEncodedButton(List.of(1, 1, 2, 3, 5))
+                        .build();
+
+        BottomBarConfig buttonConfig = mConfigCreator.create(params, List.of(mCustomButtonParams));
 
         // the button has the expected custom button params set
         assertEquals(pendingIntent, buttonConfig.getButtonList().get(2).getPendingIntent());
@@ -166,10 +197,13 @@
         when(mCustomButtonParams.getIcon(mContext)).thenReturn(drawable);
         var pendingIntent = mock(PendingIntent.class);
         when(mCustomButtonParams.getPendingIntent()).thenReturn(pendingIntent);
-
         // PIH_BASIC, SHARE, SAVE
-        BottomBarConfig buttonConfig =
-                mConfigCreator.create("0,1,2,3", List.of(mCustomButtonParams));
+        GoogleBottomBarIntentParams params =
+                GoogleBottomBarIntentParams.newBuilder()
+                        .addAllEncodedButton(List.of(0, 1, 2, 3))
+                        .build();
+
+        BottomBarConfig buttonConfig = mConfigCreator.create(params, List.of(mCustomButtonParams));
 
         Bitmap expectedBitmap =
                 drawableToBitmap(
@@ -197,8 +231,8 @@
     private static void assertDefaultConfig(BottomBarConfig config) {
         assertNull(config.getSpotlightId());
         assertEquals(3, config.getButtonList().size());
-        assertEquals(ButtonId.SAVE, config.getButtonList().get(0).getId());
-        assertEquals(ButtonId.PIH_BASIC, config.getButtonList().get(1).getId());
-        assertEquals(ButtonId.SHARE, config.getButtonList().get(2).getId());
+        assertEquals(SAVE, config.getButtonList().get(0).getId());
+        assertEquals(PIH_BASIC, config.getButtonList().get(1).getId());
+        assertEquals(SHARE, config.getButtonList().get(2).getId());
     }
 }
diff --git a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarActionsHandler.java b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarActionsHandler.java
index b2acb7f..25edfc3 100644
--- a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarActionsHandler.java
+++ b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarActionsHandler.java
@@ -19,7 +19,7 @@
 import org.chromium.chrome.browser.share.ShareDelegate;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonConfig;
-import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId;
+import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId;
 import org.chromium.chrome.browser.ui.google_bottom_bar.GoogleBottomBarLogger.GoogleBottomBarButtonEvent;
 import org.chromium.chrome.browser.util.ChromeAccessibilityUtil;
 import org.chromium.components.browser_ui.widget.textbubble.TextBubble;
diff --git a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarActionsHandlerTest.java b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarActionsHandlerTest.java
index 57ac8ef..dc97682 100644
--- a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarActionsHandlerTest.java
+++ b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarActionsHandlerTest.java
@@ -12,6 +12,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId.PIH_BASIC;
 import static org.chromium.chrome.browser.ui.google_bottom_bar.GoogleBottomBarLogger.BUTTON_CLICKED_HISTOGRAM;
 
 import android.app.Activity;
@@ -41,7 +42,7 @@
 import org.chromium.chrome.browser.page_insights.PageInsightsCoordinator;
 import org.chromium.chrome.browser.share.ShareDelegate;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId;
+import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId;
 import org.chromium.chrome.browser.ui.google_bottom_bar.GoogleBottomBarLogger.GoogleBottomBarButtonEvent;
 import org.chromium.components.browser_ui.widget.textbubble.TextBubble;
 import org.chromium.ui.base.TestActivity;
@@ -209,7 +210,7 @@
         View buttonView = new View(context);
         BottomBarConfig.ButtonConfig buttonConfig =
                 new BottomBarConfig.ButtonConfig(
-                        ButtonId.PIH_BASIC,
+                        PIH_BASIC,
                         context.getDrawable(R.drawable.page_insights_icon),
                         context.getString(
                                 R.string.google_bottom_bar_page_insights_button_description),
@@ -233,7 +234,7 @@
         View buttonView = new View(context);
         BottomBarConfig.ButtonConfig buttonConfig =
                 new BottomBarConfig.ButtonConfig(
-                        ButtonId.PIH_BASIC,
+                        PIH_BASIC,
                         context.getDrawable(R.drawable.page_insights_icon),
                         context.getString(
                                 R.string.google_bottom_bar_page_insights_button_description),
@@ -257,7 +258,7 @@
         View buttonView = new View(context);
         BottomBarConfig.ButtonConfig buttonConfig =
                 new BottomBarConfig.ButtonConfig(
-                        BottomBarConfigCreator.ButtonId.PIH_BASIC,
+                        PIH_BASIC,
                         context.getDrawable(R.drawable.page_insights_icon),
                         context.getString(
                                 R.string.google_bottom_bar_page_insights_button_description),
diff --git a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarCoordinator.java b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarCoordinator.java
index 4ef0e7a..9a36161a 100644
--- a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarCoordinator.java
+++ b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarCoordinator.java
@@ -12,7 +12,6 @@
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.base.Log;
-import org.chromium.base.cached_flags.StringCachedFieldTrialParameter;
 import org.chromium.base.supplier.Supplier;
 import org.chromium.chrome.browser.browserservices.intents.CustomButtonParams;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
@@ -29,11 +28,6 @@
 public class GoogleBottomBarCoordinator {
 
     private static final String TAG = "GBBCoordinator";
-    private static final String BUTTON_LIST_PARAM = "google_bottom_bar_button_list";
-
-    public static final StringCachedFieldTrialParameter GOOGLE_BOTTOM_BAR_PARAM_BUTTON_LIST =
-            ChromeFeatureList.newStringCachedFieldTrialParameter(
-                    ChromeFeatureList.CCT_GOOGLE_BOTTOM_BAR, BUTTON_LIST_PARAM, "");
 
     /** Returns true if GoogleBottomBar is enabled in the feature flag. */
     public static boolean isFeatureEnabled() {
@@ -124,16 +118,7 @@
             GoogleBottomBarIntentParams intentParams,
             List<CustomButtonParams> customButtonsOnGoogleBottomBar) {
         BottomBarConfigCreator configCreator = new BottomBarConfigCreator(mContext);
-
-        // Encoded button list provided in intent from embedder
-        if (intentParams.getEncodedButtonCount() != 0) {
-            return configCreator.create(
-                    intentParams.getEncodedButtonList(), customButtonsOnGoogleBottomBar);
-        }
-
-        // Fall back on encoded string provided in Finch param
-        return configCreator.create(
-                GOOGLE_BOTTOM_BAR_PARAM_BUTTON_LIST.getValue(), customButtonsOnGoogleBottomBar);
+        return configCreator.create(intentParams, customButtonsOnGoogleBottomBar);
     }
 
     private @Nullable PageInsightsCoordinator getPageInsightsCoordinator() {
diff --git a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarCoordinatorTest.java b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarCoordinatorTest.java
index 0401338..50a57af 100644
--- a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarCoordinatorTest.java
+++ b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarCoordinatorTest.java
@@ -7,9 +7,9 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId.PIH_BASIC;
-import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId.SAVE;
-import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId.SHARE;
+import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId.PIH_BASIC;
+import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId.SAVE;
+import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId.SHARE;
 import static org.chromium.chrome.browser.ui.google_bottom_bar.GoogleBottomBarLogger.BOTTOM_BAR_CREATED_HISTOGRAM;
 import static org.chromium.chrome.browser.ui.google_bottom_bar.GoogleBottomBarLogger.BUTTON_SHOWN_HISTOGRAM;
 
@@ -34,6 +34,7 @@
 import org.chromium.chrome.browser.page_insights.PageInsightsCoordinator;
 import org.chromium.chrome.browser.share.ShareDelegate;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId;
 import org.chromium.chrome.browser.ui.google_bottom_bar.GoogleBottomBarLogger.GoogleBottomBarButtonEvent;
 import org.chromium.chrome.browser.ui.google_bottom_bar.GoogleBottomBarLogger.GoogleBottomBarCreatedEvent;
 import org.chromium.chrome.browser.ui.google_bottom_bar.proto.IntentParams.GoogleBottomBarIntentParams;
@@ -208,8 +209,7 @@
                 customButtonParamsList);
     }
 
-    private CustomButtonParams getMockCustomButtonParams(
-            @BottomBarConfigCreator.ButtonId int buttonId) {
+    private CustomButtonParams getMockCustomButtonParams(@ButtonId int buttonId) {
         CustomButtonParams customButtonParams = mock(CustomButtonParams.class);
         Drawable drawable = mock(Drawable.class);
         when(drawable.mutate()).thenReturn(drawable);
diff --git a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarLogger.java b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarLogger.java
index dee6af2..eaef9ac0 100644
--- a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarLogger.java
+++ b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarLogger.java
@@ -10,7 +10,7 @@
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.supplier.Supplier;
 import org.chromium.chrome.browser.page_insights.PageInsightsCoordinator;
-import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId;
+import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarViewCreator.java b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarViewCreator.java
index fb442b17..54d8aab 100644
--- a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarViewCreator.java
+++ b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarViewCreator.java
@@ -19,7 +19,7 @@
 import org.chromium.chrome.browser.share.ShareDelegate;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonConfig;
-import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId;
+import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId;
 import org.chromium.chrome.browser.ui.google_bottom_bar.GoogleBottomBarLogger.GoogleBottomBarCreatedEvent;
 
 /** Builds the GoogleBottomBar view. */
diff --git a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarViewCreatorTest.java b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarViewCreatorTest.java
index e444fc2..a255550 100644
--- a/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarViewCreatorTest.java
+++ b/chrome/browser/ui/android/google_bottom_bar/java/src/org/chromium/chrome/browser/ui/google_bottom_bar/GoogleBottomBarViewCreatorTest.java
@@ -10,10 +10,10 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId.CUSTOM;
-import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId.PIH_BASIC;
-import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId.SAVE;
-import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId.SHARE;
+import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId.CUSTOM;
+import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId.PIH_BASIC;
+import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId.SAVE;
+import static org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId.SHARE;
 import static org.chromium.chrome.browser.ui.google_bottom_bar.GoogleBottomBarLogger.BOTTOM_BAR_CREATED_HISTOGRAM;
 import static org.chromium.chrome.browser.ui.google_bottom_bar.GoogleBottomBarLogger.BUTTON_SHOWN_HISTOGRAM;
 import static org.chromium.chrome.browser.ui.google_bottom_bar.GoogleBottomBarLogger.BUTTON_UPDATED_HISTOGRAM;
@@ -43,9 +43,10 @@
 import org.chromium.chrome.browser.page_insights.PageInsightsCoordinator;
 import org.chromium.chrome.browser.share.ShareDelegate;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfigCreator.ButtonId;
+import org.chromium.chrome.browser.ui.google_bottom_bar.BottomBarConfig.ButtonId;
 import org.chromium.chrome.browser.ui.google_bottom_bar.GoogleBottomBarLogger.GoogleBottomBarButtonEvent;
 import org.chromium.chrome.browser.ui.google_bottom_bar.GoogleBottomBarLogger.GoogleBottomBarCreatedEvent;
+import org.chromium.chrome.browser.ui.google_bottom_bar.proto.IntentParams.GoogleBottomBarIntentParams;
 import org.chromium.ui.base.TestActivity;
 
 import java.util.ArrayList;
@@ -101,7 +102,9 @@
 
     private BottomBarConfig getEvenLayoutConfig() {
         List<Integer> buttonIdList = List.of(0, PIH_BASIC, SHARE, SAVE);
-        return mConfigCreator.create(buttonIdList, new ArrayList<>());
+        return mConfigCreator.create(
+                GoogleBottomBarIntentParams.newBuilder().addAllEncodedButton(buttonIdList).build(),
+                new ArrayList<>());
     }
 
     private void setUpPageInsightsCoordinatorSupplier() {
@@ -115,7 +118,9 @@
 
     private BottomBarConfig getAllChromeButtonsConfig(List<Integer> buttonIdList) {
         setUpPageInsightsCoordinatorSupplier();
-        return mConfigCreator.create(buttonIdList, new ArrayList<>());
+        return mConfigCreator.create(
+                GoogleBottomBarIntentParams.newBuilder().addAllEncodedButton(buttonIdList).build(),
+                new ArrayList<>());
     }
 
     private BottomBarConfig getAllEmbedderButtonsConfig() {
@@ -127,11 +132,12 @@
                         getMockCustomButtonParams(SHARE),
                         getMockCustomButtonParams(SAVE));
 
-        return mConfigCreator.create(buttonIdList, customButtonParamsList);
+        return mConfigCreator.create(
+                GoogleBottomBarIntentParams.newBuilder().addAllEncodedButton(buttonIdList).build(),
+                customButtonParamsList);
     }
 
-    private CustomButtonParams getMockCustomButtonParams(
-            @BottomBarConfigCreator.ButtonId int buttonId) {
+    private CustomButtonParams getMockCustomButtonParams(@ButtonId int buttonId) {
         CustomButtonParams customButtonParams = mock(CustomButtonParams.class);
         Drawable drawable = mock(Drawable.class);
         when(drawable.mutate()).thenReturn(drawable);
@@ -147,7 +153,9 @@
 
     private BottomBarConfig getSpotlightLayoutConfig() {
         List<Integer> buttonIdList = List.of(PIH_BASIC, PIH_BASIC, SHARE, SAVE);
-        return mConfigCreator.create(buttonIdList, new ArrayList<>());
+        return mConfigCreator.create(
+                GoogleBottomBarIntentParams.newBuilder().addAllEncodedButton(buttonIdList).build(),
+                new ArrayList<>());
     }
 
     @Test
@@ -225,7 +233,11 @@
         List<Integer> buttonIdList = List.of(0, PIH_BASIC);
         mGoogleBottomBarViewCreator =
                 getGoogleBottomBarViewCreator(
-                        mConfigCreator.create(buttonIdList, new ArrayList<>()));
+                        mConfigCreator.create(
+                                GoogleBottomBarIntentParams.newBuilder()
+                                        .addAllEncodedButton(buttonIdList)
+                                        .build(),
+                                new ArrayList<>()));
         mGoogleBottomBarViewCreator.createGoogleBottomBarView();
 
         mGoogleBottomBarViewCreator.logButtons();
@@ -248,10 +260,12 @@
         mGoogleBottomBarViewCreator =
                 getGoogleBottomBarViewCreator(
                         mConfigCreator.create(
-                                buttonIdList,
+                                GoogleBottomBarIntentParams.newBuilder()
+                                        .addAllEncodedButton(buttonIdList)
+                                        .build(),
                                 List.of(
                                         getMockCustomButtonParams(PIH_BASIC),
-                                        getMockCustomButtonParams(ButtonId.CUSTOM))));
+                                        getMockCustomButtonParams(CUSTOM))));
         mGoogleBottomBarViewCreator.createGoogleBottomBarView();
 
         mGoogleBottomBarViewCreator.logButtons();
@@ -273,7 +287,10 @@
         mGoogleBottomBarViewCreator =
                 getGoogleBottomBarViewCreator(
                         mConfigCreator.create(
-                                buttonIdList, List.of(getMockCustomButtonParams(PIH_BASIC))));
+                                GoogleBottomBarIntentParams.newBuilder()
+                                        .addAllEncodedButton(buttonIdList)
+                                        .build(),
+                                List.of(getMockCustomButtonParams(PIH_BASIC))));
         mGoogleBottomBarViewCreator.createGoogleBottomBarView();
 
         mGoogleBottomBarViewCreator.logButtons();
diff --git a/chrome/browser/ui/android/logo/java/res/values-sw600dp/dimens.xml b/chrome/browser/ui/android/logo/java/res/values-sw600dp/dimens.xml
index 25f76fc3..12a6f2d1 100644
--- a/chrome/browser/ui/android/logo/java/res/values-sw600dp/dimens.xml
+++ b/chrome/browser/ui/android/logo/java/res/values-sw600dp/dimens.xml
@@ -5,12 +5,12 @@
 found in the LICENSE file.
 -->
 <resources>
-  <dimen name="logo_height_polished">72dp</dimen>
-  <dimen name="logo_margin_top_polished">64dp</dimen>
-  <dimen name="logo_margin_bottom_polished">24dp</dimen>
+  <dimen name="ntp_logo_height">72dp</dimen>
+  <dimen name="ntp_logo_margin_top">64dp</dimen>
+  <dimen name="ntp_logo_margin_bottom">24dp</dimen>
   <dimen name="logo_height_logo_polish_large">112dp</dimen>
   <dimen name="logo_height_logo_polish_medium">104dp</dimen>
   <dimen name="logo_height_logo_polish_small">84dp</dimen>
-  <dimen name="logo_margin_top_logo_polish">@dimen/logo_margin_top_polished</dimen>
-  <dimen name="logo_margin_bottom_logo_polish">@dimen/logo_margin_bottom_polished</dimen>
+  <dimen name="logo_margin_top_logo_polish">@dimen/ntp_logo_margin_top</dimen>
+  <dimen name="logo_margin_bottom_logo_polish">@dimen/ntp_logo_margin_bottom</dimen>
 </resources>
diff --git a/chrome/browser/ui/android/logo/java/res/values/dimens.xml b/chrome/browser/ui/android/logo/java/res/values/dimens.xml
index 2dc9ce2..0922e97 100644
--- a/chrome/browser/ui/android/logo/java/res/values/dimens.xml
+++ b/chrome/browser/ui/android/logo/java/res/values/dimens.xml
@@ -5,9 +5,9 @@
 found in the LICENSE file.
 -->
 <resources>
-  <dimen name="logo_height_polished">48dp</dimen>
-  <dimen name="logo_margin_top_polished">12dp</dimen>
-  <dimen name="logo_margin_bottom_polished">24dp</dimen>
+  <dimen name="ntp_logo_height">48dp</dimen>
+  <dimen name="ntp_logo_margin_top">12dp</dimen>
+  <dimen name="ntp_logo_margin_bottom">24dp</dimen>
   <dimen name="logo_height_logo_polish_large">84dp</dimen>
   <dimen name="logo_height_logo_polish_medium">76dp</dimen>
   <dimen name="logo_height_logo_polish_small">68dp</dimen>
diff --git a/chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoUtils.java b/chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoUtils.java
index dce8fe0..3819c3c 100644
--- a/chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoUtils.java
+++ b/chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoUtils.java
@@ -28,22 +28,6 @@
         int LARGE = 2;
     }
 
-    /** Returns the top margin of the LogoView if Surface Polish is enabled. */
-    public static int getTopMarginPolished(Resources resources) {
-        return resources.getDimensionPixelSize(R.dimen.logo_margin_top_polished);
-    }
-
-    /** Returns the bottom margin of the LogoView if Surface Polish is enabled. */
-    public static int getBottomMarginPolished(Resources resources) {
-        return resources.getDimensionPixelSize(R.dimen.logo_margin_bottom_polished);
-    }
-
-    @VisibleForTesting
-    /** Returns the height of the LogoView if Surface Polish is enabled. */
-    public static int getLogoHeightPolished(Resources resources) {
-        return resources.getDimensionPixelSize(R.dimen.logo_height_polished);
-    }
-
     /** Returns the top margin of the LogoView if Logo Polish is enabled. */
     public static int getTopMarginForLogoPolish(Resources resources) {
         return resources.getDimensionPixelSize(R.dimen.logo_margin_top_logo_polish);
@@ -72,14 +56,11 @@
         return resources.getDimensionPixelSize(R.dimen.logo_height_logo_polish_small);
     }
 
-    /**
-     * Returns the sum of the height, the top margin and the bottom margin of the LogoView if
-     * Surface Polish is enabled.
-     */
-    public static int getLogoTotalHeightPolished(Resources resources) {
-        return getLogoHeightPolished(resources)
-                + getTopMarginPolished(resources)
-                + getBottomMarginPolished(resources);
+    /** Returns the sum of the height, the top margin and the bottom margin of the LogoView. */
+    public static int getLogoTotalHeight(Resources resources) {
+        return resources.getDimensionPixelSize(R.dimen.ntp_logo_height)
+                + resources.getDimensionPixelSize(R.dimen.ntp_logo_margin_top)
+                + resources.getDimensionPixelSize(R.dimen.ntp_logo_margin_bottom);
     }
 
     /**
@@ -106,22 +87,19 @@
                         + getTopMarginForLogoPolish(resources);
             default:
                 assert false;
-                return getLogoTotalHeightPolished(resources);
+                return getLogoTotalHeight(resources);
         }
     }
 
-    /**
-     * Sets the layout params for the LogoView when Surface Polished or Logo Polished is enabled.
-     */
+    /** Sets the layout params for the LogoView when Logo Polished is enabled. */
     public static void setLogoViewLayoutParams(
             LogoView logoView,
             Resources resources,
-            boolean isTablet,
             boolean isLogoPolishEnabled,
             final @LogoSizeForLogoPolish int logoSizeForLogoPolish) {
         MarginLayoutParams layoutParams = (MarginLayoutParams) logoView.getLayoutParams();
         setLogoViewLayoutParams(
-                layoutParams, resources, isTablet, isLogoPolishEnabled, logoSizeForLogoPolish);
+                layoutParams, resources, isLogoPolishEnabled, logoSizeForLogoPolish);
         if (layoutParams != null) {
             logoView.setLayoutParams(layoutParams);
         }
@@ -131,7 +109,6 @@
     public static void setLogoViewLayoutParams(
             MarginLayoutParams layoutParams,
             Resources resources,
-            boolean isTablet,
             boolean isLogoPolishEnabled,
             final @LogoSizeForLogoPolish int logoSizeForLogoPolish) {
         if (layoutParams == null) return;
@@ -157,9 +134,10 @@
                     assert false;
             }
         } else {
-            layoutParams.height = getLogoHeightPolished(resources);
-            layoutParams.topMargin = getTopMarginPolished(resources);
-            layoutParams.bottomMargin = getBottomMarginPolished(resources);
+            layoutParams.height = resources.getDimensionPixelSize(R.dimen.ntp_logo_height);
+            layoutParams.topMargin = resources.getDimensionPixelSize(R.dimen.ntp_logo_margin_top);
+            layoutParams.bottomMargin =
+                    resources.getDimensionPixelSize(R.dimen.ntp_logo_margin_bottom);
         }
     }
 }
diff --git a/chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoUtilsUnitTest.java b/chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoUtilsUnitTest.java
index 76144fc..8f21259 100644
--- a/chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoUtilsUnitTest.java
+++ b/chrome/browser/ui/android/logo/java/src/org/chromium/chrome/browser/logo/LogoUtilsUnitTest.java
@@ -36,10 +36,9 @@
     @SmallTest
     public void testSetLogoViewLayoutParams() {
         MarginLayoutParams layoutParams = new MarginLayoutParams(0, 0);
-        int logoHeight = mResources.getDimensionPixelSize(R.dimen.logo_height_polished);
-        int logoTopMargin = mResources.getDimensionPixelSize(R.dimen.logo_margin_top_polished);
-        int logoBottomMargin =
-                mResources.getDimensionPixelSize(R.dimen.logo_margin_bottom_polished);
+        int logoHeight = mResources.getDimensionPixelSize(R.dimen.ntp_logo_height);
+        int logoTopMargin = mResources.getDimensionPixelSize(R.dimen.ntp_logo_margin_top);
+        int logoBottomMargin = mResources.getDimensionPixelSize(R.dimen.ntp_logo_margin_bottom);
 
         int logoHeightLargeForLogoPolish =
                 mResources.getDimensionPixelSize(R.dimen.logo_height_logo_polish_large);
@@ -55,15 +54,6 @@
         LogoUtils.setLogoViewLayoutParams(
                 layoutParams,
                 mResources,
-                /* isTablet= */ false,
-                /* isLogoPolishEnabled= */ false,
-                /* logoSizeForLogoPolish= */ LogoSizeForLogoPolish.LARGE);
-        testSetLogoViewLayoutParamsImpl(logoHeight, logoTopMargin, logoBottomMargin, layoutParams);
-
-        LogoUtils.setLogoViewLayoutParams(
-                layoutParams,
-                mResources,
-                /* isTablet= */ true,
                 /* isLogoPolishEnabled= */ false,
                 /* logoSizeForLogoPolish= */ LogoSizeForLogoPolish.LARGE);
         testSetLogoViewLayoutParamsImpl(logoHeight, logoTopMargin, logoBottomMargin, layoutParams);
@@ -72,7 +62,6 @@
         LogoUtils.setLogoViewLayoutParams(
                 layoutParams,
                 mResources,
-                /* isTablet= */ false,
                 /* isLogoPolishEnabled= */ true,
                 /* logoSizeForLogoPolish= */ LogoSizeForLogoPolish.LARGE);
         testSetLogoViewLayoutParamsImpl(
@@ -84,19 +73,6 @@
         LogoUtils.setLogoViewLayoutParams(
                 layoutParams,
                 mResources,
-                /* isTablet= */ true,
-                /* isLogoPolishEnabled= */ true,
-                /* logoSizeForLogoPolish= */ LogoSizeForLogoPolish.LARGE);
-        testSetLogoViewLayoutParamsImpl(
-                logoHeightLargeForLogoPolish,
-                logoTopMarginForLogoPolish,
-                logoBottomMarginForLogoPolish,
-                layoutParams);
-
-        LogoUtils.setLogoViewLayoutParams(
-                layoutParams,
-                mResources,
-                /* isTablet= */ false,
                 /* isLogoPolishEnabled= */ true,
                 /* logoSizeForLogoPolish= */ LogoSizeForLogoPolish.MEDIUM);
         testSetLogoViewLayoutParamsImpl(
@@ -108,31 +84,6 @@
         LogoUtils.setLogoViewLayoutParams(
                 layoutParams,
                 mResources,
-                /* isTablet= */ true,
-                /* isLogoPolishEnabled= */ true,
-                /* logoSizeForLogoPolish= */ LogoSizeForLogoPolish.MEDIUM);
-        testSetLogoViewLayoutParamsImpl(
-                logoHeightMediumForLogoPolish,
-                logoTopMarginForLogoPolish,
-                logoBottomMarginForLogoPolish,
-                layoutParams);
-
-        LogoUtils.setLogoViewLayoutParams(
-                layoutParams,
-                mResources,
-                /* isTablet= */ false,
-                /* isLogoPolishEnabled= */ true,
-                /* logoSizeForLogoPolish= */ LogoSizeForLogoPolish.SMALL);
-        testSetLogoViewLayoutParamsImpl(
-                logoHeightSmallForLogoPolish,
-                logoTopMarginForLogoPolish,
-                logoBottomMarginForLogoPolish,
-                layoutParams);
-
-        LogoUtils.setLogoViewLayoutParams(
-                layoutParams,
-                mResources,
-                /* isTablet= */ true,
                 /* isLogoPolishEnabled= */ true,
                 /* logoSizeForLogoPolish= */ LogoSizeForLogoPolish.SMALL);
         testSetLogoViewLayoutParamsImpl(
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/CachedZeroSuggestionsManager.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/CachedZeroSuggestionsManager.java
index d44af979..cf33fd7 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/CachedZeroSuggestionsManager.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/CachedZeroSuggestionsManager.java
@@ -199,6 +199,7 @@
                             classifications,
                             null,
                             null,
+                            0,
                             null,
                             url,
                             GURL.emptyGURL(),
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java
index 83003090..66b5532 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java
@@ -19,8 +19,6 @@
 import org.chromium.components.omnibox.AnswerType;
 import org.chromium.components.omnibox.AutocompleteMatch;
 import org.chromium.components.omnibox.OmniboxSuggestionType;
-import org.chromium.components.omnibox.RichAnswerTemplateProto.RichAnswerTemplate;
-import org.chromium.components.omnibox.SuggestionAnswer;
 import org.chromium.components.omnibox.suggestions.OmniboxSuggestionUiType;
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.url.GURL;
@@ -73,14 +71,17 @@
         @AnswerType
         int answerType =
                 suggestion.getAnswer() == null
-                        ? AnswerType.INVALID
+                        ? suggestion.getAnswerType()
                         : suggestion.getAnswer().getType();
         boolean suggestionTextColorReversal = checkColorReversalRequired(answerType);
         AnswerText[] details;
         if (suggestion.getAnswerTemplate() != null) {
             details =
                     RichAnswerText.from(
-                            mContext, suggestion.getAnswerTemplate(), suggestionTextColorReversal);
+                            mContext,
+                            suggestion.getAnswerTemplate(),
+                            answerType,
+                            suggestionTextColorReversal);
         } else {
             details =
                     AnswerTextNewLayout.from(
@@ -141,10 +142,11 @@
     public @NonNull OmniboxDrawableState getFallbackIcon(@NonNull AutocompleteMatch suggestion) {
         int icon = 0;
 
-        SuggestionAnswer answer = suggestion.getAnswer();
-        int type = answer != null ? answer.getType() : AnswerType.INVALID;
-        RichAnswerTemplate template = suggestion.getAnswerTemplate();
-        type = template != null ? template.getAnswerType().getNumber() : type;
+        @AnswerType
+        int type =
+                suggestion.getAnswer() == null
+                        ? suggestion.getAnswerType()
+                        : suggestion.getAnswer().getType();
         if (type != AnswerType.INVALID) {
             switch (type) {
                 case AnswerType.DICTIONARY:
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessorUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessorUnitTest.java
index 56fe012..dbdcef3 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessorUnitTest.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessorUnitTest.java
@@ -199,7 +199,6 @@
             @AnswerType int type, String line1Text, String line2Text) {
         RichAnswerTemplate answer =
                 RichAnswerTemplate.newBuilder()
-                        .setAnswerType(RichAnswerTemplate.AnswerType.forNumber(type))
                         .addAnswers(
                                 AnswerData.newBuilder()
                                         .setHeadline(
@@ -214,6 +213,7 @@
         AutocompleteMatch suggestion =
                 AutocompleteMatchBuilder.searchWithType(OmniboxSuggestionType.SEARCH_SUGGEST)
                         .setSerializedAnswerTemplate(answer.toByteArray())
+                        .setAnswerType(type)
                         .build();
         PropertyModel model = mProcessor.createModel();
         return new SuggestionTestHelper(suggestion, model, null);
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/RichAnswerText.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/RichAnswerText.java
index ca2d661..a774acc 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/RichAnswerText.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/RichAnswerText.java
@@ -58,10 +58,10 @@
     static AnswerText[] from(
             @NonNull Context context,
             @NonNull RichAnswerTemplate richAnswerTemplate,
+            @AnswerType int answerType,
             boolean reverseStockTextColor) {
         RichAnswerText[] result = new RichAnswerText[2];
 
-        int answerType = richAnswerTemplate.getAnswerType().getNumber();
         int maxLines = getMaxLinesForAnswerType(answerType);
         if (answerType == AnswerType.DICTIONARY) {
             result[0] =
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/RichAnswerTextTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/RichAnswerTextTest.java
index 28f058b..e539f6d 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/RichAnswerTextTest.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/RichAnswerTextTest.java
@@ -24,10 +24,10 @@
 import org.chromium.components.omnibox.AnswerDataProto.FormattedString;
 import org.chromium.components.omnibox.AnswerDataProto.FormattedString.ColorType;
 import org.chromium.components.omnibox.AnswerDataProto.FormattedString.FormattedStringFragment;
+import org.chromium.components.omnibox.AnswerType;
 import org.chromium.components.omnibox.OmniboxFeatureList;
 import org.chromium.components.omnibox.OmniboxFeatures;
 import org.chromium.components.omnibox.RichAnswerTemplateProto.RichAnswerTemplate;
-import org.chromium.components.omnibox.RichAnswerTemplateProto.RichAnswerTemplate.AnswerType;
 
 /** Tests for {@link RichAnswerText}. */
 @RunWith(BaseRobolectricTestRunner.class)
@@ -90,13 +90,13 @@
 
         RichAnswerTemplate richAnswerTemplate =
                 RichAnswerTemplate.newBuilder()
-                        .setAnswerType(AnswerType.DICTIONARY)
                         .addAnswers(
                                 0,
                                 AnswerData.newBuilder().setHeadline(headline).setSubhead(subhead))
                         .build();
 
-        AnswerText[] texts = RichAnswerText.from(mContext, richAnswerTemplate, false);
+        int answerType = AnswerType.DICTIONARY;
+        AnswerText[] texts = RichAnswerText.from(mContext, richAnswerTemplate, answerType, false);
         Assert.assertEquals(texts[0].getMaxLines(), 1);
         Assert.assertEquals(texts[1].getMaxLines(), 3);
         Assert.assertEquals(texts[0].getAccessibilityDescription(), "define adroit • /əˈdroit/");
@@ -146,7 +146,6 @@
 
         RichAnswerTemplate richAnswerTemplate =
                 RichAnswerTemplate.newBuilder()
-                        .setAnswerType(AnswerType.FINANCE)
                         .addAnswers(
                                 0,
                                 AnswerData.newBuilder()
@@ -154,7 +153,8 @@
                                         .setSubhead(positiveSubhead))
                         .build();
 
-        AnswerText[] texts = RichAnswerText.from(mContext, richAnswerTemplate, false);
+        int answerType = AnswerType.FINANCE;
+        AnswerText[] texts = RichAnswerText.from(mContext, richAnswerTemplate, answerType, false);
         // A11y descriptions are reverse of visual ordering.
         Assert.assertEquals(
                 texts[0].getAccessibilityDescription(), "goog stock GOOG(NASDAQ), 3:22 PM EDT");
@@ -193,15 +193,13 @@
 
         RichAnswerTemplate negativeRichAnswerTemplate =
                 RichAnswerTemplate.newBuilder()
-                        .setAnswerType(AnswerType.FINANCE)
                         .addAnswers(
                                 0,
                                 AnswerData.newBuilder()
                                         .setHeadline(headline)
                                         .setSubhead(negativeSubhead))
                         .build();
-
-        texts = RichAnswerText.from(mContext, negativeRichAnswerTemplate, false);
+        texts = RichAnswerText.from(mContext, negativeRichAnswerTemplate, answerType, false);
         primaryText = texts[0].getText();
 
         Assert.assertEquals(primaryText.toString(), "100.00 -1.00");
@@ -238,7 +236,6 @@
 
         RichAnswerTemplate richAnswerTemplate =
                 RichAnswerTemplate.newBuilder()
-                        .setAnswerType(AnswerType.FINANCE)
                         .addAnswers(
                                 0,
                                 AnswerData.newBuilder()
@@ -246,7 +243,8 @@
                                         .setSubhead(positiveSubhead))
                         .build();
 
-        AnswerText[] texts = RichAnswerText.from(mContext, richAnswerTemplate, true);
+        int answerType = AnswerType.FINANCE;
+        AnswerText[] texts = RichAnswerText.from(mContext, richAnswerTemplate, answerType, true);
         SpannableStringBuilder primaryText = texts[0].getText();
 
         Assert.assertEquals(primaryText.toString(), "100.00 +1.00");
@@ -271,7 +269,6 @@
 
         RichAnswerTemplate negativeRichAnswerTemplate =
                 RichAnswerTemplate.newBuilder()
-                        .setAnswerType(AnswerType.FINANCE)
                         .addAnswers(
                                 0,
                                 AnswerData.newBuilder()
@@ -279,7 +276,7 @@
                                         .setSubhead(negativeSubhead))
                         .build();
 
-        texts = RichAnswerText.from(mContext, negativeRichAnswerTemplate, true);
+        texts = RichAnswerText.from(mContext, negativeRichAnswerTemplate, answerType, true);
         primaryText = texts[0].getText();
 
         Assert.assertEquals(primaryText.toString(), "100.00 -1.00");
@@ -310,13 +307,13 @@
 
         RichAnswerTemplate richAnswerTemplate =
                 RichAnswerTemplate.newBuilder()
-                        .setAnswerType(AnswerType.WEATHER)
                         .addAnswers(
                                 0,
                                 AnswerData.newBuilder().setHeadline(headline).setSubhead(subhead))
                         .build();
 
-        AnswerText[] texts = RichAnswerText.from(mContext, richAnswerTemplate, false);
+        int answerType = AnswerType.WEATHER;
+        AnswerText[] texts = RichAnswerText.from(mContext, richAnswerTemplate, answerType, false);
         Assert.assertEquals(texts[0].getMaxLines(), 1);
         Assert.assertEquals(texts[1].getMaxLines(), 1);
 
@@ -356,13 +353,13 @@
 
         RichAnswerTemplate richAnswerTemplate =
                 RichAnswerTemplate.newBuilder()
-                        .setAnswerType(AnswerType.TRANSLATION)
                         .addAnswers(
                                 0,
                                 AnswerData.newBuilder().setHeadline(headline).setSubhead(subhead))
                         .build();
 
-        AnswerText[] texts = RichAnswerText.from(mContext, richAnswerTemplate, false);
+        int answerType = AnswerType.TRANSLATION;
+        AnswerText[] texts = RichAnswerText.from(mContext, richAnswerTemplate, answerType, false);
         Assert.assertEquals(texts[0].getMaxLines(), 3);
         Assert.assertEquals(texts[1].getMaxLines(), 1);
     }
@@ -386,13 +383,13 @@
                         .build();
         RichAnswerTemplate richAnswerTemplate =
                 RichAnswerTemplate.newBuilder()
-                        .setAnswerType(AnswerType.CURRENCY)
                         .addAnswers(
                                 0,
                                 AnswerData.newBuilder().setHeadline(headline).setSubhead(subhead))
                         .build();
 
-        AnswerText[] texts = RichAnswerText.from(mContext, richAnswerTemplate, false);
+        int answerType = AnswerType.CURRENCY;
+        AnswerText[] texts = RichAnswerText.from(mContext, richAnswerTemplate, answerType, false);
         SpannableStringBuilder primaryText = texts[0].getText();
         SpannableStringBuilder secondaryText = texts[1].getText();
 
@@ -414,13 +411,13 @@
 
         RichAnswerTemplate richAnswerTemplate =
                 RichAnswerTemplate.newBuilder()
-                        .setAnswerType(AnswerType.WEATHER)
                         .addAnswers(
                                 0,
                                 AnswerData.newBuilder().setHeadline(headline).setSubhead(subhead))
                         .build();
 
-        AnswerText[] texts = RichAnswerText.from(mContext, richAnswerTemplate, false);
+        int answerType = AnswerType.WEATHER;
+        AnswerText[] texts = RichAnswerText.from(mContext, richAnswerTemplate, answerType, false);
         SpannableStringBuilder primaryText = texts[0].getText();
         SpannableStringBuilder secondaryText = texts[1].getText();
 
@@ -448,13 +445,13 @@
 
         RichAnswerTemplate richAnswerTemplate =
                 RichAnswerTemplate.newBuilder()
-                        .setAnswerType(AnswerType.WEATHER)
                         .addAnswers(
                                 0,
                                 AnswerData.newBuilder().setHeadline(headline).setSubhead(subhead))
                         .build();
 
-        AnswerText[] texts = RichAnswerText.from(mContext, richAnswerTemplate, false);
+        int answerType = AnswerType.WEATHER;
+        AnswerText[] texts = RichAnswerText.from(mContext, richAnswerTemplate, answerType, false);
         SpannableStringBuilder primaryText = texts[0].getText();
         SpannableStringBuilder secondaryText = texts[1].getText();
 
diff --git a/chrome/browser/ui/android/signin/java/res/layout/upgrade_promo_landscape_view.xml b/chrome/browser/ui/android/signin/java/res/layout/upgrade_promo_landscape_view.xml
index 6c68bef9..9718c41 100644
--- a/chrome/browser/ui/android/signin/java/res/layout/upgrade_promo_landscape_view.xml
+++ b/chrome/browser/ui/android/signin/java/res/layout/upgrade_promo_landscape_view.xml
@@ -5,7 +5,7 @@
 found in the LICENSE file.
 -->
 
-<ViewSwitcher
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/upgrade_promo_landscape"
     android:background="@macro/default_bg_color"
@@ -18,4 +18,4 @@
     <include
         android:id="@+id/history_sync"
         layout="@layout/history_sync_landscape_view"/>
-</ViewSwitcher>
\ No newline at end of file
+</FrameLayout>
\ No newline at end of file
diff --git a/chrome/browser/ui/android/signin/java/res/layout/upgrade_promo_portrait_view.xml b/chrome/browser/ui/android/signin/java/res/layout/upgrade_promo_portrait_view.xml
index ddc4896..aae8a9c 100644
--- a/chrome/browser/ui/android/signin/java/res/layout/upgrade_promo_portrait_view.xml
+++ b/chrome/browser/ui/android/signin/java/res/layout/upgrade_promo_portrait_view.xml
@@ -5,7 +5,7 @@
 found in the LICENSE file.
 -->
 
-<ViewSwitcher
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/upgrade_promo_portrait"
     android:background="@macro/default_bg_color"
@@ -18,4 +18,4 @@
     <include
         android:id="@+id/history_sync"
         layout="@layout/history_sync_portrait_view"/>
-</ViewSwitcher>
\ No newline at end of file
+</FrameLayout>
\ No newline at end of file
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/UpgradePromoCoordinator.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/UpgradePromoCoordinator.java
index e29226a0..0eacfc5 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/UpgradePromoCoordinator.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/UpgradePromoCoordinator.java
@@ -8,7 +8,9 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.view.LayoutInflater;
-import android.widget.ViewSwitcher;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
 
 import androidx.annotation.IntDef;
 
@@ -19,12 +21,15 @@
 import org.chromium.chrome.browser.profiles.ProfileProvider;
 import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
 import org.chromium.chrome.browser.signin.services.SigninManager;
+import org.chromium.chrome.browser.signin.services.SigninMetricsUtils;
 import org.chromium.chrome.browser.ui.signin.fullscreen_signin.FullscreenSigninCoordinator;
 import org.chromium.chrome.browser.ui.signin.fullscreen_signin.FullscreenSigninView;
 import org.chromium.chrome.browser.ui.signin.history_sync.HistorySyncCoordinator;
 import org.chromium.chrome.browser.ui.signin.history_sync.HistorySyncHelper;
+import org.chromium.components.browser_ui.styles.SemanticColorUtils;
 import org.chromium.components.signin.identitymanager.ConsentLevel;
 import org.chromium.components.signin.identitymanager.IdentityManager;
+import org.chromium.components.signin.metrics.AccountConsistencyPromoAction;
 import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.components.signin.metrics.SignoutReason;
 import org.chromium.ui.modaldialog.ModalDialogManager;
@@ -64,11 +69,11 @@
      * views in upgrade_promo_portrait/landscape_view.xml
      */
     @IntDef({
-        ViewSwitcherChild.SIGNIN,
-        ViewSwitcherChild.HISTORY_SYNC,
+        ChildView.SIGNIN,
+        ChildView.HISTORY_SYNC,
     })
     @Retention(RetentionPolicy.SOURCE)
-    private @interface ViewSwitcherChild {
+    private @interface ChildView {
         /** The fullscreen sign-in UI. */
         int SIGNIN = 0;
 
@@ -82,7 +87,10 @@
     private final PrivacyPreferencesManager mPrivacyPreferencesManager;
     private final Delegate mDelegate;
     private final boolean mDidShowSignin;
-    private ViewSwitcher mViewSwitcher;
+    private @ChildView int mCurrentView;
+    private FullscreenSigninView mFullscreenSigninView;
+    private View mHistorySyncView;
+    private FrameLayout mViewHolder;
     private FullscreenSigninCoordinator mSigninCoordinator;
     private HistorySyncCoordinator mHistorySyncCoordinator;
 
@@ -93,26 +101,36 @@
             PrivacyPreferencesManager privacyPreferencesManager,
             Delegate delegate) {
         mContext = context;
-        mViewSwitcher = new ViewSwitcher(context);
+        mCurrentView = ChildView.SIGNIN;
+        mViewHolder = new FrameLayout(context);
+        mViewHolder.setBackgroundColor(SemanticColorUtils.getDefaultBgColor(mContext));
         mModalDialogManager = modalDialogManager;
         mProfileSupplier = profileSupplier;
         mPrivacyPreferencesManager = privacyPreferencesManager;
         mDelegate = delegate;
-        inflateViewSwitcher();
+        inflateViewBundle();
         if (isSignedIn()) {
             advanceToNextPage();
             mDidShowSignin = false;
         } else {
             mSigninCoordinator =
                     new FullscreenSigninCoordinator(
-                            mContext, mModalDialogManager, this, mPrivacyPreferencesManager);
-            mSigninCoordinator.setView((FullscreenSigninView) mViewSwitcher.getCurrentView());
+                            mContext,
+                            mModalDialogManager,
+                            this,
+                            mPrivacyPreferencesManager,
+                            SigninAccessPoint.SIGNIN_PROMO);
+            mViewHolder.addView(getCurrentChildView());
+            mSigninCoordinator.setView((FullscreenSigninView) getCurrentChildView());
+            // TODO(crbug.com/347657449): Record other AccountConsistencyPromoActions.
+            SigninMetricsUtils.logAccountConsistencyPromoAction(
+                    AccountConsistencyPromoAction.SHOWN, SigninAccessPoint.SIGNIN_PROMO);
             mDidShowSignin = true;
         }
     }
 
     public void destroy() {
-        mViewSwitcher.removeAllViews();
+        mViewHolder.removeAllViews();
         if (mSigninCoordinator != null) {
             mSigninCoordinator.destroy();
             mSigninCoordinator = null;
@@ -124,8 +142,8 @@
         }
     }
 
-    public ViewSwitcher getViewSwitcher() {
-        return mViewSwitcher;
+    public View getView() {
+        return mViewHolder;
     }
 
     /** Implements {@link FullscreenSigninCoordinator.Delegate} */
@@ -141,7 +159,7 @@
     /** Implements {@link FullscreenSigninCoordinator.Delegate} */
     @Override
     public void advanceToNextPage() {
-        if (!isSignedIn() || mViewSwitcher.getDisplayedChild() == ViewSwitcherChild.HISTORY_SYNC) {
+        if (!isSignedIn() || mCurrentView == ChildView.HISTORY_SYNC) {
             mDelegate.onFlowComplete();
             return;
         }
@@ -152,20 +170,7 @@
             mDelegate.onFlowComplete();
             return;
         }
-        mViewSwitcher.setDisplayedChild(ViewSwitcherChild.HISTORY_SYNC);
-        mHistorySyncCoordinator =
-                new HistorySyncCoordinator(
-                        mContext,
-                        this,
-                        profile,
-                        SigninAccessPoint.SIGNIN_PROMO,
-                        /* showEmailInFooter= */ !mDidShowSignin,
-                        /* shouldSignOutOnDecline= */ false,
-                        mViewSwitcher.getCurrentView());
-        if (mSigninCoordinator != null) {
-            mSigninCoordinator.destroy();
-            mSigninCoordinator = null;
-        }
+        showChildView(ChildView.HISTORY_SYNC);
     }
 
     @Override
@@ -233,9 +238,11 @@
     /** Implements {@link HistorySyncDelegate} */
     @Override
     public void dismissHistorySync() {
-        mViewSwitcher.removeAllViews();
-        mHistorySyncCoordinator.destroy();
-        mHistorySyncCoordinator = null;
+        mViewHolder.removeAllViews();
+        if (mHistorySyncCoordinator != null) {
+            mHistorySyncCoordinator.destroy();
+            mHistorySyncCoordinator = null;
+        }
         mDelegate.onFlowComplete();
     }
 
@@ -251,15 +258,9 @@
      * after a configuration change.
      */
     public void recreateLayoutAfterConfigurationChange() {
-        mViewSwitcher.removeAllViews();
-        mViewSwitcher = null;
-        inflateViewSwitcher();
-        if (mSigninCoordinator != null) {
-            mViewSwitcher.setDisplayedChild(ViewSwitcherChild.SIGNIN);
-            mSigninCoordinator.setView((FullscreenSigninView) mViewSwitcher.getCurrentView());
-            return;
-        }
-        advanceToNextPage();
+        mViewHolder.removeAllViews();
+        inflateViewBundle();
+        showChildView(mCurrentView);
     }
 
     public void onAccountSelected(String accountName) {
@@ -267,9 +268,8 @@
     }
 
     public void handleBackPress() {
-        @ViewSwitcherChild int currentlyDisplayedChild = mViewSwitcher.getDisplayedChild();
-        switch (currentlyDisplayedChild) {
-            case ViewSwitcherChild.SIGNIN:
+        switch (mCurrentView) {
+            case ChildView.SIGNIN:
                 if (isSignedIn()) {
                     SigninManager signinManager =
                             IdentityServicesProvider.get()
@@ -278,34 +278,34 @@
                 }
                 mDelegate.onFlowComplete();
                 break;
-            case ViewSwitcherChild.HISTORY_SYNC:
+            case ChildView.HISTORY_SYNC:
                 if (!mDidShowSignin) {
                     mDelegate.onFlowComplete();
                     return;
                 }
-                mViewSwitcher.setDisplayedChild(ViewSwitcherChild.SIGNIN);
-                mSigninCoordinator =
-                        new FullscreenSigninCoordinator(
-                                mContext, mModalDialogManager, this, mPrivacyPreferencesManager);
-                mSigninCoordinator.setView((FullscreenSigninView) mViewSwitcher.getCurrentView());
+                showChildView(ChildView.SIGNIN);
                 mSigninCoordinator.reset();
-                return;
         }
     }
 
-    private void inflateViewSwitcher() {
+    private void inflateViewBundle() {
         Configuration configuration = mContext.getResources().getConfiguration();
         boolean useLandscapeLayout =
                 configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
                         && !isLargeScreen();
-        mViewSwitcher =
-                (ViewSwitcher)
+        ViewGroup viewBundle =
+                (ViewGroup)
                         LayoutInflater.from(mContext)
                                 .inflate(
                                         useLandscapeLayout
                                                 ? R.layout.upgrade_promo_landscape_view
                                                 : R.layout.upgrade_promo_portrait_view,
                                         null);
+        mFullscreenSigninView = viewBundle.findViewById(R.id.fullscreen_signin);
+        mHistorySyncView = viewBundle.findViewById(R.id.history_sync);
+        mViewHolder.setId(viewBundle.getId());
+        // Remove all child views from the bundle so that they can be added to mViewHolder later.
+        viewBundle.removeAllViews();
     }
 
     private boolean isSignedIn() {
@@ -314,4 +314,49 @@
                         .getIdentityManager(mProfileSupplier.get().getOriginalProfile());
         return identityManager.hasPrimaryAccount(ConsentLevel.SIGNIN);
     }
+
+    private void showChildView(@ChildView int child) {
+        mCurrentView = child;
+        mViewHolder.removeAllViews();
+        mViewHolder.addView(getCurrentChildView());
+        switch (child) {
+            case ChildView.SIGNIN:
+                mSigninCoordinator =
+                        new FullscreenSigninCoordinator(
+                                mContext,
+                                mModalDialogManager,
+                                this,
+                                mPrivacyPreferencesManager,
+                                SigninAccessPoint.SIGNIN_PROMO);
+                mSigninCoordinator.setView((FullscreenSigninView) getCurrentChildView());
+                if (mHistorySyncCoordinator != null) {
+                    mHistorySyncCoordinator.destroy();
+                    mHistorySyncCoordinator = null;
+                }
+                break;
+            case ChildView.HISTORY_SYNC:
+                mHistorySyncCoordinator =
+                        new HistorySyncCoordinator(
+                                mContext,
+                                this,
+                                mProfileSupplier.get().getOriginalProfile(),
+                                SigninAccessPoint.SIGNIN_PROMO,
+                                /* showEmailInFooter= */ !mDidShowSignin,
+                                /* shouldSignOutOnDecline= */ false,
+                                getCurrentChildView());
+                if (mSigninCoordinator != null) {
+                    mSigninCoordinator.destroy();
+                    mSigninCoordinator = null;
+                }
+                break;
+        }
+    }
+
+    private View getCurrentChildView() {
+        return switch (mCurrentView) {
+            case ChildView.SIGNIN -> mFullscreenSigninView;
+            case ChildView.HISTORY_SYNC -> mHistorySyncView;
+            default -> throw new IllegalStateException(mCurrentView + " view index doesn't exist");
+        };
+    }
 }
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fullscreen_signin/FullscreenSigninCoordinator.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fullscreen_signin/FullscreenSigninCoordinator.java
index b0c3d4a..f759b4f 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fullscreen_signin/FullscreenSigninCoordinator.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fullscreen_signin/FullscreenSigninCoordinator.java
@@ -16,6 +16,7 @@
 import org.chromium.chrome.browser.firstrun.MobileFreProgress;
 import org.chromium.chrome.browser.privacy.settings.PrivacyPreferencesManager;
 import org.chromium.chrome.browser.profiles.ProfileProvider;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
 import org.chromium.ui.modaldialog.ModalDialogManager;
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
@@ -114,10 +115,15 @@
             Context context,
             ModalDialogManager modalDialogManager,
             Delegate delegate,
-            PrivacyPreferencesManager privacyPreferencesManager) {
+            PrivacyPreferencesManager privacyPreferencesManager,
+            @SigninAccessPoint int accessPoint) {
         mMediator =
                 new FullscreenSigninMediator(
-                        context, modalDialogManager, delegate, privacyPreferencesManager);
+                        context,
+                        modalDialogManager,
+                        delegate,
+                        privacyPreferencesManager,
+                        accessPoint);
     }
 
     /** Releases the resources used by the coordinator. */
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fullscreen_signin/FullscreenSigninMediator.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fullscreen_signin/FullscreenSigninMediator.java
index 117adf5..ace7be5 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fullscreen_signin/FullscreenSigninMediator.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fullscreen_signin/FullscreenSigninMediator.java
@@ -25,6 +25,7 @@
 import org.chromium.chrome.browser.signin.services.SigninManager;
 import org.chromium.chrome.browser.signin.services.SigninManager.SignInCallback;
 import org.chromium.chrome.browser.signin.services.SigninManager.SignOutCallback;
+import org.chromium.chrome.browser.signin.services.SigninMetricsUtils;
 import org.chromium.chrome.browser.signin.services.SigninPreferencesManager;
 import org.chromium.chrome.browser.sync.SyncServiceFactory;
 import org.chromium.chrome.browser.ui.signin.R;
@@ -87,6 +88,7 @@
     private final AccountManagerFacade mAccountManagerFacade;
     private final Delegate mDelegate;
     private final PrivacyPreferencesManager mPrivacyPreferencesManager;
+    private final @SigninAccessPoint int mAccessPoint;
     private final PropertyModel mModel;
     private final ProfileDataCache mProfileDataCache;
     private boolean mDestroyed;
@@ -107,11 +109,13 @@
             Context context,
             ModalDialogManager modalDialogManager,
             Delegate delegate,
-            PrivacyPreferencesManager privacyPreferencesManager) {
+            PrivacyPreferencesManager privacyPreferencesManager,
+            @SigninAccessPoint int accessPoint) {
         mContext = context;
         mModalDialogManager = modalDialogManager;
         mDelegate = delegate;
         mPrivacyPreferencesManager = privacyPreferencesManager;
+        mAccessPoint = accessPoint;
         mProfileDataCache = ProfileDataCache.createWithDefaultImageSizeAndNoBadge(mContext);
         mModel =
                 FullscreenSigninProperties.createModel(
@@ -141,6 +145,7 @@
         updateAccounts(
                 AccountUtils.getCoreAccountInfosIfFulfilledOrEmpty(
                         mAccountManagerFacade.getCoreAccountInfos()));
+        SigninMetricsUtils.logSigninStartAccessPoint(mAccessPoint);
     }
 
     PropertyModel getModel() {
@@ -397,7 +402,7 @@
             final @SigninAccessPoint int accessPoint =
                     mModel.get(FullscreenSigninProperties.IS_SELECTED_ACCOUNT_SUPERVISED)
                             ? SigninAccessPoint.FORCED_SIGNIN
-                            : SigninAccessPoint.START_PAGE;
+                            : mAccessPoint;
             SigninUtils.checkAccountManagementAndSignIn(
                     selectedAccount,
                     signinManager,
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/history_sync/HistorySyncCoordinator.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/history_sync/HistorySyncCoordinator.java
index be0e6097..1f77f30 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/history_sync/HistorySyncCoordinator.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/history_sync/HistorySyncCoordinator.java
@@ -29,7 +29,6 @@
     }
 
     private final HistorySyncMediator mMediator;
-    private final HistorySyncDelegate mDelegate;
     private final boolean mUseLandscapeLayout;
     private HistorySyncView mView;
     private PropertyModelChangeProcessor mPropertyModelChangeProcessor;
@@ -56,7 +55,6 @@
             boolean showEmailInFooter,
             boolean shouldSignOutOnDecline,
             @Nullable View view) {
-        mDelegate = delegate;
         LayoutInflater inflater = LayoutInflater.from(context);
         mUseLandscapeLayout =
                 !delegate.isLargeScreen()
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb
index 45988bc..dfa923b2 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb
@@ -117,6 +117,8 @@
 <translation id="1513814250881909472">Կատարեք համաժամացում, որպեսզի ձեր մյուս սարքերի ներդիրները հասանելի դառնան։</translation>
 <translation id="1513858653616922153">Ջնջել գաղտնաբառը</translation>
 <translation id="1521774566618522728">Այսօր ակտիվ է եղել</translation>
+<translation id="1544084554881119930">Վճարման եղանակները և հասցեները չեն գաղտնագրվի։ Chrome-ի այցելությունների պատմությունը չի համաժամացվի։
+Միայն ձեր անցաբառն ունեցող մարդիկ կարող են կարդալ ձեր գաղտնագրված տվյալները։ Անցաբառը չի ուղարկվում Google-ին կամ պահվում նրա կողմից։ Եթե մոռացել եք ձեր անցաբառը կամ ուզում եք փոխել այս կարգավորումը, <ph name="BEGIN_LINK" />մաքրեք Chrome-ի տվյալները ձեր հաշվում<ph name="END_LINK" />։</translation>
 <translation id="1544826120773021464">Google հաշիվը կառավարելու համար հպեք «Կառավարել հաշիվը» կոճակին</translation>
 <translation id="154513667535157406">«Լավն է» կոճակի սեղմումը դրական կարծիք է ուղարկում այս ամփոփագրի մասին</translation>
 <translation id="1549000191223877751">Տեղափոխել այլ պատուհան</translation>
@@ -457,6 +459,7 @@
 <translation id="3264259168916048410">Ձեր համակարգիչն ուզում է օգտագործել այս սարքը՝ կայքում մուտք գործելու համար</translation>
 <translation id="3265093782546847662"><ph name="DOMAIN" /> տիրույթի բոլոր էջերը</translation>
 <translation id="3269093882174072735">Բեռնել պատկերը</translation>
+<translation id="327204079441056603">Մենք փոխել ենք այս սարքում գաղտնաբառերի պահման եղանակը</translation>
 <translation id="3280562213547448728">Ձայնային որոնում</translation>
 <translation id="3282568296779691940">Մուտք գործել Chrome</translation>
 <translation id="3290249595466894471">Նաև ուղարկում է էջերի, ներբեռնված ֆայլերի, ընդլայնումների գործողությունների և համակարգի մասին տեղեկություններից որոշ հատվածներ, որոնք օգնում են հայտնաբերել օգտատերերին սպառնացող նոր վտանգներ։</translation>
@@ -1213,6 +1216,7 @@
 <translation id="6918398787259831832">Եթե խնդիրը չվերանա, <ph name="BEGIN_LINK" />ստացեք լրացուցիչ տեղեկություններ<ph name="END_LINK" /> <ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE" />-ից։</translation>
 <translation id="6929224077895306814">Անվտանգության բոլոր կոդերը, որոնք պահված են ձեր սարքում և Google հաշվում, կջնջվեն</translation>
 <translation id="6937524809504266803">Անհատականացում և կապում</translation>
+<translation id="6937876069006524083">Կեղծանուն (պարտադիր չէ)</translation>
 <translation id="6942665639005891494">Դուք ցանկացած ժամանակ կարող եք փոխել ներբեռնումների կանխադրված պանակը կարգավորումներում</translation>
 <translation id="694267552845942083">Այս պահին դուք համաժամացման կարգավորումների էջում եք։ Համաժամացումը միացնելու համար սեղմեք «Հաստատել» կոճակը էկրանի ներքևի հատվածում: Անցնել վերև</translation>
 <translation id="6945221475159498467">Ընտրել</translation>
@@ -1276,6 +1280,7 @@
 <translation id="7207760545532569765">Վերականգնել <ph name="TAB_COUNT" /> ներդիրները որպես նոր ֆոնային ներդիրներ։</translation>
 <translation id="7217781228893594884">Ինկոգնիտո ներդիրները կկողպվեն, երբ դուք փակեք Chrome-ը</translation>
 <translation id="7221869452894271364">Վերաբեռնել այս էջը</translation>
+<translation id="7224097611345298931">Բոլոր գաղտնաբառերը, որոնք պահված են միայն այս սարքում Chrome-ի և <ph name="CHROME_CHANNEL" />-ի համար, միավորվել են։ Դուք կարող եք ինքնալրացնել ձեր բոլոր պահված գաղտնաբառերը երկու հավելվածներում։</translation>
 <translation id="7227218174981371415">{FILE_COUNT,plural, =1{Կնեռբեռնվի 1 ֆայլ}one{Կներբեռնվի # ֆայլ}other{Կներբեռնվի # ֆայլ}}</translation>
 <translation id="72415438529550637">Գաղտնաբառի առաջարկը փակված է։</translation>
 <translation id="7252076891734325316">Հեռախոսը դրեք համակարգչի մոտ</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb
index 559f070..addacc7 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb
@@ -915,6 +915,7 @@
 <translation id="5596627076506792578">אפשרויות נוספות</translation>
 <translation id="5599455543593328020">מצב אנונימי</translation>
 <translation id="5601180634394228718">‏כדי לראות אילו הגדרות נוספות מתבססות על נתונים לצורך שיפור חוויית השימוש ב-Chrome, אפשר לעבור אל <ph name="BEGIN_LINK" />שירותי Google<ph name="END_LINK" />.</translation>
+<translation id="5614625640221885312">לאחר הכניסה לחשבון, הסימניות, הסיסמאות ונתונים נוספים יופיעו בכל המכשירים שלך</translation>
 <translation id="5620163320393916465">אין סיסמאות שמורות</translation>
 <translation id="5620928963363755975">איתור הקבצים והדפים שלך ב'הורדות' דרך הלחצן 'אפשרויות נוספות'</translation>
 <translation id="562289928968387744">ניהול התגובות</translation>
@@ -956,6 +957,7 @@
 <translation id="5793665092639000975"><ph name="SPACE_USED" /> מתוך <ph name="SPACE_AVAILABLE" /> נמצאים בשימוש</translation>
 <translation id="5795872532621730126">חיפוש וגלישה</translation>
 <translation id="5797949256525811424">הנושא חסום</translation>
+<translation id="580893287573699959">ניהול הנושאים והאתרים שמעניינים אותך</translation>
 <translation id="5809361687334836369">{HOURS,plural, =1{לפני שעה}one{לפני # שעות}two{לפני שעתיים}other{לפני # שעות}}</translation>
 <translation id="5810288467834065221">‏Copyright <ph name="YEAR" /> Google LLC.‎ כל הזכויות שמורות.</translation>
 <translation id="5814749351757353073">עוקבים אחר אתרים שאוהבים</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mr.xtb
index f027093..b9ff93e 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mr.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mr.xtb
@@ -117,6 +117,8 @@
 <translation id="1513814250881909472">तुमच्या इतर डिव्हाइसवरून तुमचे टॅब मिळवण्यासाठी सिंक करा</translation>
 <translation id="1513858653616922153">पासवर्ड हटवा</translation>
 <translation id="1521774566618522728">आज ॲक्टिव्ह होते</translation>
+<translation id="1544084554881119930">पेमेंट पद्धती आणि पत्ते एन्क्रिप्ट केले जाणार नाहीत. Chrome वरील ब्राउझिंग इतिहास सिंक होणार नाही.
+फक्त तुमचा पासफ्रेझ असलेली कोणतीही व्यक्ती तुमचा एन्क्रिप्ट केलेला डेटा वाचू शकते. पासफ्रेझ Google कडे पाठवला किंवा त्याद्वारे स्टोअर केलेला नाही. तुम्ही तुमचा पासफ्रेझ विसरल्यास किंवा हे सेटिंग बदलायचे असल्यास, <ph name="BEGIN_LINK" />तुमच्या खात्यामधील Chrome डेटा साफ करणे<ph name="END_LINK" /> हे करा.</translation>
 <translation id="1544826120773021464">तुमचे Google खाते व्यवस्थापित करण्यासाठी, "खाते व्यवस्थापित करा" बटणावर टॅप करा</translation>
 <translation id="154513667535157406">थंब्स अपवर क्लिक केल्यावर तुम्हाला हा सारांश आवडला आहे असा फीडबॅक सबमिट केला जातो</translation>
 <translation id="1549000191223877751">अन्य विंडोवर हलवा</translation>
@@ -457,6 +459,7 @@
 <translation id="3264259168916048410">साइटवर साइन इन करण्यासाठी तुमच्या कॉंप्युटरला हे डिव्हाइस वापरायचे आहे</translation>
 <translation id="3265093782546847662"><ph name="DOMAIN" /> ची सर्व पेज</translation>
 <translation id="3269093882174072735">इमेज लोड करा</translation>
+<translation id="327204079441056603">या डिव्हाइसवर पासवर्ड कसे सेव्ह केले जातात ते आम्ही बदलले आहे</translation>
 <translation id="3280562213547448728">व्हॉइस शोध</translation>
 <translation id="3282568296779691940">Chrome वर साइन इन करा</translation>
 <translation id="3290249595466894471">तसेच नवीन धोके शोधण्यात मदत करण्यासाठी पेज, डाउनलोड, एक्स्टेंशन अ‍ॅक्टिव्हिटी आणि सिस्टीम माहिती यांचे लहान नमुने पाठवते</translation>
@@ -1213,6 +1216,7 @@
 <translation id="6918398787259831832">ही समस्या येत राहिल्यास, <ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE" /> कडून <ph name="BEGIN_LINK" />अधिक माहिती मिळवा<ph name="END_LINK" />.</translation>
 <translation id="6929224077895306814">तुमच्या डिव्हाइसवर आणि तुमच्या Google खाते मध्ये सेव्ह केलेले सर्व सुरक्षा कोड हटवले जातील</translation>
 <translation id="6937524809504266803">पर्सनलायझेशन आणि लिंक करणे</translation>
+<translation id="6937876069006524083">टोपणनाव (पर्यायी)</translation>
 <translation id="6942665639005891494">सेटिंग्ज मेनू पर्याय वापरून केव्हाही डीफॉल्ट डाउनलोड स्थान बदला</translation>
 <translation id="694267552845942083">तुम्ही सध्या तुमची सिंक सेटिंग्ज कस्टमाइझ करत आहात. सिंक सुरू करणे पूर्ण करण्यासाठी, स्क्रीनच्या तळाशी असलेल्या कन्फर्म करा बटणावर टॅप करा. वर नेव्‍हिगेट करा</translation>
 <translation id="6945221475159498467">निवडा</translation>
@@ -1276,6 +1280,7 @@
 <translation id="7207760545532569765">नवीन बॅकग्राउंड टॅब गट म्हणून <ph name="TAB_COUNT" /> टॅब रिस्टोअर करा.</translation>
 <translation id="7217781228893594884">तुम्ही Chrome मधून बाहेर पडता, तेव्हा गुप्त टॅब लॉक केले जातील</translation>
 <translation id="7221869452894271364">हे पेज रीलोड करा</translation>
+<translation id="7224097611345298931">या डिव्हाइसवर Chrome आणि <ph name="CHROME_CHANNEL" /> यांसाठी सेव्ह केलेले पासवर्ड हे मर्ज केले गेले आहेत. तुम्ही तुमचे सेव्ह केलेले पासवर्ड दोन्ही अ‍ॅप्सवर ऑटोफिल करू शकता.</translation>
 <translation id="7227218174981371415">{FILE_COUNT,plural, =1{एक डाउनलोड बाकी आहे}other{# डाउनलोड बाकी आहेत}}</translation>
 <translation id="72415438529550637">पासवर्डसंबंधित सूचना बंद आहे.</translation>
 <translation id="7252076891734325316">तुमचा फोन कॉंप्युटरच्या जवळ ठेवा</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb
index 8bf76e1..3dfbe6a 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb
@@ -117,6 +117,8 @@
 <translation id="1513814250881909472">Segerakkan untuk mendapatkan tab anda daripada peranti anda yang lain</translation>
 <translation id="1513858653616922153">Padam kata laluan</translation>
 <translation id="1521774566618522728">Aktif hari ini</translation>
+<translation id="1544084554881119930">Kaedah pembayaran dan alamat tidak akan disulitkan. Sejarah penyemakan imbas daripada Chrome tidak akan disegerakkan.
+Orang yang mengetahui ungkapan laluan anda sahaja yang dapat membaca data anda yang disulitkan. Ungkapan laluan tidak dihantar kepada atau disimpan oleh Google. Jika anda terlupa ungkapan laluan anda atau mahu menukar tetapan ini, <ph name="BEGIN_LINK" />kosongkan data Chrome dalam akaun anda<ph name="END_LINK" />.</translation>
 <translation id="1544826120773021464">Untuk mengurus Google Account anda, ketik butang "Urus akaun"</translation>
 <translation id="154513667535157406">Isyarat menyukai menyerahkan maklum balas yang menunjukkan bahawa anda menyukai ringkasan ini</translation>
 <translation id="1549000191223877751">Alihkan ke tetingkap lain</translation>
@@ -457,6 +459,7 @@
 <translation id="3264259168916048410">Komputer anda mahu menggunakan peranti ini untuk log masuk ke laman</translation>
 <translation id="3265093782546847662">Semua halaman <ph name="DOMAIN" /></translation>
 <translation id="3269093882174072735">Muatkan imej</translation>
+<translation id="327204079441056603">Kami telah menukar cara kata laluan disimpan pada peranti ini</translation>
 <translation id="3280562213547448728">Carian suara</translation>
 <translation id="3282568296779691940">Log masuk ke Chrome</translation>
 <translation id="3290249595466894471">Turut menghantar sedikit sampel halaman, muat turun, aktiviti sambungan dan maklumat sistem untuk membantu penemuan ancaman baharu</translation>
@@ -1213,6 +1216,7 @@
 <translation id="6918398787259831832">Jika masalah ini tetap berlaku, <ph name="BEGIN_LINK" />dapatkan lebih banyak maklumat<ph name="END_LINK" /> daripada <ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE" />.</translation>
 <translation id="6929224077895306814">Semua kod keselamatan yang disimpan pada peranti anda dan dalam Google Account akan dipadamkan</translation>
 <translation id="6937524809504266803">Pemeribadian &amp; Pemautan</translation>
+<translation id="6937876069006524083">Nama panggilan (pilihan)</translation>
 <translation id="6942665639005891494">Tukar lokasi muat turun lalai pada bila-bila masa menggunakan pilihan menu Tetapan</translation>
 <translation id="694267552845942083">Anda sedang menyesuaikan tetapan Penyegerakan anda. Untuk menyelesaikan tindakan menghidupkan penyegerakan, ketik butang Sahkan berdekatan bahagian bawah skrin. Navigasi ke atas</translation>
 <translation id="6945221475159498467">Pilih</translation>
@@ -1276,6 +1280,7 @@
 <translation id="7207760545532569765">Pulihkan <ph name="TAB_COUNT" /> tab sebagai tab latar baharu.</translation>
 <translation id="7217781228893594884">Tab inkognito akan dikunci apabila anda meninggalkan Chrome</translation>
 <translation id="7221869452894271364">Muatkan semula halaman ini</translation>
+<translation id="7224097611345298931">Semua kata laluan yang disimpan hanya pada peranti ini untuk Chrome dan <ph name="CHROME_CHANNEL" /> telah digabungkan. Anda dapat membuat autolengkap semua kata laluan anda yang disimpan pada kedua-dua apl.</translation>
 <translation id="7227218174981371415">{FILE_COUNT,plural, =1{1 muat turun belum selesai}other{# muat turun belum selesai}}</translation>
 <translation id="72415438529550637">Cadangan kata laluan telah ditutup.</translation>
 <translation id="7252076891734325316">Letakkan telefon anda dekat dengan komputer</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb
index 4ffa73e2..8e6c41f 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb
@@ -117,6 +117,8 @@
 <translation id="1513814250881909472">Voer een synchronisatie uit om de tabbladen van je andere apparaten op te halen</translation>
 <translation id="1513858653616922153">Wachtwoord verwijderen</translation>
 <translation id="1521774566618522728">Vandaag actief</translation>
+<translation id="1544084554881119930">Betaalmethoden en adressen worden niet versleuteld. De browsegeschiedenis in Chrome wordt niet gesynchroniseerd.
+Alleen iemand met je wachtwoordzin kan je versleutelde gegevens lezen. De wachtwoordzin wordt niet gestuurd naar of opgeslagen door Google. Als je je wachtwoordzin vergeet of deze instelling wilt wijzigen, <ph name="BEGIN_LINK" />wis je de Chrome-gegevens in je account<ph name="END_LINK" />.</translation>
 <translation id="1544826120773021464">Tik op de knop 'Account beheren' om je Google-account te beheren</translation>
 <translation id="154513667535157406">Met Leuk stuur je feedback dat je dit overzicht leuk vindt.</translation>
 <translation id="1549000191223877751">Naar ander venster</translation>
@@ -457,6 +459,7 @@
 <translation id="3264259168916048410">Je computer wil dit apparaat gebruiken om in te loggen op een site</translation>
 <translation id="3265093782546847662">Alle pagina's van <ph name="DOMAIN" /></translation>
 <translation id="3269093882174072735">Afbeelding laden</translation>
+<translation id="327204079441056603">We hebben de manier gewijzigd waarop wachtwoorden op dit apparaat worden opgeslagen</translation>
 <translation id="3280562213547448728">Gesproken zoekopdracht</translation>
 <translation id="3282568296779691940">Inloggen bij Chrome</translation>
 <translation id="3290249595466894471">Stuurt ook een klein gedeelte pagina's, downloads, extensie-activiteit en systeeminformatie om nieuwe dreigingen te kunnen vinden</translation>
@@ -1213,6 +1216,7 @@
 <translation id="6918398787259831832">Als dit probleem zich blijft voordoen, kun je <ph name="BEGIN_LINK" />meer informatie krijgen<ph name="END_LINK" /> van <ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE" />.</translation>
 <translation id="6929224077895306814">Alle beveiligingscodes die zijn opgeslagen op je apparaat en in je Google-account, worden verwijderd</translation>
 <translation id="6937524809504266803">Personalisatie en koppelen</translation>
+<translation id="6937876069006524083">Bijnaam (optioneel)</translation>
 <translation id="6942665639005891494">Je kunt via de menuoptie Instellingen op elk gewenst moment de standaard downloadlocatie wijzigen</translation>
 <translation id="694267552845942083">Je past momenteel je synchronisatie-instellingen aan. Als je synchronisatie wilt aanzetten, tik je onderaan het scherm op Bevestigen. Omhoog navigeren</translation>
 <translation id="6945221475159498467">Selecteren</translation>
@@ -1276,6 +1280,7 @@
 <translation id="7207760545532569765"><ph name="TAB_COUNT" /> tabbladen herstellen als nieuwe tabbladen op de achtergrond.</translation>
 <translation id="7217781228893594884">Incognitotabbladen worden vergrendeld als je Chrome verlaat</translation>
 <translation id="7221869452894271364">Deze pagina opnieuw laden</translation>
+<translation id="7224097611345298931">Alle wachtwoorden die alleen op dit apparaat zijn opgeslagen voor Chrome en <ph name="CHROME_CHANNEL" />, zijn samengevoegd. Je kunt al je opgeslagen wachtwoorden automatisch laten invullen in beide apps.</translation>
 <translation id="7227218174981371415">{FILE_COUNT,plural, =1{1 download in behandeling}other{# downloads in behandeling}}</translation>
 <translation id="72415438529550637">Wachtwoordsuggestie is gesloten.</translation>
 <translation id="7252076891734325316">Houd je telefoon dicht bij de computer</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_uz.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_uz.xtb
index 9fcec887..1f4b4e3 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_uz.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_uz.xtb
@@ -117,6 +117,8 @@
 <translation id="1513814250881909472">Boshqa qurilmalardan varaqlarni olish uchun sinxronlang</translation>
 <translation id="1513858653616922153">Parolni o‘chirish</translation>
 <translation id="1521774566618522728">Bugun onlayn edi</translation>
+<translation id="1544084554881119930">Toʻlov usullari va manzillar shifrlanmaydi. Chrome brauzer tarixi sinxronlanmaydi.
+Shifrlangan maʼlumotlarni faqatgina kodli ibora yordamida oʻqish mumkin. Kodli ibora ulashilmaydi va Google serverlarida saqlanmaydi. Agar kodli iborani unutsangiz yoki bu sozlamani oʻzgartirmoqchi boʻlsangiz, <ph name="BEGIN_LINK" />hisobingizda Chrome maʼlumotlarini tozalang<ph name="END_LINK" />.</translation>
 <translation id="1544826120773021464">Google hisobingizni boshqarish uchun “Hisobni boshqarish” tugmasini bosing</translation>
 <translation id="154513667535157406">Ijobiy baho bosilsa, bu xulosaning sizga yoqqani haqida fikr-mulohaza yuboriladi.</translation>
 <translation id="1549000191223877751">Boshqa oynaga o‘tkazish</translation>
@@ -457,6 +459,7 @@
 <translation id="3264259168916048410">Kompyuteringiz bu qurilmadan saytga kirish uchun foydalanmoqchi</translation>
 <translation id="3265093782546847662"><ph name="DOMAIN" /> barcha sahifalari</translation>
 <translation id="3269093882174072735">Tasvirni yuklash</translation>
+<translation id="327204079441056603">Bu qurilmada parollar qanday saqlanishini oʻzgartirdik</translation>
 <translation id="3280562213547448728">Ovozli qidiruv</translation>
 <translation id="3282568296779691940">Chrome hisobiga kirish</translation>
 <translation id="3290249595466894471">Sahifa, yuklanma, kengaytma harakati va tizim axboroti parchalarini ham yangi tahdidlarni aniqlashga yordam berishi uchun yuboradi</translation>
@@ -1213,6 +1216,7 @@
 <translation id="6918398787259831832">Muammo qayta takrorlansa, <ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE" /> orqali <ph name="BEGIN_LINK" />batafsil axborot oling<ph name="END_LINK" />.</translation>
 <translation id="6929224077895306814">Qurilma va Google hisobingizda saqlangan barcha xavfsizlik kodlari oʻchirib tashlanadi</translation>
 <translation id="6937524809504266803">Moslashtirish va xizmat ulash</translation>
+<translation id="6937876069006524083">Taxallus (ixtiyoriy)</translation>
 <translation id="6942665639005891494">Yuklanmalar standart jildini istalgan vaqtda sozlamalar menyusidan o‘zgartirish mumkin</translation>
 <translation id="694267552845942083">Siz hozirda sinxronizatsiya sozlamalarini sozlayapsiz. Sinxronizatsiyani yoqish uchun ekranning quyi qismidagi Tasdiqlash tugmasini bosing. Tepaga</translation>
 <translation id="6945221475159498467">Tanlash</translation>
@@ -1276,6 +1280,7 @@
 <translation id="7207760545532569765"><ph name="TAB_COUNT" /> ta varaqni fondagi varaqlar sifatida tiklash.</translation>
 <translation id="7217781228893594884">Chrome brauzeridan chiqib ketganingizda Inkognito varaqlar qulflanadi</translation>
 <translation id="7221869452894271364">Bu sahifani yangilash</translation>
+<translation id="7224097611345298931">Chrome va <ph name="CHROME_CHANNEL" /> uchun shu qurilmada saqlangan barcha parollar birlashtirildi. Avtomatik kiritish funksiyasidan foydalangan holda saqlangan parollarni har ikki ilovaga ham kiritish mumkin.</translation>
 <translation id="7227218174981371415">{FILE_COUNT,plural, =1{1 ta fayl yuklab olinishi kutilmoqda...}other{# ta fayl yuklab olinishi kutilmoqda...}}</translation>
 <translation id="72415438529550637">Parol taklifi yopildi.</translation>
 <translation id="7252076891734325316">Telefoningizni kompyuterga yaqin tuting</translation>
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java
index b7a725e..1100ce7d 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java
@@ -341,7 +341,7 @@
                                     StartSurfaceConfiguration.getLogoSizeForLogoPolish());
         } else {
             mFakeSearchBoxOffsetForSurfacePolishLogoInContent =
-                    toolbarPlaceholderHeight + LogoUtils.getLogoTotalHeightPolished(resources);
+                    toolbarPlaceholderHeight + LogoUtils.getLogoTotalHeight(resources);
         }
         mFakeSearchBoxOffsetForSurfacePolishNoLogoInContent =
                 toolbarPlaceholderHeight
diff --git a/chrome/browser/ui/autofill/address_bubbles_controller.h b/chrome/browser/ui/autofill/address_bubbles_controller.h
index f448eb1..845a8fe 100644
--- a/chrome/browser/ui/autofill/address_bubbles_controller.h
+++ b/chrome/browser/ui/autofill/address_bubbles_controller.h
@@ -92,8 +92,8 @@
   friend class content::WebContentsUserData<
       AddressBubblesController>;
 
-  // TODO(b/325440757): Remove `profile` and `original_profile`, put them in
-  // specific bubble controllers.
+  // TODO(crbug.com/325440757): Remove `profile` and `original_profile`, put
+  // them in specific bubble controllers.
   void SetUpAndShowBubble(
       ShowBubbleViewCallback show_bubble_view_callback,
       std::u16string page_action_icon_tootip,
diff --git a/chrome/browser/ui/autofill/autofill_context_menu_manager.cc b/chrome/browser/ui/autofill/autofill_context_menu_manager.cc
index a0c8f28a..ae5a113 100644
--- a/chrome/browser/ui/autofill/autofill_context_menu_manager.cc
+++ b/chrome/browser/ui/autofill/autofill_context_menu_manager.cc
@@ -59,6 +59,10 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/models/menu_model.h"
 
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#include "components/plus_addresses/resources/vector_icons.h"
+#endif
+
 namespace autofill {
 
 using FillingProductSet = DenseSet<FillingProduct>;
@@ -82,7 +86,7 @@
 
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
 const gfx::VectorIcon& kPlusAddressLogoIcon =
-    vector_icons::kPlusAddressLogoSmallIcon;
+    plus_addresses::kPlusAddressLogoSmallIcon;
 #else
 const gfx::VectorIcon& kPlusAddressLogoIcon = vector_icons::kEmailIcon;
 #endif
@@ -429,7 +433,7 @@
 
   const bool select_passwords_option_shown =
       add_passwords_fallback && UserHasPasswordsSaved(*password_manager_driver);
-  // TODO(b/327566698): Log metrics for plus address fallbacks, too.
+  // TODO(crbug.com/327566698): Log metrics for plus address fallbacks, too.
   LogManualFallbackContextMenuEntryShown(
       autofill_driver, password_manager_driver, add_address_fallback,
       add_payments_fallback, select_passwords_option_shown);
@@ -518,7 +522,7 @@
       password_manager_util::ManualPasswordGenerationEnabled(
           &password_manager_driver);
 
-  // TODO(b/321678141): Update strings once we have UX decision.
+  // TODO(crbug.com/321678141): Update strings once we have UX decision.
   if (UserHasPasswordsSaved(password_manager_driver)) {
     regular_password_entry_command_id =
         IDC_CONTENT_CONTEXT_AUTOFILL_FALLBACK_PASSWORDS_SELECT_PASSWORD;
@@ -645,14 +649,14 @@
           rfh ? ContentPasswordManagerDriver::GetForRenderFrameHost(rfh)
               : nullptr;
 
-      // TODO(b/321678141): Handle the "else" case of this if.
+      // TODO(crbug.com/321678141): Handle the "else" case of this if.
       if (!IsPasswordFormField(password_manager_driver, params_)) {
         manager.GetManualFallbackEventLogger().ContextMenuEntryAccepted(
             filling_product);
       }
       break;
     }
-    // TODO(b/327566698): Add metrics for plus addresses.
+    // TODO(crbug.com/327566698): Add metrics for plus addresses.
     case FillingProduct::kPlusAddresses:
       NOTIMPLEMENTED();
       break;
diff --git a/chrome/browser/ui/autofill/autofill_context_menu_manager_browsertest.cc b/chrome/browser/ui/autofill/autofill_context_menu_manager_browsertest.cc
index 7ead7e1..9abce7d3 100644
--- a/chrome/browser/ui/autofill/autofill_context_menu_manager_browsertest.cc
+++ b/chrome/browser/ui/autofill/autofill_context_menu_manager_browsertest.cc
@@ -1441,7 +1441,7 @@
   static constexpr char kExcludedDomainUrl[] = "https://muh.mah";
 
   PlusAddressContextMenuManagerTest() {
-    // TODO(b/327562692): Create and use a `PlusAddressTestEnvironment`.
+    // TODO(crbug.com/327562692): Create and use a `PlusAddressTestEnvironment`.
     feature_list_.InitWithFeaturesAndParameters(
         /*enabled_features=*/
         {{plus_addresses::features::kPlusAddressesEnabled,
diff --git a/chrome/browser/ui/autofill/autofill_field_promo_controller_impl.cc b/chrome/browser/ui/autofill/autofill_field_promo_controller_impl.cc
index 9332303..27e9fd57 100644
--- a/chrome/browser/ui/autofill/autofill_field_promo_controller_impl.cc
+++ b/chrome/browser/ui/autofill/autofill_field_promo_controller_impl.cc
@@ -39,8 +39,8 @@
   }
 
   AutofillPopupHideHelper::HidingParams hiding_params = {
-      // TODO(b/313587343): Maybe make this true when clicking on the IPH
-      // doesn't trigger anymore the event of web contents losing focus.
+      // TODO(crbug.com/313587343): Maybe make this true when clicking on the
+      // IPH doesn't trigger anymore the event of web contents losing focus.
       .hide_on_web_contents_lost_focus = false};
   AutofillPopupHideHelper::HidingCallback hiding_callback =
       base::BindRepeating([](AutofillFieldPromoControllerImpl& controller,
diff --git a/chrome/browser/ui/autofill/autofill_keyboard_accessory_controller_impl.h b/chrome/browser/ui/autofill/autofill_keyboard_accessory_controller_impl.h
index 1302d8f..708f247 100644
--- a/chrome/browser/ui/autofill/autofill_keyboard_accessory_controller_impl.h
+++ b/chrome/browser/ui/autofill/autofill_keyboard_accessory_controller_impl.h
@@ -60,8 +60,8 @@
   gfx::NativeView container_view() const override;
   content::WebContents* GetWebContents() const override;
   const gfx::RectF& element_bounds() const override;
-  // TODO(b/b/342383222) Re-evaluate whether this method makes sense here.
-  // Today it is only needed on desktop.
+  // TODO(crbug.com/b/342383222) Re-evaluate whether this method makes sense
+  // here. Today it is only needed on desktop.
   PopupAnchorType anchor_type() const override;
 
   base::i18n::TextDirection GetElementTextDirection() const override;
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller.h b/chrome/browser/ui/autofill/autofill_popup_controller.h
index 305e6e8..05e4f550 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller.h
+++ b/chrome/browser/ui/autofill/autofill_popup_controller.h
@@ -88,8 +88,8 @@
   // Handles a key press event and returns whether the event should be swallowed
   // (meaning that no other handler, in particular not the default handler, can
   // process it).
-  // TODO(b/325246516): Change the event type to `ui::KeyEvent` as events can
-  // come not only from blink, but from native UI too.
+  // TODO(crbug.com/325246516): Change the event type to `ui::KeyEvent` as
+  // events can come not only from blink, but from native UI too.
   virtual bool HandleKeyPressEvent(
       const input::NativeWebKeyboardEvent& event) = 0;
 
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
index 672957c..5ac3c6a8 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
@@ -235,7 +235,7 @@
         trigger_source_ ==
                 AutofillSuggestionTriggerSource::kManualFallbackPasswords
             ? std::optional<AutofillPopupView::SearchBarConfig>(
-                  // TODO(b/325246516): Set translated strings from the
+                  // TODO(crbug.com/325246516): Set translated strings from the
                   // greenlines when they get finalized.
                   {.placeholder = u"Search",
                    .no_results_message = u"No passwords found"})
@@ -350,8 +350,9 @@
   }
   key_press_observer_.Reset();
   popup_hide_helper_.reset();
-  // TODO(b/341916065): Consider only emitting this metric if the popup has been opened
-  // before. Today the show method can call `Hide()` before properly opening the popup.
+  // TODO(crbug.com/341916065): Consider only emitting this metric if the popup
+  // has been opened before. Today the show method can call `Hide()` before
+  // properly opening the popup.
   AutofillMetrics::LogAutofillSuggestionHidingReason(
       suggestions_filling_product_, reason);
 
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc
index 168b875e..62d4441 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.cc
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -649,7 +649,7 @@
                                               std::move(callback));
 }
 
-// TODO(b/309163844): Add follow-up ManualFallback for showing IBANs.
+// TODO(crbug.com/309163844): Add follow-up ManualFallback for showing IBANs.
 bool ChromeAutofillClient::ShowTouchToFillCreditCard(
     base::WeakPtr<TouchToFillDelegate> delegate,
     base::span<const autofill::CreditCard> cards_to_suggest,
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h
index ec7fec7..e90f4f1 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.h
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -197,7 +197,7 @@
       FormGlobalId form_id,
       FieldGlobalId field_id) const override;
 
-  // TODO(b/320634151): Create a test API.
+  // TODO(crbug.com/320634151): Create a test API.
   base::WeakPtr<AutofillSuggestionController>
   suggestion_controller_for_testing() {
     return suggestion_controller_;
diff --git a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc
index e87d91d5..ae467cc 100644
--- a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc
+++ b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc
@@ -505,8 +505,8 @@
 
   // If the dialog should be re-shown, do not change the bubble type or log
   // metrics.
-  // TODO(b/316391673): Determine if we should track metrics on the usage of
-  // this member.
+  // TODO(crbug.com/316391673): Determine if we should track metrics on the
+  // usage of this member.
   if (was_url_opened_) {
     return;
   }
diff --git a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h
index eeace193..eba85a9 100644
--- a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h
+++ b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h
@@ -61,7 +61,7 @@
   // `CardSaveType::kCardSaveWithCvc`, the offer-to-save card bubble is shown,
   // and the users are informed that the CVC will also be stored. If the type is
   // `CardSaveType::kCvcSaveOnly`, the offer-to-save CVC bubble is shown.
-  // TODO(b/40937065) refactor: pass Iban by value since all they then
+  // TODO(crbug.com/40937065) refactor: pass Iban by value since all they then
   // immediately move it into a member.
   void OfferLocalSave(
       const CreditCard& card,
diff --git a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc
index c426c5f..6bf4b14 100644
--- a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc
+++ b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc
@@ -957,7 +957,7 @@
   EXPECT_TRUE(controller()->IsIconVisible());
   EXPECT_NE(controller()->GetPaymentBubbleView(), nullptr);
 
-  // TODO(b/309627643): Change the bubble type when the
+  // TODO(crbug.com/309627643): Change the bubble type when the
   // AutofillEnableSaveCardLoadingAndConfirmation feature flag is enabled.
   controller()->OnSaveButton({});
   EXPECT_EQ(controller()->GetBubbleType(), BubbleType::UPLOAD_SAVE);
@@ -1532,8 +1532,8 @@
   // Expect the prompt metric not to change from the initial bubble showing
   // because this is a reshowing after returning to the original tab after a
   // link click.
-  // TODO(b/316391673): Determine if a different metric (or the re-show metric)
-  // should be tracking this re-show.
+  // TODO(crbug.com/316391673): Determine if a different metric (or the re-show
+  // metric) should be tracking this re-show.
   histogram_tester.ExpectUniqueSample(
       "Autofill.SaveCreditCardPromptOffer.Upload.FirstShow",
       autofill_metrics::SaveCardPromptOffer::kShown, 1);
diff --git a/chrome/browser/ui/chromeos/magic_boost/magic_boost_card_controller.cc b/chrome/browser/ui/chromeos/magic_boost/magic_boost_card_controller.cc
index e2a0581..365692f 100644
--- a/chrome/browser/ui/chromeos/magic_boost/magic_boost_card_controller.cc
+++ b/chrome/browser/ui/chromeos/magic_boost/magic_boost_card_controller.cc
@@ -90,6 +90,14 @@
 void MagicBoostCardController::ShowOptInUi(
     const gfx::Rect& anchor_view_bounds) {
   CHECK(!opt_in_widget_);
+
+  // If the disclaimer view is showing, close it.
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  remote_->CloseDisclaimerUi();
+#else   // BUILDFLAG(IS_CHROMEOS_ASH)
+  GetMagicBoostControllerAsh().CloseDisclaimerUi();
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   opt_in_widget_ = MagicBoostOptInCard::CreateWidget(
       /*controller=*/this, anchor_view_bounds, is_orca_included_);
   opt_in_widget_->ShowInactive();
diff --git a/chrome/browser/ui/chromeos/magic_boost/magic_boost_card_controller_unittest.cc b/chrome/browser/ui/chromeos/magic_boost/magic_boost_card_controller_unittest.cc
index 7cddfde..e987e2b 100644
--- a/chrome/browser/ui/chromeos/magic_boost/magic_boost_card_controller_unittest.cc
+++ b/chrome/browser/ui/chromeos/magic_boost/magic_boost_card_controller_unittest.cc
@@ -58,6 +58,7 @@
   EXPECT_FALSE(card_controller_.opt_in_widget_for_test());
 
   // Show the opt-in widget and test that the proper views are set.
+  EXPECT_CALL(crosapi_controller_, CloseDisclaimerUi);
   card_controller_.OnTextAvailable(/*anchor_bounds=*/gfx::Rect(),
                                    /*selected_text=*/"",
                                    /*surrounding_text=*/"");
@@ -77,6 +78,7 @@
 TEST_F(MagicBoostCardControllerTest, BoundsChanged) {
   EXPECT_FALSE(card_controller_.opt_in_widget_for_test());
 
+  EXPECT_CALL(crosapi_controller_, CloseDisclaimerUi);
   gfx::Rect anchor_bounds = gfx::Rect(50, 50, 25, 100);
   card_controller_.OnTextAvailable(anchor_bounds,
                                    /*selected_text=*/"",
@@ -115,4 +117,20 @@
   card_controller_.ShowDisclaimerUi(expected_display_id, expected_action);
 }
 
+TEST_F(MagicBoostCardControllerTest, ShowOptInCardAgain) {
+  // Shows the disclaimer view.
+  EXPECT_CALL(crosapi_controller_, ShowDisclaimerUi);
+  card_controller_.ShowDisclaimerUi(
+      /*display_id=*/1,
+      crosapi::mojom::MagicBoostController::TransitionAction::kShowEditorPanel);
+  EXPECT_FALSE(card_controller_.opt_in_widget_for_test());
+
+  // Shows the opt-in widget. It should close the discalimer view.
+  EXPECT_CALL(crosapi_controller_, CloseDisclaimerUi);
+  card_controller_.OnTextAvailable(/*anchor_bounds=*/gfx::Rect(),
+                                   /*selected_text=*/"",
+                                   /*surrounding_text=*/"");
+  ASSERT_TRUE(card_controller_.opt_in_widget_for_test());
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/ui/chromeos/magic_boost/magic_boost_opt_in_card_unittest.cc b/chrome/browser/ui/chromeos/magic_boost/magic_boost_opt_in_card_unittest.cc
index ab66790..4796775 100644
--- a/chrome/browser/ui/chromeos/magic_boost/magic_boost_opt_in_card_unittest.cc
+++ b/chrome/browser/ui/chromeos/magic_boost/magic_boost_opt_in_card_unittest.cc
@@ -70,6 +70,7 @@
 
 TEST_F(MagicBoostOptInCardTest, PrimaryButtonActions) {
   // Show the opt-in UI card.
+  EXPECT_CALL(crosapi_controller_, CloseDisclaimerUi);
   card_controller_.ShowOptInUi(/*anchor_view_bounds=*/gfx::Rect());
   auto* opt_in_widget = card_controller_.opt_in_widget_for_test();
   ASSERT_TRUE(opt_in_widget);
@@ -87,6 +88,7 @@
 
 TEST_F(MagicBoostOptInCardTest, SecondaryButtonActions) {
   // Show the opt-in UI card.
+  EXPECT_CALL(crosapi_controller_, CloseDisclaimerUi);
   card_controller_.ShowOptInUi(/*anchor_view_bounds=*/gfx::Rect());
   auto* opt_in_widget = card_controller_.opt_in_widget_for_test();
   ASSERT_TRUE(opt_in_widget);
diff --git a/chrome/browser/ui/chromeos/magic_boost/test/mock_magic_boost_controller_crosapi.h b/chrome/browser/ui/chromeos/magic_boost/test/mock_magic_boost_controller_crosapi.h
index 04f19b97..7883c19 100644
--- a/chrome/browser/ui/chromeos/magic_boost/test/mock_magic_boost_controller_crosapi.h
+++ b/chrome/browser/ui/chromeos/magic_boost/test/mock_magic_boost_controller_crosapi.h
@@ -20,6 +20,7 @@
               ShowDisclaimerUi,
               (int64_t, crosapi::mojom::MagicBoostController::TransitionAction),
               (override));
+  MOCK_METHOD(void, CloseDisclaimerUi, (), (override));
 };
 
 }  // namespace chromeos
diff --git a/chrome/browser/ui/chromeos/test_util.cc b/chrome/browser/ui/chromeos/test_util.cc
index 1691f62..82472234 100644
--- a/chrome/browser/ui/chromeos/test_util.cc
+++ b/chrome/browser/ui/chromeos/test_util.cc
@@ -92,7 +92,7 @@
 
 void ChromeOSBrowserUITest::SetUpDefaultCommandLine(
     base::CommandLine* command_line) {
-  InProcessBrowserTest::SetUpDefaultCommandLine(command_line);
+  MixinBasedInProcessBrowserTest::SetUpDefaultCommandLine(command_line);
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   command_line->AppendSwitch(ash::switches::kAshEnableTabletMode);
 #endif
@@ -102,7 +102,7 @@
   if (InTabletMode()) {
     ExitTabletMode();
   }
-  InProcessBrowserTest::TearDownOnMainThread();
+  MixinBasedInProcessBrowserTest::TearDownOnMainThread();
 }
 
 bool ChromeOSBrowserUITest::InTabletMode() {
diff --git a/chrome/browser/ui/chromeos/test_util.h b/chrome/browser/ui/chromeos/test_util.h
index ff86547..2162ff3 100644
--- a/chrome/browser/ui/chromeos/test_util.h
+++ b/chrome/browser/ui/chromeos/test_util.h
@@ -7,6 +7,7 @@
 
 #include "base/test/test_future.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/mixin_based_in_process_browser_test.h"
 #include "chromeos/crosapi/mojom/test_controller.mojom.h"
 #include "chromeos/ui/base/window_state_type.h"
 #include "ui/aura/window.h"
@@ -27,14 +28,14 @@
 //
 // (*) Typically, these tests are built into the `browser_tests` target for Ash,
 // and into the `lacros_chrome_browsertests` target for Lacros.
-class ChromeOSBrowserUITest : public InProcessBrowserTest {
+class ChromeOSBrowserUITest : public MixinBasedInProcessBrowserTest {
  public:
   ChromeOSBrowserUITest() = default;
   ChromeOSBrowserUITest(const ChromeOSBrowserUITest&) = delete;
   ChromeOSBrowserUITest& operator=(const ChromeOSBrowserUITest&) = delete;
   ~ChromeOSBrowserUITest() override = default;
 
-  // InProcessBrowserTest:
+  // MixinBasedInProcessBrowserTest:
   void SetUpDefaultCommandLine(base::CommandLine* command_line) override;
   void TearDownOnMainThread() override;
 
diff --git a/chrome/browser/ui/performance_controls/performance_intervention_button_controller.cc b/chrome/browser/ui/performance_controls/performance_intervention_button_controller.cc
index cd4291c..c0cee3b 100644
--- a/chrome/browser/ui/performance_controls/performance_intervention_button_controller.cc
+++ b/chrome/browser/ui/performance_controls/performance_intervention_button_controller.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/performance_manager/public/user_tuning/performance_detection_manager.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/performance_controls/performance_controls_metrics.h"
 #include "chrome/browser/ui/performance_controls/performance_intervention_button_controller_delegate.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -55,9 +56,14 @@
 void PerformanceInterventionButtonController::OnActionableTabListChanged(
     PerformanceDetectionManager::ResourceType type,
     PerformanceDetectionManager::ActionableTabsResult result) {
-  Profile* const profile = browser_->profile();
   actionable_cpu_tabs_ = result;
+
   if (!result.empty()) {
+    // Only trigger performance detection UI for the active window.
+    if (browser_ != chrome::FindLastActive()) {
+      return;
+    }
+    Profile* const profile = browser_->profile();
     auto* const tracker =
         feature_engagement::TrackerFactory::GetForBrowserContext(profile);
     CHECK(tracker);
diff --git a/chrome/browser/ui/signin/signin_view_controller.cc b/chrome/browser/ui/signin/signin_view_controller.cc
index 58b7b8a..58c2991 100644
--- a/chrome/browser/ui/signin/signin_view_controller.cc
+++ b/chrome/browser/ui/signin/signin_view_controller.cc
@@ -5,10 +5,13 @@
 #include "chrome/browser/ui/signin/signin_view_controller.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
+#include "base/functional/callback_forward.h"
+#include "base/functional/callback_helpers.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/profiles/profile.h"
@@ -38,6 +41,7 @@
 #include "google_apis/gaia/core_account_id.h"
 
 #if BUILDFLAG(ENABLE_DICE_SUPPORT)
+#include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/search/search.h"
 #include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
 #include "chrome/browser/signin/account_consistency_mode_manager.h"
@@ -52,20 +56,59 @@
 #include "chrome/browser/ui/singleton_tabs.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/webui_url_constants.h"
+#include "chrome/grit/branded_strings.h"
+#include "chrome/grit/generated_resources.h"
+#include "components/constrained_window/constrained_window_views.h"
 #include "components/signin/public/base/account_consistency_method.h"
 #include "components/signin/public/identity_manager/accounts_mutator.h"
 #include "components/signin/public/identity_manager/primary_account_mutator.h"
+#include "components/strings/grit/components_strings.h"
 #include "components/sync/base/user_selectable_type.h"
 #include "components/sync/service/sync_service.h"
+#include "content/public/browser/navigation_handle.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 #include "google_apis/gaia/gaia_urls.h"
 #include "google_apis/google_api_keys.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/models/dialog_model.h"
 #include "url/url_constants.h"
 #endif  // BUILDFLAG(ENABLE_DICE_SUPPORT)
 
 namespace {
 
 #if BUILDFLAG(ENABLE_DICE_SUPPORT)
+class NewTabWebContentsObserver : public content::WebContentsObserver {
+ public:
+  explicit NewTabWebContentsObserver(
+      content::WebContents* web_contents,
+      base::OnceCallback<void(content::WebContents*)> callback)
+      : callback_(std::move(callback)) {
+    this->Observe(web_contents);
+  }
+
+  ~NewTabWebContentsObserver() override { Notify(nullptr); }
+
+  void DidFinishNavigation(
+      content::NavigationHandle* navigation_handle) override {
+    if (!callback_) {
+      return;
+    }
+    if (SigninViewController::IsNTPTab(navigation_handle->GetWebContents())) {
+      Notify(navigation_handle->GetWebContents());
+    }
+  }
+
+  void WebContentsDestroyed() override { Notify(nullptr); }
+
+ private:
+  void Notify(content::WebContents* web_contents) {
+    if (callback_) {
+      std::move(callback_).Run(web_contents);
+      // `this` might be destroyed.
+    }
+  }
+  base::OnceCallback<void(content::WebContents*)> callback_;
+};
 
 // Opens a new tab on |url| or reuses the current tab if it is the NTP.
 void ShowTabOverwritingNTP(Browser* browser, const GURL& url) {
@@ -230,6 +273,16 @@
 }
 
 #if BUILDFLAG(ENABLE_DICE_SUPPORT)
+// static
+bool SigninViewController::IsNTPTab(content::WebContents* contents) {
+  if (!contents) {
+    return false;
+  }
+  const GURL& contents_url = contents->GetVisibleURL();
+  return contents_url == chrome::kChromeUINewTabURL ||
+         search::IsInstantNTP(contents) || contents_url == url::kAboutBlankURL;
+}
+
 void SigninViewController::ShowSignin(signin_metrics::AccessPoint access_point,
                                       const GURL& redirect_url) {
   Profile* profile = browser_->profile();
@@ -279,6 +332,73 @@
   // Dice users don't see the prompt, pass empty datatypes.
   std::move(signout_prompt_with_datatypes).Run(syncer::ModelTypeSet());
 }
+
+void SigninViewController::MaybeShowChromeSigninDialogForExtensions(
+    std::string_view extension_name,
+    base::OnceClosure on_complete) {
+  // TODO(b/321900930): Consider using `CHECK()` instead on `DVLOG()`.
+  signin::IdentityManager* identity_manager =
+      IdentityManagerFactory::GetForProfile(browser_->profile());
+  if (identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin)) {
+    DVLOG(1) << "Chrome is already signed in.";
+    std::move(on_complete).Run();
+    return;
+  }
+
+  AccountInfo account_info_for_promos =
+      signin_ui_util::GetSingleAccountForPromos(
+          IdentityManagerFactory::GetForProfile(browser_->profile()));
+  if (account_info_for_promos.IsEmpty()) {
+    DVLOG(1) << "The user is not signed in on the web.";
+    std::move(on_complete).Run();
+    return;
+  }
+
+  // Check if there is already a new_tab_page open.
+  TabStripModel* tab_strip = browser_->tab_strip_model();
+  int ntp_tab_index = TabStripModel::kNoTab;
+  int active_tab_index = tab_strip->active_index();
+  int tab_count = tab_strip->count();
+  for (int tab_index = 0; tab_index < tab_count; ++tab_index) {
+    content::WebContents* web_contents = tab_strip->GetWebContentsAt(tab_index);
+    if (web_contents && SigninViewController::IsNTPTab(web_contents)) {
+      ntp_tab_index = tab_index;
+      // Prefer to keep the active tab if possible.
+      if (ntp_tab_index == active_tab_index) {
+        break;
+      }
+    }
+  }
+
+  if (ntp_tab_index != TabStripModel::kNoTab) {
+    tab_strip->ActivateTabAt(
+        ntp_tab_index, TabStripUserGestureDetails(
+                           TabStripUserGestureDetails::GestureType::kOther));
+    ShowChromeSigninDialogForExtensions(
+        extension_name, std::move(on_complete), account_info_for_promos,
+        tab_strip->GetWebContentsAt(ntp_tab_index));
+    return;
+  }
+
+  // Create a new tab page and wait for the navigation to complete.
+  NavigateParams params(browser_, GURL(chrome::kChromeUINewTabURL),
+                        ui::PAGE_TRANSITION_AUTO_BOOKMARK);
+  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
+  params.window_action = NavigateParams::SHOW_WINDOW;
+  params.user_gesture = false;
+  params.tabstrip_add_types |= AddTabTypes::ADD_INHERIT_OPENER;
+
+  content::WebContents* web_contents = Navigate(&params)->GetWebContents();
+  // `base::Unretained(this)` is safe as `this` owns
+  // `new_tab_web_contents_observer_`.
+  base::OnceCallback<void(content::WebContents*)> callback =
+      base::BindOnce(&SigninViewController::ShowChromeSigninDialogForExtensions,
+                     base::Unretained(this), std::string(extension_name),
+                     std::move(on_complete), account_info_for_promos);
+
+  new_tab_web_contents_observer_ = std::make_unique<NewTabWebContentsObserver>(
+      web_contents, std::move(callback));
+}
 #endif  // BUILDFLAG(ENABLE_DICE_SUPPORT)
 
 #if BUILDFLAG(ENABLE_DICE_SUPPORT) || BUILDFLAG(IS_CHROMEOS_LACROS)
@@ -620,6 +740,69 @@
     std::move(callback).Run(ChromeSignoutConfirmationChoice::kSignout);
   }
 }
+
+void SigninViewController::ShowChromeSigninDialogForExtensions(
+    std::string_view extension_name,
+    base::OnceClosure on_complete,
+    const AccountInfo& account_info_for_promos,
+    content::WebContents* contents) {
+  new_tab_web_contents_observer_.reset();
+  if (!contents) {
+    std::move(on_complete).Run();
+    return;
+  }
+
+  // `ok_callback` sets the primary account.
+  base::OnceClosure ok_callback = base::BindOnce(
+      [](base::WeakPtr<Profile> profile, const CoreAccountId& account_id) {
+        if (!profile) {
+          return;
+        }
+        signin::IdentityManager* identity_manager =
+            IdentityManagerFactory::GetForProfile(profile.get());
+        if (identity_manager) {
+          identity_manager->GetPrimaryAccountMutator()->SetPrimaryAccount(
+              account_id, signin::ConsentLevel::kSignin,
+              signin_metrics::AccessPoint::ACCESS_POINT_EXTENSIONS);
+        }
+      },
+      browser_->profile()->GetWeakPtr(), account_info_for_promos.account_id);
+
+  std::u16string title =
+      extension_name.empty()
+          ? l10n_util::GetStringUTF16(
+                IDS_EXTENSION_ASKS_IDENTITY_WHILE_SIGNED_IN_WEB_ONLY_TITLE_FALLBACK)
+          : l10n_util::GetStringFUTF16(
+                IDS_EXTENSION_ASKS_IDENTITY_WHILE_SIGNED_IN_WEB_ONLY_TITLE,
+                base::UTF8ToUTF16(extension_name));
+  // TODO(msalama): Remove in next milestone.
+  base::RemoveChars(title, u"\\", &title);
+
+  std::u16string continue_as_text =
+      base::UTF8ToUTF16(!account_info_for_promos.given_name.empty()
+                            ? account_info_for_promos.given_name
+                            : account_info_for_promos.email);
+  std::u16string body = l10n_util::GetStringFUTF16(
+      IDS_EXTENSION_ASKS_IDENTITY_WHILE_SIGNED_IN_WEB_ONLY_BODY,
+      base::UTF8ToUTF16(account_info_for_promos.email));
+  // TODO(msalama): Remove in next milestone.
+  base::ReplaceSubstringsAfterOffset(&body, 0, u"\\n", u"\n");
+
+  ui::DialogModel::Builder dialog_builder;
+  dialog_builder.SetInternalName("ChromeSigninChoiceForExtensionsPrompt")
+      .SetTitle(title)
+      .AddParagraph((ui::DialogModelLabel(body)))
+      .AddOkButton(
+          base::BindOnce(std::move(ok_callback)),
+          ui::DialogModel::Button::Params().SetLabel(l10n_util::GetStringFUTF16(
+              IDS_PROFILES_DICE_WEB_ONLY_SIGNIN_BUTTON, continue_as_text)))
+      .AddCancelButton(base::DoNothing(),
+                       ui::DialogModel::Button::Params().SetLabel(
+                           l10n_util::GetStringUTF16(IDS_CANCEL)))
+      .SetDialogDestroyingCallback(std::move(on_complete));
+
+  constrained_window::ShowWebModal(dialog_builder.Build(), contents);
+}
 #endif  // BUILDFLAG(ENABLE_DICE_SUPPORT)
 
 content::WebContents*
diff --git a/chrome/browser/ui/signin/signin_view_controller.h b/chrome/browser/ui/signin/signin_view_controller.h
index 0e801fa..83f579d 100644
--- a/chrome/browser/ui/signin/signin_view_controller.h
+++ b/chrome/browser/ui/signin/signin_view_controller.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "base/functional/callback.h"
+#include "base/functional/callback_forward.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
@@ -53,6 +54,12 @@
 enum class ReauthResult;
 }
 
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+namespace {
+class NewTabWebContentsObserver;
+}
+#endif
+
 // Class responsible for showing and hiding all sign-in related UIs
 // (modal sign-in, DICE full-tab sign-in page, sync confirmation dialog, sign-in
 // error dialog, reauth prompt). Sync confirmation is used on
@@ -74,6 +81,9 @@
   virtual ~SigninViewController();
 
 #if BUILDFLAG(ENABLE_DICE_SUPPORT)
+  // Returns true if Chrome new tab page/blank is displayed in `contents`.
+  static bool IsNTPTab(content::WebContents* contents);
+
   // Shows the signin attached to |browser_|'s active web contents.
   // |access_point| indicates the access point used to open the Gaia sign in
   // page.
@@ -115,6 +125,13 @@
       signin_metrics::AccessPoint reauth_access_point,
       signin_metrics::ProfileSignout profile_signout_source,
       signin_metrics::SourceForRefreshTokenOperation token_signout_source);
+
+  // Called by extensions to ask the user to sign in to chrome while they are
+  // signed in on the web only.
+  // This opens/reuses a new tab page and opens a modal dialog.
+  // Note: This should  only be called if the dialog is not already showing.
+  void MaybeShowChromeSigninDialogForExtensions(std::string_view extension_name,
+                                                base::OnceClosure on_complete);
 #endif  // BUILDFLAG(ENABLE_DICE_SUPPORT)
 
 #if BUILDFLAG(ENABLE_DICE_SUPPORT) || BUILDFLAG(IS_CHROMEOS_LACROS)
@@ -236,6 +253,13 @@
       signin_metrics::ProfileSignout profile_signout_source,
       signin_metrics::SourceForRefreshTokenOperation token_signout_source,
       syncer::ModelTypeSet unsynced_datatypes);
+
+  void ShowChromeSigninDialogForExtensions(
+      std::string_view extension_name,
+      base::OnceClosure on_complete,
+      const AccountInfo& account_info_for_promos,
+      content::WebContents* contents);
+
 #endif  // BUILDFLAG(ENABLE_DICE_SUPPORT)
 
   // Returns the web contents of the modal dialog.
@@ -254,6 +278,10 @@
   // Currently displayed modal dialog, or nullptr if none is displayed.
   std::unique_ptr<SigninModalDialog> dialog_;
 
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+  std::unique_ptr<NewTabWebContentsObserver> new_tab_web_contents_observer_;
+#endif
+
   base::WeakPtrFactory<SigninViewController> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/ui/signin/signin_view_controller_browsertest.cc b/chrome/browser/ui/signin/signin_view_controller_browsertest.cc
index 502a647d..6378bf2 100644
--- a/chrome/browser/ui/signin/signin_view_controller_browsertest.cc
+++ b/chrome/browser/ui/signin/signin_view_controller_browsertest.cc
@@ -4,8 +4,12 @@
 
 #include "chrome/browser/ui/signin/signin_view_controller.h"
 
+#include <string_view>
+
+#include "base/functional/callback_forward.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
+#include "base/test/test_future.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/dice_tab_helper.h"
 #include "chrome/browser/signin/logout_tab_helper.h"
@@ -14,6 +18,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/signin/chrome_signout_confirmation_prompt.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/test/base/ui_test_utils.h"
 #include "chrome_signout_confirmation_prompt.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/prefs/pref_service.h"
@@ -24,6 +29,7 @@
 #include "components/signin/public/identity_manager/account_info.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/signin/public/identity_manager/identity_test_environment.h"
+#include "components/signin/public/identity_manager/identity_test_utils.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/test/test_sync_service.h"
 #include "content/public/test/browser_test.h"
@@ -44,6 +50,7 @@
     "Signin.ChromeSignoutConfirmationPrompt.Unsynced";
 constexpr char kConfirmationUnsyncedReauthHistogramName[] =
     "Signin.ChromeSignoutConfirmationPrompt.UnsyncedReauth";
+constexpr std::string_view kTestExtensionName = "Test extension";
 
 std::unique_ptr<KeyedService> CreateTestSyncService(content::BrowserContext*) {
   return std::make_unique<syncer::TestSyncService>();
@@ -174,6 +181,22 @@
 
 class SigninViewControllerBrowserTest
     : public SigninViewControllerBrowserTestBase {
+ public:
+  views::DialogDelegate* TriggerChromeSigninDialogForExtensionsPrompt(
+      base::OnceClosure on_complete) {
+    views::NamedWidgetShownWaiter widget_waiter(
+        views::test::AnyWidgetTestPasskey{},
+        "ChromeSigninChoiceForExtensionsPrompt");
+    browser()
+        ->signin_view_controller()
+        ->MaybeShowChromeSigninDialogForExtensions(kTestExtensionName,
+                                                   std::move(on_complete));
+
+    // Confirmation prompt is shown.
+    views::Widget* confirmation_prompt = widget_waiter.WaitIfNeededAndGet();
+    return confirmation_prompt->widget_delegate()->AsDialogDelegate();
+  }
+
  private:
   base::test::ScopedFeatureList feature_list_{
       switches::kExplicitBrowserSigninUIOnDesktop};
@@ -281,6 +304,146 @@
   EXPECT_TRUE(IsSignoutTab(tab));
 }
 
+IN_PROC_BROWSER_TEST_F(SigninViewControllerBrowserTest,
+                       ShowChromeSigninDialogForExtensionsPromptReuseOpenTab) {
+  ASSERT_EQ(browser()->tab_strip_model()->count(), 1);
+  ASSERT_TRUE(SigninViewController::IsNTPTab(
+      browser()->tab_strip_model()->GetActiveWebContents()));
+
+  identity_test_env()->MakeAccountAvailable(kTestEmail, {.set_cookie = true});
+  ASSERT_FALSE(identity_manager()->GetAccountsWithRefreshTokens().empty());
+  ASSERT_FALSE(
+      identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSignin));
+
+  base::test::TestFuture<void> future;
+  views::DialogDelegate* dialog_delegate =
+      TriggerChromeSigninDialogForExtensionsPrompt(future.GetCallback());
+  ASSERT_TRUE(dialog_delegate);
+
+  content::WebContents* tab =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ASSERT_TRUE(tab);
+  EXPECT_TRUE(SigninViewController::IsNTPTab(tab));
+
+  ASSERT_FALSE(future.IsReady());
+  dialog_delegate->AcceptDialog();
+
+  EXPECT_TRUE(
+      identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSignin));
+  ASSERT_TRUE(future.Wait());
+  ASSERT_EQ(browser()->tab_strip_model()->count(), 1);
+}
+
+IN_PROC_BROWSER_TEST_F(
+    SigninViewControllerBrowserTest,
+    ShowChromeSigninDialogForExtensionsPromptReuseInactiveOpenTab) {
+  ui_test_utils::NavigateToURLWithDisposition(
+      browser(), GURL("https://www.google.com"),
+      WindowOpenDisposition::NEW_FOREGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+  ASSERT_EQ(browser()->tab_strip_model()->count(), 2);
+  ASSERT_FALSE(SigninViewController::IsNTPTab(
+      browser()->tab_strip_model()->GetActiveWebContents()));
+
+  identity_test_env()->MakeAccountAvailable(kTestEmail, {.set_cookie = true});
+  ASSERT_FALSE(identity_manager()->GetAccountsWithRefreshTokens().empty());
+  ASSERT_FALSE(
+      identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSignin));
+
+  base::test::TestFuture<void> future;
+  views::DialogDelegate* dialog_delegate =
+      TriggerChromeSigninDialogForExtensionsPrompt(future.GetCallback());
+  ASSERT_TRUE(dialog_delegate);
+
+  content::WebContents* tab =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ASSERT_TRUE(tab);
+  EXPECT_TRUE(SigninViewController::IsNTPTab(tab));
+
+  ASSERT_FALSE(future.IsReady());
+  dialog_delegate->AcceptDialog();
+
+  EXPECT_TRUE(
+      identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSignin));
+  ASSERT_TRUE(future.Wait());
+  ASSERT_EQ(browser()->tab_strip_model()->count(), 2);
+}
+
+IN_PROC_BROWSER_TEST_F(SigninViewControllerBrowserTest,
+                       ShowChromeSigninDialogForExtensionsPromptInNewTab) {
+  ASSERT_TRUE(
+      ui_test_utils::NavigateToURL(browser(), GURL("https://www.google.com")));
+  ASSERT_EQ(browser()->tab_strip_model()->count(), 1);
+  ASSERT_FALSE(SigninViewController::IsNTPTab(
+      browser()->tab_strip_model()->GetActiveWebContents()));
+
+  identity_test_env()->MakeAccountAvailable(kTestEmail, {.set_cookie = true});
+  ASSERT_FALSE(identity_manager()->GetAccountsWithRefreshTokens().empty());
+  ASSERT_FALSE(
+      identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSignin));
+
+  base::test::TestFuture<void> future;
+  views::DialogDelegate* dialog_delegate =
+      TriggerChromeSigninDialogForExtensionsPrompt(future.GetCallback());
+  ASSERT_TRUE(dialog_delegate);
+  ASSERT_EQ(browser()->tab_strip_model()->count(), 2);
+
+  content::WebContents* tab =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ASSERT_TRUE(tab);
+  EXPECT_TRUE(SigninViewController::IsNTPTab(tab));
+
+  ASSERT_FALSE(future.IsReady());
+  dialog_delegate->AcceptDialog();
+
+  EXPECT_TRUE(
+      identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSignin));
+  ASSERT_TRUE(future.Wait());
+}
+
+IN_PROC_BROWSER_TEST_F(SigninViewControllerBrowserTest,
+                       ShowChromeSigninDialogForExtensionsPromptCancel) {
+  identity_test_env()->MakeAccountAvailable(kTestEmail, {.set_cookie = true});
+  ASSERT_FALSE(identity_manager()->GetAccountsWithRefreshTokens().empty());
+  ASSERT_FALSE(
+      identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSignin));
+
+  base::test::TestFuture<void> future;
+  views::DialogDelegate* dialog_delegate =
+      TriggerChromeSigninDialogForExtensionsPrompt(future.GetCallback());
+  ASSERT_TRUE(dialog_delegate);
+
+  ASSERT_FALSE(future.IsReady());
+  dialog_delegate->CancelDialog();
+
+  EXPECT_FALSE(
+      identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSignin));
+  ASSERT_TRUE(future.Wait());
+}
+
+IN_PROC_BROWSER_TEST_F(
+    SigninViewControllerBrowserTest,
+    ShowChromeSigninDialogForExtensionsPromptNotShownPrimaryAccountSet) {
+  identity_test_env()->MakePrimaryAccountAvailable(
+      kTestEmail, signin::ConsentLevel::kSignin);
+  ASSERT_TRUE(
+      identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSignin));
+
+  base::test::TestFuture<void> future;
+  browser()->signin_view_controller()->MaybeShowChromeSigninDialogForExtensions(
+      kTestExtensionName, future.GetCallback());
+  EXPECT_TRUE(future.IsReady());
+}
+
+IN_PROC_BROWSER_TEST_F(
+    SigninViewControllerBrowserTest,
+    ShowChromeSigninDialogForExtensionsPromptNotShownNoAccounts) {
+  base::test::TestFuture<void> future;
+  browser()->signin_view_controller()->MaybeShowChromeSigninDialogForExtensions(
+      kTestExtensionName, future.GetCallback());
+  EXPECT_TRUE(future.IsReady());
+}
+
 class SigninViewControllerBrowserCookieParamTest
     : public SigninViewControllerBrowserTest,
       public testing::WithParamInterface<bool> {
diff --git a/chrome/browser/ui/tabs/features.cc b/chrome/browser/ui/tabs/features.cc
index 2ac8a92..a3d1224 100644
--- a/chrome/browser/ui/tabs/features.cc
+++ b/chrome/browser/ui/tabs/features.cc
@@ -9,6 +9,12 @@
 
 namespace tabs {
 
+// Splits pinned and unpinned tabs into separate TabStrips.
+// https://crbug.com/1346019
+BASE_FEATURE(kSplitTabStrip,
+             "SplitTabStrip",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 BASE_FEATURE(kTabSearchPositionSetting,
              "TabSearchPositionSetting",
              base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/chrome/browser/ui/tabs/features.h b/chrome/browser/ui/tabs/features.h
index 9df2d948..c119f1e 100644
--- a/chrome/browser/ui/tabs/features.h
+++ b/chrome/browser/ui/tabs/features.h
@@ -11,6 +11,8 @@
 
 // TODO(346837232) move all flags to this file.
 
+BASE_DECLARE_FEATURE(kSplitTabStrip);
+
 BASE_DECLARE_FEATURE(kTabSearchPositionSetting);
 
 extern bool CanShowTabSearchPositionSetting();
diff --git a/chrome/browser/ui/ui_features.cc b/chrome/browser/ui/ui_features.cc
index 074de1c..b021add 100644
--- a/chrome/browser/ui/ui_features.cc
+++ b/chrome/browser/ui/ui_features.cc
@@ -301,12 +301,6 @@
              base::FEATURE_DISABLED_BY_DEFAULT);
 const char kScrollableTabStripOverflowModeName[] = "tabScrollOverflow";
 
-// Splits pinned and unpinned tabs into separate TabStrips.
-// https://crbug.com/1346019
-BASE_FEATURE(kSplitTabStrip,
-             "SplitTabStrip",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 // Stores the tabs as a tree based data structure instead of a
 // vector in the tabstrip model. b/323937237
 BASE_FEATURE(kTabStripCollectionStorage,
diff --git a/chrome/browser/ui/ui_features.h b/chrome/browser/ui/ui_features.h
index c971ba1b..1b1edb9 100644
--- a/chrome/browser/ui/ui_features.h
+++ b/chrome/browser/ui/ui_features.h
@@ -151,7 +151,6 @@
 BASE_DECLARE_FEATURE(kScrollableTabStripWithDragging);
 extern const char kTabScrollingWithDraggingModeName[];
 
-BASE_DECLARE_FEATURE(kSplitTabStrip);
 BASE_DECLARE_FEATURE(kTabStripCollectionStorage);
 
 BASE_DECLARE_FEATURE(kTabScrollingButtonPosition);
diff --git a/chrome/browser/ui/views/autofill/address_bubble_base_view.h b/chrome/browser/ui/views/autofill/address_bubble_base_view.h
index 98accf83..ad208c0 100644
--- a/chrome/browser/ui/views/autofill/address_bubble_base_view.h
+++ b/chrome/browser/ui/views/autofill/address_bubble_base_view.h
@@ -12,7 +12,8 @@
 class AddressBubbleBaseView : public AutofillLocationBarBubble {
   using AutofillLocationBarBubble::AutofillLocationBarBubble;
 
-  // TODO(b/325440757): Add common for Save/UpdateAddressProfileView functions.
+  // TODO(crbug.com/325440757): Add common for Save/UpdateAddressProfileView
+  // functions.
 };
 
 }  // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/popup/password_favicon_loader_unittest.cc b/chrome/browser/ui/views/autofill/popup/password_favicon_loader_unittest.cc
index aa921c1f..67ea564 100644
--- a/chrome/browser/ui/views/autofill/popup/password_favicon_loader_unittest.cc
+++ b/chrome/browser/ui/views/autofill/popup/password_favicon_loader_unittest.cc
@@ -18,6 +18,7 @@
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/codec/png_codec.h"
+#include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_unittest_util.h"
 #include "ui/resources/grit/ui_resources.h"
 
@@ -98,6 +99,33 @@
   return gfx::test::AreBitmapsEqual(arg.AsBitmap(), img.AsBitmap());
 }
 
+favicon_base::LargeIconResult GetFaviconResult(const gfx::Image& image) {
+  scoped_refptr<base::RefCountedBytes> data =
+      base::MakeRefCounted<base::RefCountedBytes>();
+  gfx::PNGCodec::EncodeBGRASkBitmap(
+      /*input=*/*image.ToSkBitmap(),
+      /*discard_transparency=*/false, /*output=*/&data->as_vector());
+  favicon_base::FaviconRawBitmapResult bitmap_result;
+  bitmap_result.bitmap_data = data;
+  return favicon_base::LargeIconResult(bitmap_result);
+}
+
+// `LargeIconService::GetLargeIconFromCacheFallbackToGoogleServer()` wrapper
+// that simplifies its mocking by ignoring all arguments except the callback.
+auto MockGetLargeIcon(
+    testing::OnceAction<void(favicon_base::LargeIconCallback callback)>
+        callback_handler) {
+  return [callback_handler = std::move(callback_handler)](
+             const GURL&, favicon::LargeIconService::StandardIconSize,
+             std::optional<favicon::LargeIconService::StandardIconSize>,
+             favicon::LargeIconService::NoBigEnoughIconBehavior, bool,
+             const net::NetworkTrafficAnnotationTag&,
+             favicon_base::LargeIconCallback result_callback,
+             base::CancelableTaskTracker*) mutable {
+    std::move(callback_handler).Call(std::move(result_callback));
+  };
+}
+
 }  // namespace
 
 class PasswordFaviconLoaderTest : public testing::Test {
@@ -121,27 +149,14 @@
 
 TEST_F(PasswordFaviconLoaderTest, LoadsImageFromFaviconService) {
   EXPECT_CALL(large_icon_service(), GetLargeIconFromCacheFallbackToGoogleServer)
-      .WillOnce([](const GURL&, favicon::LargeIconService::StandardIconSize,
-                   std::optional<favicon::LargeIconService::StandardIconSize>,
-                   favicon::LargeIconService::NoBigEnoughIconBehavior, bool,
-                   const net::NetworkTrafficAnnotationTag&,
-                   base::OnceCallback<void(
-                       const favicon_base::LargeIconResult&)> result_callback,
-                   base::CancelableTaskTracker*) {
-        gfx::Image favicon =
-            ui::ResourceBundle::GetSharedInstance().GetImageNamed(IDR_DISABLE);
-        scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes());
-        gfx::PNGCodec::EncodeBGRASkBitmap(
-            /*input=*/*favicon.ToSkBitmap(),
-            /*discard_transparency=*/false, /*output=*/&data->as_vector());
-        favicon_base::FaviconRawBitmapResult bitmap_result;
-        bitmap_result.bitmap_data = data;
-
-        ASSERT_TRUE(bitmap_result.is_valid());
-
-        std::move(result_callback)
-            .Run(favicon_base::LargeIconResult(bitmap_result));
-      });
+      .WillOnce(
+          MockGetLargeIcon([](favicon_base::LargeIconCallback result_callback) {
+            favicon_base::LargeIconResult result = GetFaviconResult(
+                ui::ResourceBundle::GetSharedInstance().GetImageNamed(
+                    IDR_DISABLE));
+            ASSERT_TRUE(result.bitmap.is_valid());
+            std::move(result_callback).Run(result);
+          }));
 
   base::MockOnceCallback<void(const gfx::Image&)> on_success;
   base::MockOnceClosure on_fail;
@@ -160,19 +175,11 @@
 
 TEST_F(PasswordFaviconLoaderTest, FailsWithInvalidResponseFromFaviconService) {
   EXPECT_CALL(large_icon_service(), GetLargeIconFromCacheFallbackToGoogleServer)
-      .WillOnce(
-          [](const GURL&, favicon::LargeIconService::StandardIconSize,
-             std::optional<favicon::LargeIconService::StandardIconSize>,
-             favicon::LargeIconService::NoBigEnoughIconBehavior, bool,
-             const net::NetworkTrafficAnnotationTag&,
-             base::OnceCallback<void(const favicon_base::LargeIconResult&)>
-                 result_callback,
-             base::CancelableTaskTracker*) {
-            favicon_base::FaviconRawBitmapResult bitmap_result;
-            ASSERT_FALSE(bitmap_result.is_valid());
-            std::move(result_callback)
-                .Run(favicon_base::LargeIconResult(bitmap_result));
-          });
+      .WillOnce(MockGetLargeIcon([](favicon_base::LargeIconCallback callback) {
+        favicon_base::FaviconRawBitmapResult bitmap_result;
+        ASSERT_FALSE(bitmap_result.is_valid());
+        std::move(callback).Run(favicon_base::LargeIconResult(bitmap_result));
+      }));
 
   base::MockOnceCallback<void(const gfx::Image&)> on_success;
   base::MockOnceClosure on_fail;
@@ -207,27 +214,12 @@
   // Expect one call to the favicon service, after which the result will be
   // provided from cache.
   EXPECT_CALL(large_icon_service(), GetLargeIconFromCacheFallbackToGoogleServer)
-      .WillOnce([](const GURL&, favicon::LargeIconService::StandardIconSize,
-                   std::optional<favicon::LargeIconService::StandardIconSize>,
-                   favicon::LargeIconService::NoBigEnoughIconBehavior, bool,
-                   const net::NetworkTrafficAnnotationTag&,
-                   base::OnceCallback<void(
-                       const favicon_base::LargeIconResult&)> result_callback,
-                   base::CancelableTaskTracker*) {
-        gfx::Image favicon =
-            ui::ResourceBundle::GetSharedInstance().GetImageNamed(IDR_DISABLE);
-        scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes());
-        gfx::PNGCodec::EncodeBGRASkBitmap(
-            /*input=*/*favicon.ToSkBitmap(),
-            /*discard_transparency=*/false, /*output=*/&data->as_vector());
-        favicon_base::FaviconRawBitmapResult bitmap_result;
-        bitmap_result.bitmap_data = data;
-
-        ASSERT_TRUE(bitmap_result.is_valid());
-
-        std::move(result_callback)
-            .Run(favicon_base::LargeIconResult(bitmap_result));
-      });
+      .WillOnce(MockGetLargeIcon([](favicon_base::LargeIconCallback callback) {
+        favicon_base::LargeIconResult result = GetFaviconResult(
+            ui::ResourceBundle::GetSharedInstance().GetImageNamed(IDR_DISABLE));
+        ASSERT_TRUE(result.bitmap.is_valid());
+        std::move(callback).Run(result);
+      }));
   EXPECT_CALL(
       on_success,
       Run(ImagesAreEqual(
diff --git a/chrome/browser/ui/views/autofill/popup/popup_base_view.cc b/chrome/browser/ui/views/autofill/popup/popup_base_view.cc
index 4675e75..f324fad4 100644
--- a/chrome/browser/ui/views/autofill/popup/popup_base_view.cc
+++ b/chrome/browser/ui/views/autofill/popup/popup_base_view.cc
@@ -288,9 +288,9 @@
 
   // Showing the widget can change native focus (which would result in an
   // immediate hiding of the popup). Only start observing after shown.
-  // TODO(b/325246516): Hiding by widget focus change seems redundant as it is
-  // already done by the field focus loss. After successful password manual
-  // fallback testing confirms safety, remove the focus observation.
+  // TODO(crbug.com/325246516): Hiding by widget focus change seems redundant as
+  // it is already done by the field focus loss. After successful password
+  // manual fallback testing confirms safety, remove the focus observation.
   if (initialize_widget &&
       !base::FeatureList::IsEnabled(
           password_manager::features::kPasswordManualFallbackAvailable)) {
diff --git a/chrome/browser/ui/views/autofill/popup/popup_search_bar_view.cc b/chrome/browser/ui/views/autofill/popup/popup_search_bar_view.cc
index 59a85f4..2a947ca9 100644
--- a/chrome/browser/ui/views/autofill/popup/popup_search_bar_view.cc
+++ b/chrome/browser/ui/views/autofill/popup/popup_search_bar_view.cc
@@ -44,8 +44,8 @@
 
   input_ = AddChildView(
       views::Builder<views::Textfield>()
-          // TODO(b/325246516): Set default placeholder according to approved
-          // greenlines.
+          // TODO(crbug.com/325246516): Set default placeholder according to
+          // approved greenlines.
           .SetPlaceholderText(placeholder.empty() ? u"Search" : placeholder)
           .SetController(this)
           .SetBorder(nullptr)
@@ -61,9 +61,9 @@
       input_->AddTextChangedCallback(base::BindRepeating(
           &PopupSearchBarView::OnInputChanged, base::Unretained(this)));
 
-  // TODO(b/325246516): Clarify whether the clear button should be rendered
-  // on top of the input field and rework the layout (probably with a custom
-  // LayoutManager).
+  // TODO(crbug.com/325246516): Clarify whether the clear button should be
+  // rendered on top of the input field and rework the layout (probably with a
+  // custom LayoutManager).
   clear_ = AddChildView(
       views::Builder<views::ImageButton>()
           .SetCallback(base::BindRepeating(&PopupSearchBarView::OnClearPressed,
@@ -71,7 +71,8 @@
           .SetImageModel(views::Button::STATE_NORMAL,
                          ui::ImageModel::FromVectorIcon(
                              vector_icons::kCloseChromeRefreshIcon))
-          // TODO(b/325246516): Set the name according to approved greenlines.
+          // TODO(crbug.com/325246516): Set the name according to approved
+          // greenlines.
           .SetAccessibleName(u"tmp non empty name")
           .Build());
 }
diff --git a/chrome/browser/ui/views/autofill/popup/popup_search_bar_view.h b/chrome/browser/ui/views/autofill/popup/popup_search_bar_view.h
index db93ae3..ecebf3bd 100644
--- a/chrome/browser/ui/views/autofill/popup/popup_search_bar_view.h
+++ b/chrome/browser/ui/views/autofill/popup/popup_search_bar_view.h
@@ -85,8 +85,8 @@
   void SetInputTextForTesting(const std::u16string& text);
   gfx::Point GetClearButtonScreenCenterPointForTesting() const;
 
-  // TODO(b/325246516): Add methods to support communication with its hosting
-  // poopup view.
+  // TODO(crbug.com/325246516): Add methods to support communication with its
+  // hosting poopup view.
 
  private:
   void OnInputChanged();
diff --git a/chrome/browser/ui/views/autofill/popup/popup_search_bar_view_unittest.cc b/chrome/browser/ui/views/autofill/popup/popup_search_bar_view_unittest.cc
index eb40289..a796e1d 100644
--- a/chrome/browser/ui/views/autofill/popup/popup_search_bar_view_unittest.cc
+++ b/chrome/browser/ui/views/autofill/popup/popup_search_bar_view_unittest.cc
@@ -131,7 +131,8 @@
       PopupSearchBarView::kInputChangeCallbackDelay);
 }
 
-// TODO(b/338934966): Enable when key events suppressing in tests is fixed.
+// TODO(crbug.com/338934966): Enable when key events suppressing in tests is
+// fixed.
 #if !BUILDFLAG(IS_WIN)
 TEST_F(PopupSearchBarViewTest, KeyPressedFromTextfieldPassedToDelegateFirst) {
   PopupSearchBarView* view = widget().SetContentsView(
diff --git a/chrome/browser/ui/views/autofill/popup/popup_view_views.cc b/chrome/browser/ui/views/autofill/popup/popup_view_views.cc
index 7ed546b..a8183a7 100644
--- a/chrome/browser/ui/views/autofill/popup/popup_view_views.cc
+++ b/chrome/browser/ui/views/autofill/popup/popup_view_views.cc
@@ -236,7 +236,7 @@
   }
 
   // Compose has separate on show announcements.
-  // TODO(b/340359989): Replace with AutofillComposeDelegate::OnShow
+  // TODO(crbug.com/340359989): Replace with AutofillComposeDelegate::OnShow
   if (controller_->GetMainFillingProduct() == FillingProduct::kCompose) {
     switch (controller_->GetSuggestionAt(0).type) {
       case SuggestionType::kComposeResumeNudge:
@@ -756,7 +756,7 @@
     return false;
   }
 
-// TODO(b/339187209): On MaOS, conversion of a character key event to
+// TODO(crbug.com/339187209): On MaOS, conversion of a character key event to
 // `NativeWebKeyboardEvent` hits `NOTREACHED` in `ui::DomKeyFromNSEvent`. This
 // doesn't affect our use case as we handle only non-character events
 // (Arrows/Esc/etc) for navigation. But it needs to be investigated and ideally
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.cc b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.cc
index 7b516bb..a74487b0 100644
--- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.cc
+++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.cc
@@ -22,6 +22,7 @@
 #include "components/content_settings/core/common/features.h"
 #include "components/content_settings/core/common/tracking_protection_feature.h"
 #include "components/favicon/core/favicon_service.h"
+#include "components/privacy_sandbox/privacy_sandbox_features.h"
 #include "components/privacy_sandbox/tracking_protection_settings.h"
 #include "components/strings/grit/privacy_sandbox_strings.h"
 #include "content/public/browser/navigation_controller.h"
@@ -58,6 +59,11 @@
   return enabled ? views::kEyeRefreshIcon : views::kEyeCrossedRefreshIcon;
 }
 
+bool IsNewUiEnabled() {
+  return base::FeatureList::IsEnabled(
+      privacy_sandbox::kTrackingProtectionSettingsLaunch);
+}
+
 }  // namespace
 
 CookieControlsBubbleViewController::CookieControlsBubbleViewController(
@@ -149,7 +155,8 @@
   bubble_view_->UpdateTitle(l10n_util::GetStringUTF16(bubble_title));
   bubble_view_->GetContentView()->UpdateContentLabels(
       label_title, l10n_util::GetStringUTF16(label_description));
-  bubble_view_->GetContentView()->SetToggleIsOn(true);
+  // New UB UI toggle matches protections state (off when protections off).
+  bubble_view_->GetContentView()->SetToggleIsOn(!IsNewUiEnabled());
   bubble_view_->GetContentView()->SetToggleIcon(GetToggleIcon(true));
 }
 
@@ -163,7 +170,8 @@
           IDS_COOKIE_CONTROLS_BUBBLE_SITE_NOT_WORKING_TITLE),
       l10n_util::GetStringUTF16(
           IDS_TRACKING_PROTECTION_BUBBLE_SITE_NOT_WORKING_DESCRIPTION));
-  bubble_view_->GetContentView()->SetToggleIsOn(false);
+  // New UB UI toggle matches protections state (on when protections on).
+  bubble_view_->GetContentView()->SetToggleIsOn(IsNewUiEnabled());
   bubble_view_->GetContentView()->SetToggleIcon(GetToggleIcon(false));
 }
 
@@ -297,8 +305,10 @@
 }
 
 void CookieControlsBubbleViewController::OnToggleButtonPressed(
-    bool allow_third_party_cookies) {
-  if (allow_third_party_cookies) {
+    bool toggled_on) {
+  // Protections are on iff the toggle is on in the new UI or off in the old UI.
+  bool protections_on = IsNewUiEnabled() == toggled_on;
+  if (!protections_on) {
     base::RecordAction(base::UserMetricsAction(
         "CookieControls.Bubble.AllowThirdPartyCookies"));
   } else {
@@ -306,7 +316,8 @@
         "CookieControls.Bubble.BlockThirdPartyCookies"));
   }
   controller_->SetUserChangedCookieBlockingForSite(true);
-  controller_->OnCookieBlockingEnabledForSite(!allow_third_party_cookies);
+  // Set the toggle ON when protections are ON (cookies are blocked).
+  controller_->OnCookieBlockingEnabledForSite(protections_on);
   bubble_view_->GetContentView()->NotifyAccessibilityEvent(
       ax::mojom::Event::kAlert, true);
 }
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.h b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.h
index adc678e..d1e2578 100644
--- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.h
+++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.h
@@ -48,7 +48,7 @@
 
   void SetCallbacks();
   void OnUserClosedContentView();
-  void OnToggleButtonPressed(bool new_value);
+  void OnToggleButtonPressed(bool toggled_on);
   void OnFeedbackButtonPressed();
 
   void OnFaviconFetched(const favicon_base::FaviconImageResult& result) const;
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_interactive_uitest.cc b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_interactive_uitest.cc
index e11eafc..4b77b0e 100644
--- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_interactive_uitest.cc
+++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_interactive_uitest.cc
@@ -173,7 +173,8 @@
   auto CheckTrackingProtectionAllowedState() {
     return Steps(
         CheckViewProperty(CookieControlsContentView::kToggleButton,
-                          &views::ToggleButton::GetIsOn, true),
+                          &views::ToggleButton::GetIsOn,
+                          !HasNewTrackingProtectionUi()),
         CheckViewProperty(
             CookieControlsContentView::kTitle, &views::Label::GetText,
             l10n_util::GetPluralStringFUTF16(
@@ -199,7 +200,8 @@
   auto CheckTrackingProtectionBlockedState() {
     return Steps(
         CheckViewProperty(CookieControlsContentView::kToggleButton,
-                          &views::ToggleButton::GetIsOn, false),
+                          &views::ToggleButton::GetIsOn,
+                          HasNewTrackingProtectionUi()),
         CheckViewProperty(
             CookieControlsContentView::kTitle, &views::Label::GetText,
             l10n_util::GetStringUTF16(
diff --git a/chrome/browser/ui/views/performance_controls/performance_intervention_button.cc b/chrome/browser/ui/views/performance_controls/performance_intervention_button.cc
index b515b03..79562d5f 100644
--- a/chrome/browser/ui/views/performance_controls/performance_intervention_button.cc
+++ b/chrome/browser/ui/views/performance_controls/performance_intervention_button.cc
@@ -17,7 +17,6 @@
 #include "chrome/browser/ui/views/performance_controls/performance_intervention_bubble.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_button.h"
 #include "chrome/grit/generated_resources.h"
-#include "ui/accessibility/ax_enums.mojom-shared.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/base/models/image_model.h"
@@ -36,10 +35,10 @@
   button_controller()->set_notify_action(
       views::ButtonController::NotifyAction::kOnPress);
   SetFlipCanvasOnPaintForRTLUI(false);
-  // TODO(crbug.com/338620692): Replace placeholder accessibility name when
-  // strings finalize.
-  SetAccessibleName(std::u16string(),
-                    ax::mojom::NameFrom::kAttributeExplicitlyEmpty);
+  GetViewAccessibility().SetName(
+      l10n_util::GetStringUTF16(IDS_PERFORMANCE_INTERVENTION_BUTTON_ACCNAME));
+  SetTooltipText(
+      l10n_util::GetStringUTF16(IDS_PERFORMANCE_INTERVENTION_BUTTON_TOOLTIP));
   SetProperty(views::kElementIdentifierKey,
               kToolbarPerformanceInterventionButtonElementId);
   SetVisible(false);
diff --git a/chrome/browser/ui/views/performance_controls/performance_intervention_button.h b/chrome/browser/ui/views/performance_controls/performance_intervention_button.h
index 224933c..f0dd45ab 100644
--- a/chrome/browser/ui/views/performance_controls/performance_intervention_button.h
+++ b/chrome/browser/ui/views/performance_controls/performance_intervention_button.h
@@ -50,6 +50,10 @@
     return controller_.get();
   }
 
+  views::BubbleDialogModelHost* bubble_dialog_model_host() {
+    return bubble_dialog_model_host_;
+  }
+
  private:
   void OnClicked();
   void CreateBubble();
diff --git a/chrome/browser/ui/views/performance_controls/performance_intervention_interactive_ui_test.cc b/chrome/browser/ui/views/performance_controls/performance_intervention_interactive_ui_test.cc
index 6037e09..d784e09 100644
--- a/chrome/browser/ui/views/performance_controls/performance_intervention_interactive_ui_test.cc
+++ b/chrome/browser/ui/views/performance_controls/performance_intervention_interactive_ui_test.cc
@@ -8,6 +8,7 @@
 #include "base/run_loop.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
+#include "build/build_config.h"
 #include "chrome/browser/performance_manager/public/user_tuning/performance_detection_manager.h"
 #include "chrome/browser/resource_coordinator/tab_lifecycle_observer.h"
 #include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h"
@@ -21,6 +22,7 @@
 #include "chrome/browser/ui/views/performance_controls/tab_list_view.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/interaction/interaction_test_util_browser.h"
 #include "chrome/test/interaction/interactive_browser_test.h"
 #include "chrome/test/user_education/interactive_feature_promo_test.h"
@@ -31,8 +33,13 @@
 #include "content/public/test/browser_test.h"
 #include "net/dns/mock_host_resolver.h"
 #include "ui/base/interaction/interaction_test_util.h"
+#include "ui/base/ozone_buildflags.h"
+#include "ui/events/base_event_utils.h"
 #include "ui/gfx/animation/animation_test_api.h"
+#include "ui/views/bubble/bubble_dialog_model_host.h"
 #include "ui/views/interaction/interaction_test_util_views.h"
+#include "ui/views/test/button_test_api.h"
+#include "ui/views/test/widget_test.h"
 #include "ui/views/view.h"
 
 namespace {
@@ -101,9 +108,10 @@
   }
 
   std::vector<resource_attribution::PageContext> GetPageContextForTabs(
-      const std::vector<int>& tab_indices) {
+      const std::vector<int>& tab_indices,
+      Browser* browser) {
     std::vector<resource_attribution::PageContext> page_contexts;
-    TabStripModel* const tab_strip_model = browser()->tab_strip_model();
+    TabStripModel* const tab_strip_model = browser->tab_strip_model();
     for (int index : tab_indices) {
       content::WebContents* const web_contents =
           tab_strip_model->GetWebContentsAt(index);
@@ -116,18 +124,16 @@
     return page_contexts;
   }
 
+  void NotifyActionableTabListChange(const std::vector<int>& tab_indices,
+                                     Browser* browser) {
+    performance_manager::user_tuning::PerformanceDetectionManager::GetInstance()
+        ->NotifyActionableTabObserversForTesting(
+            PerformanceDetectionManager::ResourceType::kCpu,
+            GetPageContextForTabs(tab_indices, browser));
+  }
+
   auto TriggerOnActionableTabListChange(const std::vector<int>& tab_indices) {
-    return Do([&]() {
-      BrowserView* const browser_view =
-          BrowserView::GetBrowserViewForBrowser(browser());
-      PerformanceInterventionButtonController* const controller =
-          browser_view->toolbar()
-              ->performance_intervention_button()
-              ->controller();
-      controller->OnActionableTabListChanged(
-          PerformanceDetectionManager::ResourceType::kCpu,
-          GetPageContextForTabs(tab_indices));
-    });
+    return Do([&]() { NotifyActionableTabListChange(tab_indices, browser()); });
   }
 
   auto CloseTab(int index) {
@@ -402,6 +408,115 @@
       CheckTabDiscardStatus(1, false), CheckTabDiscardStatus(2, true));
 }
 
+#if !(BUILDFLAG(IS_LINUX) && BUILDFLAG(IS_OZONE_WAYLAND))
+// TODO(crbug.com/40863331): Linux Wayland doesn't support window activation
+IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
+                       UiShowsOnlyOnActiveWindow) {
+  // Create two browser windows with tabs and ensure the second browser window
+  // is active
+  Browser* const first_browser = browser();
+  ASSERT_TRUE(AddTabAtIndexToBrowser(first_browser, 0, GetURL("a.com"),
+                                     ui::PageTransition::PAGE_TRANSITION_LINK));
+  ASSERT_TRUE(AddTabAtIndexToBrowser(first_browser, 1, GetURL("b.com"),
+                                     ui::PageTransition::PAGE_TRANSITION_LINK));
+  Browser* const second_browser = CreateBrowser(first_browser->profile());
+  ASSERT_TRUE(AddTabAtIndexToBrowser(second_browser, 0, GetURL("c.com"),
+                                     ui::PageTransition::PAGE_TRANSITION_LINK));
+  BrowserWindow* const first_browser_window = first_browser->window();
+  BrowserWindow* const second_browser_window = second_browser->window();
+  second_browser_window->Activate();
+  ASSERT_TRUE(second_browser_window->IsActive());
+  ASSERT_FALSE(first_browser_window->IsActive());
+
+  ToolbarButton* const first_button =
+      BrowserView::GetBrowserViewForBrowser(first_browser)
+          ->toolbar()
+          ->performance_intervention_button();
+  ToolbarButton* const second_button =
+      BrowserView::GetBrowserViewForBrowser(second_browser)
+          ->toolbar()
+          ->performance_intervention_button();
+  ASSERT_FALSE(first_button->GetVisible());
+  ASSERT_FALSE(second_button->GetVisible());
+
+  // Second browser window should show the performance intervention button since
+  // it is the active browser.
+  NotifyActionableTabListChange({0, 1}, first_browser);
+  EXPECT_FALSE(first_button->GetVisible());
+  EXPECT_TRUE(second_button->GetVisible());
+
+  // Switching the active browser to the first browser and triggering the
+  // performance detection manager shouldn't cause the UI to show on the first
+  // browser since we already showed the notification for the day.
+  ui_test_utils::BrowserActivationWaiter first_browser_waiter(first_browser);
+  first_browser_window->Activate();
+  first_browser_waiter.WaitForActivation();
+  ASSERT_FALSE(second_browser_window->IsActive());
+  ASSERT_TRUE(first_browser_window->IsActive());
+  NotifyActionableTabListChange({0}, first_browser);
+  EXPECT_FALSE(first_button->GetVisible());
+  EXPECT_TRUE(second_button->GetVisible());
+}
+
+// The performance intervention toolbar button should hide when it is notified
+// that there is no longer any actionable tabs even though the button is being
+// shown on a non-active window.
+IN_PROC_BROWSER_TEST_F(PerformanceInterventionInteractiveTest,
+                       NonactiveInterventionButtonHides) {
+  Browser* const first_browser = browser();
+  ASSERT_TRUE(AddTabAtIndexToBrowser(first_browser, 0, GetURL("a.com"),
+                                     ui::PageTransition::PAGE_TRANSITION_LINK));
+  ASSERT_TRUE(AddTabAtIndexToBrowser(first_browser, 1, GetURL("b.com"),
+                                     ui::PageTransition::PAGE_TRANSITION_LINK));
+  Browser* const second_browser = CreateBrowser(first_browser->profile());
+  ASSERT_TRUE(AddTabAtIndexToBrowser(second_browser, 0, GetURL("c.com"),
+                                     ui::PageTransition::PAGE_TRANSITION_LINK));
+  BrowserWindow* const first_browser_window = first_browser->window();
+  BrowserWindow* const second_browser_window = second_browser->window();
+  second_browser_window->Activate();
+  ASSERT_TRUE(second_browser_window->IsActive());
+
+  // Show the intervention button on the second browser window.
+  NotifyActionableTabListChange({0, 1}, first_browser);
+  PerformanceInterventionButton* const intervention_button =
+      BrowserView::GetBrowserViewForBrowser(second_browser)
+          ->toolbar()
+          ->performance_intervention_button();
+  EXPECT_TRUE(intervention_button->GetVisible());
+  EXPECT_TRUE(intervention_button->IsBubbleShowing());
+
+  // Dismiss the dialog.
+  views::test::WidgetDestroyedWaiter widget_waiter(
+      intervention_button->bubble_dialog_model_host()->GetWidget());
+  ui::MouseEvent e(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
+                   ui::EventTimeForNow(), 0, 0);
+  views::test::ButtonTestApi test_api(intervention_button);
+  test_api.NotifyClick(e);
+  widget_waiter.Wait();
+  EXPECT_TRUE(intervention_button->GetVisible());
+  EXPECT_FALSE(intervention_button->IsBubbleShowing());
+
+  // Activate the first browser window.
+  ui_test_utils::BrowserActivationWaiter first_browser_waiter(first_browser);
+  first_browser_window->Activate();
+  first_browser_waiter.WaitForActivation();
+  ASSERT_FALSE(second_browser_window->IsActive());
+  ASSERT_TRUE(first_browser_window->IsActive());
+  EXPECT_TRUE(intervention_button->GetVisible());
+
+  // Triggering a non-empty actionable tab list should keep the toolbar button
+  // visible.
+  NotifyActionableTabListChange({0}, first_browser);
+  EXPECT_TRUE(intervention_button->GetVisible());
+  EXPECT_FALSE(intervention_button->IsBubbleShowing());
+
+  // Triggering an empty actionable tab list should immediately hide the
+  // intervention button even though the button is in the non-active window.
+  NotifyActionableTabListChange({}, first_browser);
+  EXPECT_FALSE(intervention_button->GetVisible());
+}
+#endif
+
 class PerformanceInterventionNonUiMetricsTest
     : public PerformanceInterventionInteractiveTest {
  public:
@@ -441,7 +556,7 @@
                         message_trigger_reason_histogram_name,
                         InterventionMessageTriggerResult::kRateLimited, 0);
                   }),
-                  TriggerOnActionableTabListChange({1, 2}), Do([&]() {
+                  TriggerOnActionableTabListChange({1}), Do([&]() {
                     // verify that metrics were recorded
                     histogram_tester.ExpectBucketCount(
                         message_trigger_reason_histogram_name,
diff --git a/chrome/browser/ui/views/side_panel/BUILD.gn b/chrome/browser/ui/views/side_panel/BUILD.gn
index b4099bf..96f2c30 100644
--- a/chrome/browser/ui/views/side_panel/BUILD.gn
+++ b/chrome/browser/ui/views/side_panel/BUILD.gn
@@ -50,22 +50,8 @@
     "performance_controls/performance_side_panel_model.h",
     "performance_controls/performance_state_observer.cc",
     "performance_controls/performance_state_observer.h",
-    "read_anything/read_anything_button_view.cc",
-    "read_anything/read_anything_button_view.h",
-    "read_anything/read_anything_container_view.cc",
-    "read_anything/read_anything_container_view.h",
-    "read_anything/read_anything_controller.cc",
-    "read_anything/read_anything_controller.h",
     "read_anything/read_anything_coordinator.cc",
     "read_anything/read_anything_coordinator.h",
-    "read_anything/read_anything_font_combobox.cc",
-    "read_anything/read_anything_font_combobox.h",
-    "read_anything/read_anything_menu_button.cc",
-    "read_anything/read_anything_menu_button.h",
-    "read_anything/read_anything_menu_model.cc",
-    "read_anything/read_anything_menu_model.h",
-    "read_anything/read_anything_model.cc",
-    "read_anything/read_anything_model.h",
     "read_anything/read_anything_side_panel_controller.cc",
     "read_anything/read_anything_side_panel_controller.h",
     "read_anything/read_anything_side_panel_controller_utils.cc",
@@ -76,10 +62,6 @@
     "read_anything/read_anything_side_panel_web_view.h",
     "read_anything/read_anything_tab_helper.cc",
     "read_anything/read_anything_tab_helper.h",
-    "read_anything/read_anything_toggle_button_view.cc",
-    "read_anything/read_anything_toggle_button_view.h",
-    "read_anything/read_anything_toolbar_view.cc",
-    "read_anything/read_anything_toolbar_view.h",
     "read_later_side_panel_web_view.cc",
     "read_later_side_panel_web_view.h",
     "reading_list/reading_list_side_panel_coordinator.cc",
diff --git a/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_browsertest.cc b/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_browsertest.cc
index 1f0d4097..651e850 100644
--- a/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_browsertest.cc
+++ b/chrome/browser/ui/views/side_panel/extensions/extension_side_panel_browsertest.cc
@@ -776,13 +776,9 @@
 // Test that calling window.close() from an extension side panel when it is
 // shown closes the side panel even if another entry is loading and will be
 // shown.
-#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
-#define MAYBE_WindowCloseCalledWhenLoading DISABLED_WindowCloseCalledWhenLoading
-#else
-#define MAYBE_WindowCloseCalledWhenLoading WindowCloseCalledWhenLoading
-#endif
+// TODO(crbug.com/347643170) Test is flaky.
 IN_PROC_BROWSER_TEST_F(ExtensionSidePanelBrowserTest,
-                       MAYBE_WindowCloseCalledWhenLoading) {
+                       DISABLED_WindowCloseCalledWhenLoading) {
   // Install an extension and show its side panel.
   scoped_refptr<const extensions::Extension> extension = LoadExtension(
       test_data_dir_.AppendASCII("api_test/side_panel/simple_default"));
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_button_view.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_button_view.cc
deleted file mode 100644
index 9027bec..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_button_view.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_button_view.h"
-
-#include <utility>
-
-#include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h"
-#include "ui/base/metadata/metadata_impl_macros.h"
-#include "ui/color/color_id.h"
-#include "ui/views/controls/button/image_button.h"
-#include "ui/views/controls/button/image_button_factory.h"
-#include "ui/views/controls/highlight_path_generator.h"
-
-ReadAnythingButtonView::ReadAnythingButtonView(
-    views::ImageButton::PressedCallback callback,
-    const std::u16string& tooltip)
-    : ImageButton(std::move(callback)) {
-  ConfigureInkDropForToolbar(this);
-  views::InstallCircleHighlightPathGenerator(this);
-  SetTooltipText(tooltip);
-}
-
-bool ReadAnythingButtonView::IsGroupFocusTraversable() const {
-  // Only the first item in the toolbar should be reachable with tab.
-  return false;
-}
-
-void ReadAnythingButtonView::UpdateIcon(const gfx::VectorIcon& icon,
-                                        int icon_size,
-                                        ui::ColorId icon_color,
-                                        ui::ColorId focus_ring_color) {
-  views::SetImageFromVectorIconWithColorId(this, icon, icon_color, icon_color,
-                                           icon_size);
-  DCHECK(views::FocusRing::Get(this));
-  views::FocusRing::Get(this)->SetColorId(focus_ring_color);
-}
-
-void ReadAnythingButtonView::Enable() {
-  SetState(views::Button::ButtonState::STATE_NORMAL);
-}
-
-void ReadAnythingButtonView::Disable() {
-  SetState(views::Button::ButtonState::STATE_DISABLED);
-}
-
-BEGIN_METADATA(ReadAnythingButtonView)
-END_METADATA
-
-ReadAnythingButtonView::~ReadAnythingButtonView() = default;
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_button_view.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_button_view.h
deleted file mode 100644
index fe77483..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_button_view.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_BUTTON_VIEW_H_
-#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_BUTTON_VIEW_H_
-
-#include <string>
-
-#include "ui/base/metadata/metadata_header_macros.h"
-#include "ui/color/color_id.h"
-#include "ui/views/controls/button/image_button.h"
-#include "ui/views/view.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingButtonView
-//
-//  A helper class for buttons in the Read Anything toolbar.
-//  This class makes image button views with padding and theming as a
-//  convenience class for the ReadAnythingToolbarView.
-//
-class ReadAnythingButtonView : public views::ImageButton {
-  METADATA_HEADER(ReadAnythingButtonView, views::ImageButton)
-
- public:
-  ReadAnythingButtonView(views::ImageButton::PressedCallback callback,
-                         const std::u16string& tooltip);
-  ReadAnythingButtonView(const ReadAnythingButtonView&) = delete;
-  ReadAnythingButtonView& operator=(const ReadAnythingButtonView&) = delete;
-  ~ReadAnythingButtonView() override;
-
-  // views::ImageButton
-  bool IsGroupFocusTraversable() const override;
-
-  void UpdateIcon(const gfx::VectorIcon& icon,
-                  int icon_size,
-                  ui::ColorId icon_color,
-                  ui::ColorId focus_ring_color);
-
-  void Enable();
-  void Disable();
-};
-
-#endif  // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_BUTTON_VIEW_H_
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.cc
deleted file mode 100644
index dab0154..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.h"
-
-#include <memory>
-#include <utility>
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_web_view.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h"
-#include "ui/accessibility/accessibility_features.h"
-#include "ui/base/metadata/metadata_impl_macros.h"
-#include "ui/views/background.h"
-#include "ui/views/controls/separator.h"
-#include "ui/views/layout/flex_layout.h"
-
-// TODO(crbug.com/40909106): Remove unused constructor when the
-// ReadAnythingLocalSidePanel flag is removed.
-ReadAnythingContainerView::ReadAnythingContainerView(
-    ReadAnythingCoordinator* coordinator,
-    std::unique_ptr<ReadAnythingToolbarView> toolbar,
-    std::unique_ptr<ReadAnythingSidePanelWebView> content)
-    : coordinator_(std::move(coordinator)) {
-  Init(std::move(toolbar), std::move(content));
-  coordinator_->AddObserver(this);
-  coordinator_->AddModelObserver(this);
-}
-
-ReadAnythingContainerView::ReadAnythingContainerView(
-    ReadAnythingSidePanelController* controller,
-    std::unique_ptr<ReadAnythingToolbarView> toolbar,
-    std::unique_ptr<ReadAnythingSidePanelWebView> content)
-    : controller_(std::move(controller)) {
-  Init(std::move(toolbar), std::move(content));
-  controller_->AddObserver(this);
-  controller_->AddModelObserver(this);
-}
-
-void ReadAnythingContainerView::Init(
-    std::unique_ptr<ReadAnythingToolbarView> toolbar,
-    std::unique_ptr<ReadAnythingSidePanelWebView> content) {
-  // Create and set a FlexLayout LayoutManager for this view, set background.
-  auto layout = std::make_unique<views::FlexLayout>();
-  layout->SetOrientation(views::LayoutOrientation::kVertical)
-      .SetMainAxisAlignment(views::LayoutAlignment::kStart)
-      .SetCrossAxisAlignment(views::LayoutAlignment::kStretch);
-
-  SetLayoutManager(std::move(layout));
-  SetBackground(
-      views::CreateThemedSolidBackground(ui::kColorPrimaryBackground));
-
-  // Set flex behavior on provided toolbar and content, and include a separator.
-  toolbar->SetProperty(
-      views::kFlexBehaviorKey,
-      views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred,
-                               views::MaximumFlexSizeRule::kScaleToMaximum)
-          .WithOrder(1));
-
-  auto separator = std::make_unique<views::Separator>();
-  separator->SetProperty(
-      views::kFlexBehaviorKey,
-      views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred,
-                               views::MaximumFlexSizeRule::kScaleToMaximum)
-          .WithOrder(2));
-  content->SetProperty(
-      views::kFlexBehaviorKey,
-      views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred,
-                               views::MaximumFlexSizeRule::kUnbounded)
-          .WithOrder(3));
-
-  // Add all views as children.
-  AddChildView(std::move(toolbar));
-  separator_ = AddChildView(std::move(separator));
-  AddChildView(std::move(content));
-}
-
-void ReadAnythingContainerView::OnReadAnythingThemeChanged(
-    const std::string& font_name,
-    double font_scale,
-    bool links_enabled,
-    bool images_enabled,
-    ui::ColorId foreground_color_id,
-    ui::ColorId background_color_id,
-    ui::ColorId separator_color_id,
-    ui::ColorId dropdown_color_id,
-    ui::ColorId selection_color_id,
-    ui::ColorId focus_ring_color_id,
-    read_anything::mojom::LineSpacing line_spacing,
-    read_anything::mojom::LetterSpacing letter_spacing) {
-  separator_->SetColorId(separator_color_id);
-}
-
-void ReadAnythingContainerView::OnCoordinatorDestroyed() {
-  // When the coordinator that created |this| is destroyed, clean up pointers.
-  coordinator_ = nullptr;
-}
-
-void ReadAnythingContainerView::OnSidePanelControllerDestroyed() {
-  // When the side panel controller that created |this| is destroyed, clean up
-  // pointers.
-  controller_ = nullptr;
-}
-
-ReadAnythingContainerView::~ReadAnythingContainerView() {
-  // If |this| is being destroyed before the associated coordinator or side
-  // panel controller, then remove |this| as an observer.
-  if (features::IsReadAnythingLocalSidePanelEnabled() && controller_) {
-    controller_->RemoveObserver(this);
-    controller_->RemoveModelObserver(this);
-  } else if (coordinator_) {
-    coordinator_->RemoveObserver(this);
-    coordinator_->RemoveModelObserver(this);
-  }
-}
-
-BEGIN_METADATA(ReadAnythingContainerView)
-END_METADATA
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.h
deleted file mode 100644
index 52025eb..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_CONTAINER_VIEW_H_
-#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_CONTAINER_VIEW_H_
-
-#include <memory>
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.h"
-#include "ui/base/metadata/metadata_header_macros.h"
-#include "ui/views/controls/separator.h"
-#include "ui/views/view.h"
-
-class ReadAnythingToolbarView;
-class ReadAnythingSidePanelWebView;
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingContainerView
-//
-//  A class that holds all of the Read Anything UI. This includes a toolbar,
-//  which is a View, and the Read Anything contents pane, which is a WebUI.
-//  This class is either created by the ReadAnythingCoordinator (when the side
-//  panel is global) or the ReadAnythingSidePanelController (when the side panel
-//  is local) and owned by the Side Panel View. It has the same lifetime as the
-//  Side Panel view.
-//
-class ReadAnythingContainerView
-    : public views::View,
-      public ReadAnythingModel::Observer,
-      public ReadAnythingCoordinator::Observer,
-      public ReadAnythingSidePanelController::Observer {
-  METADATA_HEADER(ReadAnythingContainerView, views::View)
-
- public:
-  ReadAnythingContainerView(
-      ReadAnythingCoordinator* coordinator,
-      std::unique_ptr<ReadAnythingToolbarView> toolbar,
-      std::unique_ptr<ReadAnythingSidePanelWebView> content);
-  ReadAnythingContainerView(
-      ReadAnythingSidePanelController* controller,
-      std::unique_ptr<ReadAnythingToolbarView> toolbar,
-      std::unique_ptr<ReadAnythingSidePanelWebView> content);
-  ReadAnythingContainerView(const ReadAnythingContainerView&) = delete;
-  ReadAnythingContainerView& operator=(const ReadAnythingContainerView&) =
-      delete;
-  ~ReadAnythingContainerView() override;
-
-  // ReadAnythingModel::Observer:
-  void OnReadAnythingThemeChanged(
-      const std::string& font_name,
-      double font_scale,
-      bool links_enabled,
-      bool images_enabled,
-      ui::ColorId foreground_color_id,
-      ui::ColorId background_color_id,
-      ui::ColorId separator_color_id,
-      ui::ColorId dropdown_color_id,
-      ui::ColorId selection_color_id,
-      ui::ColorId focus_ring_color_id,
-      read_anything::mojom::LineSpacing line_spacing,
-      read_anything::mojom::LetterSpacing letter_spacing) override;
-
-  // ReadAnythingCoordinator::Observer:
-  void OnCoordinatorDestroyed() override;
-  // ReadAnythingSidePanelController::Observer:
-  void OnSidePanelControllerDestroyed() override;
-
- private:
-  void Init(std::unique_ptr<ReadAnythingToolbarView> toolbar,
-            std::unique_ptr<ReadAnythingSidePanelWebView> content);
-
-  raw_ptr<ReadAnythingCoordinator> coordinator_;
-  raw_ptr<ReadAnythingSidePanelController> controller_;
-  raw_ptr<views::Separator> separator_;
-};
-#endif  // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_CONTAINER_VIEW_H_
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc
deleted file mode 100644
index 65c83e5..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h"
-
-#include <vector>
-
-#include "base/metrics/histogram_functions.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/webui/side_panel/read_anything/read_anything_prefs.h"
-#include "chrome/common/accessibility/read_anything_constants.h"
-#include "components/prefs/pref_service.h"
-#include "ui/accessibility/accessibility_features.h"
-
-// TODO(crbug.com/40909106): Remove unused constructor when the
-// ReadAnythingLocalSidePanel flag is removed.
-ReadAnythingController::ReadAnythingController(ReadAnythingModel* model,
-                                               Browser* browser)
-    : model_(model), browser_(browser) {}
-
-ReadAnythingController::ReadAnythingController(
-    ReadAnythingModel* model,
-    content::WebContents* web_contents)
-    : model_(model), web_contents_(web_contents) {}
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingFontCombobox::Delegate:
-///////////////////////////////////////////////////////////////////////////////
-
-void ReadAnythingController::OnFontChoiceChanged(int new_index) {
-  if (!model_->GetFontModel()->IsValidFontIndex(new_index)) {
-    return;
-  }
-
-  if (!features::IsReadAnythingWebUIToolbarEnabled()) {
-    base::UmaHistogramEnumeration(
-        string_constants::kSettingsChangeHistogramName,
-        ReadAnythingSettingsChange::kFontChange);
-  }
-  model_->SetSelectedFontByIndex(new_index);
-
-  GetProfile()->GetPrefs()->SetString(
-      prefs::kAccessibilityReadAnythingFontName,
-      model_->GetFontModel()->GetFontNameAt(new_index));
-}
-
-ReadAnythingFontModel* ReadAnythingController::GetFontComboboxModel() {
-  return model_->GetFontModel();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingToolbarView::Delegate:
-///////////////////////////////////////////////////////////////////////////////
-
-void ReadAnythingController::OnFontSizeChanged(bool increase) {
-  if (increase) {
-    model_->IncreaseTextSize();
-  } else {
-    model_->DecreaseTextSize();
-  }
-
-  if (!features::IsReadAnythingWebUIToolbarEnabled()) {
-    base::UmaHistogramEnumeration(
-        string_constants::kSettingsChangeHistogramName,
-        ReadAnythingSettingsChange::kFontSizeChange);
-  }
-  GetProfile()->GetPrefs()->SetDouble(
-      prefs::kAccessibilityReadAnythingFontScale, model_->GetFontScale());
-}
-
-void ReadAnythingController::OnColorsChanged(int new_index) {
-  PrefService* prefs = GetProfile()->GetPrefs();
-  if (!model_->GetColorsModel()->IsValidIndex(new_index) ||
-      prefs->GetInteger(prefs::kAccessibilityReadAnythingColorInfo) ==
-          new_index) {
-    return;
-  }
-
-  if (!features::IsReadAnythingWebUIToolbarEnabled()) {
-    base::UmaHistogramEnumeration(
-        string_constants::kSettingsChangeHistogramName,
-        ReadAnythingSettingsChange::kThemeChange);
-  }
-  model_->SetSelectedColorsByIndex(new_index);
-
-  prefs->SetInteger(prefs::kAccessibilityReadAnythingColorInfo, new_index);
-}
-
-ReadAnythingMenuModel* ReadAnythingController::GetColorsModel() {
-  return model_->GetColorsModel();
-}
-
-void ReadAnythingController::OnLineSpacingChanged(int new_index) {
-  if (!model_->GetLineSpacingModel()->IsValidIndex(new_index)) {
-    return;
-  }
-
-  if (!features::IsReadAnythingWebUIToolbarEnabled()) {
-    base::UmaHistogramEnumeration(
-        string_constants::kSettingsChangeHistogramName,
-        ReadAnythingSettingsChange::kLineHeightChange);
-  }
-  model_->SetSelectedLineSpacingByIndex(new_index);
-
-  // Saved preferences correspond to LineSpacing. However, since it contains a
-  // deprecated value, the drop-down indices don't correspond exactly.
-  LineSpacing line_spacing =
-      model_->GetLineSpacingModel()->GetLineSpacingAt(new_index);
-  GetProfile()->GetPrefs()->SetInteger(
-      prefs::kAccessibilityReadAnythingLineSpacing,
-      static_cast<size_t>(line_spacing));
-}
-
-ReadAnythingMenuModel* ReadAnythingController::GetLineSpacingModel() {
-  return model_->GetLineSpacingModel();
-}
-
-void ReadAnythingController::OnLetterSpacingChanged(int new_index) {
-  if (!model_->GetLetterSpacingModel()->IsValidIndex(new_index)) {
-    return;
-  }
-
-  if (!features::IsReadAnythingWebUIToolbarEnabled()) {
-    base::UmaHistogramEnumeration(
-        string_constants::kSettingsChangeHistogramName,
-        ReadAnythingSettingsChange::kLetterSpacingChange);
-  }
-  model_->SetSelectedLetterSpacingByIndex(new_index);
-
-  // Saved preferences correspond to LetterSpacing. However, since it contains a
-  // deprecated value, the drop-down indices don't correspond exactly.
-  LetterSpacing letter_spacing =
-      model_->GetLetterSpacingModel()->GetLetterSpacingAt(new_index);
-  GetProfile()->GetPrefs()->SetInteger(
-      prefs::kAccessibilityReadAnythingLetterSpacing,
-      static_cast<size_t>(letter_spacing));
-}
-
-void ReadAnythingController::OnLinksEnabledChanged(bool is_enabled) {
-  model_->SetLinksEnabled(is_enabled);
-
-  PrefService* prefs = browser_->profile()->GetPrefs();
-  prefs->SetBoolean(prefs::kAccessibilityReadAnythingLinksEnabled, is_enabled);
-}
-
-bool ReadAnythingController::GetLinksEnabled() {
-  return model_->GetLinksEnabled();
-}
-
-void ReadAnythingController::OnImagesEnabledChanged(bool is_enabled) {
-  model_->SetImagesEnabled(is_enabled);
-
-  PrefService* prefs = browser_->profile()->GetPrefs();
-  prefs->SetBoolean(prefs::kAccessibilityReadAnythingImagesEnabled, is_enabled);
-}
-
-bool ReadAnythingController::GetImagesEnabled() {
-  return model_->GetImagesEnabled();
-}
-
-ReadAnythingMenuModel* ReadAnythingController::GetLetterSpacingModel() {
-  return model_->GetLetterSpacingModel();
-}
-
-void ReadAnythingController::OnSystemThemeChanged() {
-  model_->OnSystemThemeChanged();
-}
-
-Profile* ReadAnythingController::GetProfile() {
-  if (features::IsReadAnythingLocalSidePanelEnabled() && web_contents_) {
-    return Profile::FromBrowserContext(web_contents_->GetBrowserContext());
-  } else {
-    CHECK(browser_);
-    return browser_->profile();
-  }
-}
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h
deleted file mode 100644
index 3ea34f907..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_CONTROLLER_H_
-#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_CONTROLLER_H_
-
-#include "base/memory/raw_ptr.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h"
-#include "ui/base/models/combobox_model.h"
-
-class Browser;
-
-namespace content {
-class WebContents;
-}  // namespace content
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingController
-//
-//  A class that controls the Read Anything feature. This class does all of the
-//  business logic of this feature and updates the model.
-//  The controller is meant to be internal to the Read Anything feature and
-//  classes outside this feature should not be making calls to it. The
-//  coordinator or side panel controller is the external-facing API.
-//  When the side panel entry is global, this class is owned by the
-//  ReadAnythingCoordinator and has the same lifetime as the browser.
-//  When the side panel entry is local. this class is owned by the
-//  ReadAnythingSidePanelController and has the same lifetime as the associated
-//  web contents.
-//
-class ReadAnythingController : public ReadAnythingToolbarView::Delegate,
-                               public ReadAnythingFontCombobox::Delegate {
- public:
-  ReadAnythingController(ReadAnythingModel* model, Browser* browser);
-  ReadAnythingController(ReadAnythingModel* model,
-                         content::WebContents* web_contents);
-  ReadAnythingController(const ReadAnythingController&) = delete;
-  ReadAnythingController& operator=(const ReadAnythingController&) = delete;
-  virtual ~ReadAnythingController() = default;
-
- private:
-  friend class ReadAnythingControllerTest;
-
-  // ReadAnythingFontCombobox::Delegate:
-  void OnFontChoiceChanged(int new_index) override;
-  ReadAnythingFontModel* GetFontComboboxModel() override;
-
-  // ReadAnythingToolbarView::Delegate:
-  void OnFontSizeChanged(bool increase) override;
-  void OnColorsChanged(int new_index) override;
-  ReadAnythingMenuModel* GetColorsModel() override;
-  void OnLineSpacingChanged(int new_index) override;
-  ReadAnythingMenuModel* GetLineSpacingModel() override;
-  void OnLetterSpacingChanged(int new_index) override;
-  ReadAnythingMenuModel* GetLetterSpacingModel() override;
-  void OnSystemThemeChanged() override;
-  void OnLinksEnabledChanged(bool is_enabled) override;
-  bool GetLinksEnabled() override;
-  void OnImagesEnabledChanged(bool is_enabled) override;
-  bool GetImagesEnabled() override;
-
-  Profile* GetProfile();
-
-  const raw_ptr<ReadAnythingModel> model_;
-  const raw_ptr<content::WebContents> web_contents_;
-
-  // Set when the ReadAnythingController is owned by a ReadAnythingCoordinator.
-  // ReadAnythingCoordinator is a browser user data, so this pointer is always
-  // valid.
-  raw_ptr<Browser, DanglingUntriaged> browser_;
-};
-#endif  // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_CONTROLLER_H_
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller_unittest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller_unittest.cc
deleted file mode 100644
index c58ad96..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_controller_unittest.cc
+++ /dev/null
@@ -1,514 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h"
-
-#include <memory>
-
-#include "base/test/gtest_util.h"
-#include "chrome/browser/ui/views/frame/test_with_browser_view.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h"
-#include "chrome/browser/ui/webui/side_panel/read_anything/read_anything_prefs.h"
-#include "chrome/common/accessibility/read_anything_constants.h"
-#include "chrome/test/base/browser_with_test_window_test.h"
-#include "chrome/test/base/testing_profile.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "ui/accessibility/accessibility_features.h"
-
-using testing::_;
-class MockReadAnythingModelObserver : public ReadAnythingModel::Observer {
- public:
-  MOCK_METHOD(void,
-              OnReadAnythingThemeChanged,
-              (const std::string& font_name,
-               double font_scale,
-               bool links_enabled,
-               bool images_enabled,
-               ui::ColorId foreground_color_id,
-               ui::ColorId background_color_id,
-               ui::ColorId separator_color_id,
-               ui::ColorId dropdown_color_id,
-               ui::ColorId selection_color_id,
-               ui::ColorId focus_ring_color_id,
-               read_anything::mojom::LineSpacing line_spacing,
-               read_anything::mojom::LetterSpacing letter_spacing),
-              (override));
-};
-
-class ReadAnythingControllerTest : public TestWithBrowserView {
- public:
-  void SetUp() override {
-    scoped_feature_list_.InitWithFeatures(
-        {features::kReadAnythingLocalSidePanel,
-         features::kReadAnythingWebUIToolbar},
-        {});
-    TestWithBrowserView::SetUp();
-
-    model_ = std::make_unique<ReadAnythingModel>();
-    controller_ =
-        std::make_unique<ReadAnythingController>(model_.get(), browser());
-    auto* web_contents_ = browser()->OpenURL(
-        content::OpenURLParams(GURL("https://google.com"), content::Referrer(),
-                               WindowOpenDisposition::CURRENT_TAB,
-                               ui::PAGE_TRANSITION_TYPED, false),
-        /*navigation_handle_callback=*/{});
-    controller_for_web_contents_ =
-        std::make_unique<ReadAnythingController>(model_.get(), web_contents_);
-
-    // Reset prefs to default values for test.
-    browser()->profile()->GetPrefs()->SetString(
-        prefs::kAccessibilityReadAnythingFontName,
-        string_constants::kReadAnythingPlaceholderFontName);
-    browser()->profile()->GetPrefs()->SetDouble(
-        prefs::kAccessibilityReadAnythingFontScale,
-        kReadAnythingDefaultFontScale);
-    browser()->profile()->GetPrefs()->SetInteger(
-        prefs::kAccessibilityReadAnythingColorInfo,
-        static_cast<int>(read_anything::mojom::Colors::kDefaultValue));
-    browser()->profile()->GetPrefs()->SetInteger(
-        prefs::kAccessibilityReadAnythingLineSpacing,
-        static_cast<int>(read_anything::mojom::LineSpacing::kDefaultValue));
-    browser()->profile()->GetPrefs()->SetInteger(
-        prefs::kAccessibilityReadAnythingLetterSpacing,
-        static_cast<int>(read_anything::mojom::LetterSpacing::kDefaultValue));
-    browser()->profile()->GetPrefs()->SetBoolean(
-        prefs::kAccessibilityReadAnythingLinksEnabled,
-        kReadAnythingDefaultLinksEnabled);
-    browser()->profile()->GetPrefs()->SetBoolean(
-        prefs::kAccessibilityReadAnythingImagesEnabled,
-        kReadAnythingDefaultImagesEnabled);
-  }
-
-  void TearDown() override {
-    controller_for_web_contents_ = nullptr;
-    controller_ = nullptr;
-    TestWithBrowserView::TearDown();
-  }
-
-  void MockOnFontChoiceChanged(int index) {
-    controller_->OnFontChoiceChanged(index);
-  }
-
-  void MockControllerForWebContentsOnFontChoiceChanged(int index) {
-    controller_for_web_contents_->OnFontChoiceChanged(index);
-  }
-
-  void MockOnFontSizeChanged(bool increase) {
-    controller_->OnFontSizeChanged(increase);
-  }
-
-  void MockControllerForWebContentsOnFontSizeChanged(bool increase) {
-    controller_for_web_contents_->OnFontSizeChanged(increase);
-  }
-
-  void MockOnColorsChanged(int index) { controller_->OnColorsChanged(index); }
-
-  void MockControllerForWebContentsOnColorsChanged(int index) {
-    controller_for_web_contents_->OnColorsChanged(index);
-  }
-
-  void MockOnLineSpacingChanged(int index) {
-    controller_->OnLineSpacingChanged(index);
-  }
-
-  void MockControllerForWebContentsOnLineSpacingChanged(int index) {
-    controller_for_web_contents_->OnLineSpacingChanged(index);
-  }
-
-  void MockOnLetterSpacingChanged(int index) {
-    controller_->OnLetterSpacingChanged(index);
-  }
-
-  void MockOnLinksEnabledChanged(bool enabled) {
-    controller_->OnLinksEnabledChanged(enabled);
-  }
-
-  void MockControllerForWebContentsOnLetterSpacingChanged(int index) {
-    controller_for_web_contents_->OnLetterSpacingChanged(index);
-  }
-
-  void MockModelInit(std::string language,
-                     std::string font_name,
-                     double font_scale,
-                     bool links_enabled,
-                     bool images_enabled,
-                     read_anything::mojom::Colors colors,
-                     read_anything::mojom::LineSpacing line_spacing,
-                     read_anything::mojom::LetterSpacing letter_spacing) {
-    model_->Init(language, font_name, font_scale, links_enabled, images_enabled,
-                 colors, line_spacing, letter_spacing);
-  }
-
-  std::string GetPrefFontName() {
-    return browser()->profile()->GetPrefs()->GetString(
-        prefs::kAccessibilityReadAnythingFontName);
-  }
-
-  double GetPrefFontScale() {
-    return browser()->profile()->GetPrefs()->GetDouble(
-        prefs::kAccessibilityReadAnythingFontScale);
-  }
-
-  int GetPrefsColors() {
-    return browser()->profile()->GetPrefs()->GetInteger(
-        prefs::kAccessibilityReadAnythingColorInfo);
-  }
-
-  int GetPrefsLineSpacing() {
-    return browser()->profile()->GetPrefs()->GetInteger(
-        prefs::kAccessibilityReadAnythingLineSpacing);
-  }
-
-  int GetPrefsLetterSpacing() {
-    return browser()->profile()->GetPrefs()->GetInteger(
-        prefs::kAccessibilityReadAnythingLetterSpacing);
-  }
-
-  bool GetPrefsLinksEnabled() {
-    return browser()->profile()->GetPrefs()->GetBoolean(
-        prefs::kAccessibilityReadAnythingLinksEnabled);
-  }
-
-  TabStripModel* GetTabStripModel() { return browser()->tab_strip_model(); }
-
- protected:
-  std::unique_ptr<ReadAnythingModel> model_;
-  std::unique_ptr<ReadAnythingController> controller_;
-  MockReadAnythingModelObserver model_observer_;
-
-  // Variables for the controller created using web contents;
-  std::unique_ptr<ReadAnythingController> controller_for_web_contents_;
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-TEST_F(ReadAnythingControllerTest, ValidIndexUpdatesFontNamePref) {
-  std::string expected_font_name = "Comic Neue";
-
-  // Initialize model with English so all fonts are available choices.
-  std::string font_name;
-  std::string language = "en";
-  MockModelInit(language, font_name, 4.5, true, false,
-                read_anything::mojom::Colors::kDefaultValue,
-                read_anything::mojom::LineSpacing::kDefaultValue,
-                read_anything::mojom::LetterSpacing::kDefaultValue);
-  MockOnFontChoiceChanged(3);
-
-  EXPECT_EQ(expected_font_name, GetPrefFontName());
-}
-
-TEST_F(ReadAnythingControllerTest,
-       ControllerForWebContentsValidIndexUpdatesFontNamePref) {
-  std::string expected_font_name = "Comic Neue";
-
-  // Initialize model with English so all fonts are available choices.
-  std::string font_name;
-  std::string language = "en";
-  MockModelInit(language, font_name, 4.5, true, false,
-                read_anything::mojom::Colors::kDefaultValue,
-                read_anything::mojom::LineSpacing::kDefaultValue,
-                read_anything::mojom::LetterSpacing::kDefaultValue);
-  MockControllerForWebContentsOnFontChoiceChanged(3);
-
-  EXPECT_EQ(expected_font_name, GetPrefFontName());
-}
-
-TEST_F(ReadAnythingControllerTest, OnFontSizeChangedIncreaseUpdatesPref) {
-  EXPECT_NEAR(GetPrefFontScale(), 1.0, 0.01);
-
-  MockOnFontSizeChanged(true);
-
-  EXPECT_NEAR(GetPrefFontScale(), 1.25, 0.01);
-}
-
-TEST_F(ReadAnythingControllerTest,
-       ControllerForWebContentsOnFontSizeChangedIncreaseUpdatesPref) {
-  EXPECT_NEAR(GetPrefFontScale(), 1.0, 0.01);
-
-  MockControllerForWebContentsOnFontSizeChanged(true);
-
-  EXPECT_NEAR(GetPrefFontScale(), 1.25, 0.01);
-}
-
-TEST_F(ReadAnythingControllerTest, OnFontSizeChangedDecreasePref) {
-  EXPECT_NEAR(GetPrefFontScale(), 1.0, 0.01);
-
-  MockOnFontSizeChanged(false);
-
-  EXPECT_NEAR(GetPrefFontScale(), 0.75, 0.01);
-}
-
-TEST_F(ReadAnythingControllerTest,
-       ControllerForWebContentsOnFontSizeChangedDecreasePref) {
-  EXPECT_NEAR(GetPrefFontScale(), 1.0, 0.01);
-
-  MockControllerForWebContentsOnFontSizeChanged(false);
-
-  EXPECT_NEAR(GetPrefFontScale(), 0.75, 0.01);
-}
-
-TEST_F(ReadAnythingControllerTest, OnFontSizeChangedHonorsMax) {
-  EXPECT_NEAR(GetPrefFontScale(), 1.0, 0.01);
-
-  std::string font_name;
-  std::string language = "en";
-  MockModelInit(language, font_name, 4.5, true, false,
-                read_anything::mojom::Colors::kDefaultValue,
-                read_anything::mojom::LineSpacing::kDefaultValue,
-                read_anything::mojom::LetterSpacing::kDefaultValue);
-
-  MockOnFontSizeChanged(true);
-
-  EXPECT_NEAR(GetPrefFontScale(), 4.5, 0.01);
-}
-
-TEST_F(ReadAnythingControllerTest,
-       ControllerForWebContentsOnFontSizeChangedHonorsMax) {
-  EXPECT_NEAR(GetPrefFontScale(), 1.0, 0.01);
-
-  std::string font_name;
-  std::string language = "en";
-  MockModelInit(language, font_name, 4.5, true, false,
-                read_anything::mojom::Colors::kDefaultValue,
-                read_anything::mojom::LineSpacing::kDefaultValue,
-                read_anything::mojom::LetterSpacing::kDefaultValue);
-
-  MockControllerForWebContentsOnFontSizeChanged(true);
-
-  EXPECT_NEAR(GetPrefFontScale(), 4.5, 0.01);
-}
-
-TEST_F(ReadAnythingControllerTest, OnFontSizeChangedHonorsMin) {
-  EXPECT_NEAR(GetPrefFontScale(), 1.0, 0.01);
-
-  std::string font_name;
-  std::string language = "en";
-  MockModelInit(language, font_name, 0.5, true, false,
-                read_anything::mojom::Colors::kDefaultValue,
-                read_anything::mojom::LineSpacing::kDefaultValue,
-                read_anything::mojom::LetterSpacing::kDefaultValue);
-
-  MockOnFontSizeChanged(false);
-
-  EXPECT_NEAR(GetPrefFontScale(), 0.5, 0.01);
-}
-
-TEST_F(ReadAnythingControllerTest,
-       ControllerForWebContentsOnFontSizeChangedHonorsMin) {
-  EXPECT_NEAR(GetPrefFontScale(), 1.0, 0.01);
-
-  std::string font_name;
-  std::string language = "en";
-  MockModelInit(language, font_name, 0.5, true, false,
-                read_anything::mojom::Colors::kDefaultValue,
-                read_anything::mojom::LineSpacing::kDefaultValue,
-                read_anything::mojom::LetterSpacing::kDefaultValue);
-
-  MockControllerForWebContentsOnFontSizeChanged(false);
-
-  EXPECT_NEAR(GetPrefFontScale(), 0.5, 0.01);
-}
-
-TEST_F(ReadAnythingControllerTest, OnColorsChangedUpdatesPref) {
-  EXPECT_EQ(GetPrefsColors(), 0);
-
-  MockOnColorsChanged(static_cast<int>(read_anything::mojom::Colors::kYellow));
-
-  EXPECT_EQ(GetPrefsColors(), 3);
-}
-
-TEST_F(ReadAnythingControllerTest,
-       ControllerForWebContentsOnColorsChangedUpdatesPref) {
-  EXPECT_EQ(GetPrefsColors(), 0);
-
-  MockControllerForWebContentsOnColorsChanged(
-      static_cast<int>(read_anything::mojom::Colors::kYellow));
-
-  EXPECT_EQ(GetPrefsColors(), 3);
-}
-
-TEST_F(ReadAnythingControllerTest, OnLineSpacingChangedUpdatesPref) {
-  EXPECT_EQ(GetPrefsLineSpacing(), 2);
-
-  // Subtract one to account for the deprecated value (kLooseDeprecated), since
-  // this is the index in the drop-down and not the enum value.
-  MockOnLineSpacingChanged(
-      static_cast<int>(read_anything::mojom::LineSpacing::kStandard) - 1);
-
-  EXPECT_EQ(GetPrefsLineSpacing(), 1);
-}
-
-TEST_F(ReadAnythingControllerTest,
-       ControllerForWebContentsOnLineSpacingChangedUpdatesPref) {
-  EXPECT_EQ(GetPrefsLineSpacing(), 2);
-
-  // Subtract one to account for the deprecated value (kLooseDeprecated), since
-  // this is the index in the drop-down and not the enum value.
-  MockControllerForWebContentsOnLineSpacingChanged(
-      static_cast<int>(read_anything::mojom::LineSpacing::kStandard) - 1);
-
-  EXPECT_EQ(GetPrefsLineSpacing(), 1);
-}
-
-TEST_F(ReadAnythingControllerTest,
-       OnLineSpacingChangedValidInputAtTopBoundary) {
-  EXPECT_EQ(GetPrefsLineSpacing(), 2);
-
-  // Subtract one to account for the deprecated value (kLooseDeprecated), since
-  // this is the index in the drop-down and not the enum value.
-  MockOnLineSpacingChanged(
-      static_cast<int>(read_anything::mojom::LineSpacing::kVeryLoose) - 1);
-
-  EXPECT_EQ(GetPrefsLineSpacing(), 3);
-}
-
-TEST_F(ReadAnythingControllerTest,
-       ControllerForWebContentsOnLineSpacingChangedValidInputAtTopBoundary) {
-  EXPECT_EQ(GetPrefsLineSpacing(), 2);
-
-  // Subtract one to account for the deprecated value (kLooseDeprecated), since
-  // this is the index in the drop-down and not the enum value.
-  MockControllerForWebContentsOnLineSpacingChanged(
-      static_cast<int>(read_anything::mojom::LineSpacing::kVeryLoose) - 1);
-
-  EXPECT_EQ(GetPrefsLineSpacing(), 3);
-}
-
-TEST_F(ReadAnythingControllerTest,
-       OnLineSpacingChangedInvalidInputAtTopBoundary) {
-  EXPECT_EQ(GetPrefsLineSpacing(), 2);
-
-  // Subtract one to account for the deprecated value (kLooseDeprecated), since
-  // this is the index in the drop-down and not the enum value.
-  MockOnLineSpacingChanged(
-      static_cast<int>(read_anything::mojom::LineSpacing::kVeryLoose));
-
-  EXPECT_EQ(GetPrefsLineSpacing(), 2);
-}
-
-TEST_F(ReadAnythingControllerTest,
-       ControllerForWebContentsOnLineSpacingChangedInvalidInputAtTopBoundary) {
-  EXPECT_EQ(GetPrefsLineSpacing(), 2);
-
-  // Subtract one to account for the deprecated value (kLooseDeprecated), since
-  // this is the index in the drop-down and not the enum value.
-  MockControllerForWebContentsOnLineSpacingChanged(
-      static_cast<int>(read_anything::mojom::LineSpacing::kVeryLoose));
-
-  EXPECT_EQ(GetPrefsLineSpacing(), 2);
-}
-
-TEST_F(ReadAnythingControllerTest, OnLineSpacingChangedInvalidInput) {
-  EXPECT_EQ(GetPrefsLineSpacing(), 2);
-
-  MockOnLineSpacingChanged(10);
-
-  EXPECT_EQ(GetPrefsLineSpacing(), 2);
-}
-
-TEST_F(ReadAnythingControllerTest,
-       ControllerForWebContentsOnLineSpacingChangedInvalidInput) {
-  EXPECT_EQ(GetPrefsLineSpacing(), 2);
-
-  MockControllerForWebContentsOnLineSpacingChanged(10);
-
-  EXPECT_EQ(GetPrefsLineSpacing(), 2);
-}
-
-TEST_F(ReadAnythingControllerTest, OnLetterSpacingChangedUpdatesPref) {
-  EXPECT_EQ(GetPrefsLetterSpacing(), 1);
-
-  // Subtract one to account for the deprecated value (kLooseDeprecated), since
-  // this is the index in the drop-down and not the enum value.
-  MockOnLetterSpacingChanged(
-      static_cast<int>(read_anything::mojom::LetterSpacing::kWide) - 1);
-
-  EXPECT_EQ(GetPrefsLetterSpacing(), 2);
-}
-
-TEST_F(ReadAnythingControllerTest,
-       ControllerForWebContentsOnLetterSpacingChangedUpdatesPref) {
-  EXPECT_EQ(GetPrefsLetterSpacing(), 1);
-
-  // Subtract one to account for the deprecated value (kLooseDeprecated), since
-  // this is the index in the drop-down and not the enum value.
-  MockControllerForWebContentsOnLetterSpacingChanged(
-      static_cast<int>(read_anything::mojom::LetterSpacing::kWide) - 1);
-
-  EXPECT_EQ(GetPrefsLetterSpacing(), 2);
-}
-
-TEST_F(ReadAnythingControllerTest,
-       OnLetterSpacingChangedValidInputAtTopBoundary) {
-  EXPECT_EQ(GetPrefsLetterSpacing(), 1);
-
-  // Subtract one to account for the deprecated value (kLooseDeprecated), since
-  // this is the index in the drop-down and not the enum value.
-  MockOnLetterSpacingChanged(
-      static_cast<int>(read_anything::mojom::LetterSpacing::kVeryWide) - 1);
-
-  EXPECT_EQ(GetPrefsLetterSpacing(), 3);
-}
-
-TEST_F(ReadAnythingControllerTest,
-       ControllerForWebContentsOnLetterSpacingChangedValidInputAtTopBoundary) {
-  EXPECT_EQ(GetPrefsLetterSpacing(), 1);
-
-  // Subtract one to account for the deprecated value (kLooseDeprecated), since
-  // this is the index in the drop-down and not the enum value.
-  MockControllerForWebContentsOnLetterSpacingChanged(
-      static_cast<int>(read_anything::mojom::LetterSpacing::kVeryWide) - 1);
-
-  EXPECT_EQ(GetPrefsLetterSpacing(), 3);
-}
-
-TEST_F(ReadAnythingControllerTest,
-       OnLetterSpacingChangedInvalidInputAtTopBoundary) {
-  EXPECT_EQ(GetPrefsLetterSpacing(), 1);
-
-  // Since this is the index in the drop-down and not the enum value, the max
-  // enum value is one larger than the max index value in the drop down.
-  MockOnLetterSpacingChanged(
-      static_cast<int>(read_anything::mojom::LetterSpacing::kVeryWide));
-
-  EXPECT_EQ(GetPrefsLetterSpacing(), 1);
-}
-
-TEST_F(
-    ReadAnythingControllerTest,
-    ControllerForWebContentsOnLetterSpacingChangedInvalidInputAtTopBoundary) {
-  EXPECT_EQ(GetPrefsLetterSpacing(), 1);
-
-  // Since this is the index in the drop-down and not the enum value, the max
-  // enum value is one larger than the max index value in the drop down.
-  MockControllerForWebContentsOnLetterSpacingChanged(
-      static_cast<int>(read_anything::mojom::LetterSpacing::kVeryWide));
-
-  EXPECT_EQ(GetPrefsLetterSpacing(), 1);
-}
-
-TEST_F(ReadAnythingControllerTest, OnLetterSpacingChangedInvalidInput) {
-  EXPECT_EQ(GetPrefsLetterSpacing(), 1);
-
-  MockOnLetterSpacingChanged(10);
-
-  EXPECT_EQ(GetPrefsLetterSpacing(), 1);
-}
-
-TEST_F(ReadAnythingControllerTest,
-       ControllerForWebContentsOnLetterSpacingChangedInvalidInput) {
-  EXPECT_EQ(GetPrefsLetterSpacing(), 1);
-
-  MockControllerForWebContentsOnLetterSpacingChanged(10);
-
-  EXPECT_EQ(GetPrefsLetterSpacing(), 1);
-}
-
-TEST_F(ReadAnythingControllerTest, OnLinksEnabledChangedUpdatesPref) {
-  EXPECT_EQ(GetPrefsLinksEnabled(), true);
-
-  MockOnLinksEnabledChanged(false);
-
-  EXPECT_EQ(GetPrefsLinksEnabled(), false);
-}
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc
index f77a0c6..f0d98523 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc
@@ -15,18 +15,14 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/accessibility/embedded_a11y_extension_loader.h"
-#include "chrome/browser/language/language_model_manager_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window/public/browser_window_features.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller_utils.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_web_view.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_tab_helper.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_registry.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_web_ui_view.h"
@@ -35,9 +31,6 @@
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/feature_engagement/public/feature_constants.h"
-#include "components/language/core/browser/language_model.h"
-#include "components/language/core/browser/language_model_manager.h"
-#include "components/language/core/common/locale_util.h"
 #include "ui/accessibility/accessibility_features.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -82,13 +75,6 @@
                    base::BindRepeating(
                        &ReadAnythingCoordinator::OnTabChangeDelayComplete,
                        base::Unretained(this))) {
-  // Create the model and initialize it with user prefs (if present).
-  model_ = std::make_unique<ReadAnythingModel>();
-  InitModelWithUserPrefs();
-
-  // Create the controller.
-  controller_ = std::make_unique<ReadAnythingController>(model_.get(), browser);
-
   browser->tab_strip_model()->AddObserver(this);
   Observe(GetActiveWebContents());
   if (features::IsReadAnythingLocalSidePanelEnabled()) {
@@ -104,61 +90,6 @@
   }
 }
 
-void ReadAnythingCoordinator::InitModelWithUserPrefs() {
-  Browser* browser = &GetBrowser();
-  if (!browser->profile() || !browser->profile()->GetPrefs()) {
-    return;
-  }
-
-  // Get user's default language to check for compatible fonts.
-  language::LanguageModel* language_model =
-      LanguageModelManagerFactory::GetForBrowserContext(browser->profile())
-          ->GetPrimaryModel();
-  std::string prefs_lang = language_model->GetLanguages().front().lang_code;
-  prefs_lang = language::ExtractBaseLanguage(prefs_lang);
-
-  std::string prefs_font_name = browser->profile()->GetPrefs()->GetString(
-      prefs::kAccessibilityReadAnythingFontName);
-
-  double prefs_font_scale = browser->profile()->GetPrefs()->GetDouble(
-      prefs::kAccessibilityReadAnythingFontScale);
-
-  bool prefs_links_enabled = browser->profile()->GetPrefs()->GetBoolean(
-      prefs::kAccessibilityReadAnythingLinksEnabled);
-
-  bool prefs_images_enabled = browser->profile()->GetPrefs()->GetBoolean(
-      prefs::kAccessibilityReadAnythingImagesEnabled);
-
-  read_anything::mojom::Colors prefs_colors =
-      static_cast<read_anything::mojom::Colors>(
-          browser->profile()->GetPrefs()->GetInteger(
-              prefs::kAccessibilityReadAnythingColorInfo));
-
-  read_anything::mojom::LineSpacing prefs_line_spacing =
-      static_cast<read_anything::mojom::LineSpacing>(
-          browser->profile()->GetPrefs()->GetInteger(
-              prefs::kAccessibilityReadAnythingLineSpacing));
-
-  read_anything::mojom::LetterSpacing prefs_letter_spacing =
-      static_cast<read_anything::mojom::LetterSpacing>(
-          browser->profile()->GetPrefs()->GetInteger(
-              prefs::kAccessibilityReadAnythingLetterSpacing));
-
-  model_->Init(
-      /* lang code = */ prefs_lang,
-      /* font name= */ prefs_font_name,
-      /* font scale = */ prefs_font_scale,
-      /* links enabled = */ prefs_links_enabled,
-      /* images_enabled = */ prefs_images_enabled,
-      /* colors = */ prefs_colors,
-      /* line spacing = */ prefs_line_spacing,
-      /* letter spacing = */ prefs_letter_spacing);
-  default_language_code_ = prefs_lang;
-  for (Observer& obs : observers_) {
-    obs.SetDefaultLanguageCode(prefs_lang);
-  }
-}
-
 ReadAnythingCoordinator::~ReadAnythingCoordinator() {
   local_side_panel_switch_delay_timer_.Stop();
 
@@ -224,37 +155,15 @@
   tab_helper->CreateAndRegisterEntry();
 }
 
-ReadAnythingController* ReadAnythingCoordinator::GetController() {
-  return controller_.get();
-}
-
-ReadAnythingModel* ReadAnythingCoordinator::GetModel() {
-  return model_.get();
-}
-
 void ReadAnythingCoordinator::AddObserver(
     ReadAnythingCoordinator::Observer* observer) {
   observers_.AddObserver(observer);
-
-  // InitModelWithUserPrefs where default_language_code_ is set may be called
-  // before all observerers have been added, so ensure that observers are
-  // updated with the correct language code as they're added.
-  observer->SetDefaultLanguageCode(default_language_code_);
 }
+
 void ReadAnythingCoordinator::RemoveObserver(
     ReadAnythingCoordinator::Observer* observer) {
   observers_.RemoveObserver(observer);
 }
-void ReadAnythingCoordinator::AddModelObserver(
-    ReadAnythingModel::Observer* observer) {
-  DCHECK(model_);
-  model_->AddObserver(observer);
-}
-void ReadAnythingCoordinator::RemoveModelObserver(
-    ReadAnythingModel::Observer* observer) {
-  DCHECK(model_);
-  model_->RemoveObserver(observer);
-}
 
 void ReadAnythingCoordinator::OnEntryShown(SidePanelEntry* entry) {
   DCHECK(entry->key().id() == SidePanelEntry::Id::kReadAnything);
@@ -312,23 +221,7 @@
   auto web_view =
       std::make_unique<ReadAnythingSidePanelWebView>(browser->profile());
 
-  if (features::IsReadAnythingWebUIToolbarEnabled()) {
-    return std::move(web_view);
-  }
-
-  // Create the views.
-  auto toolbar = std::make_unique<ReadAnythingToolbarView>(
-      this,
-      /* ReadAnythingToolbarView::Delegate* = */ controller_.get(),
-      /* ReadAnythingFontCombobox::Delegate* = */ controller_.get());
-
-  // Create the component.
-  // Note that a coordinator would normally maintain ownership of these objects,
-  // but objects extending {ui/views/view.h} prefer ownership over raw pointers.
-  auto container_view = std::make_unique<ReadAnythingContainerView>(
-      this, std::move(toolbar), std::move(web_view));
-
-  return std::move(container_view);
+  return std::move(web_view);
 }
 
 void ReadAnythingCoordinator::StartPageChangeDelay() {
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h
index 1fdf49b..a9307271 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h
@@ -14,12 +14,10 @@
 #include "chrome/browser/ui/browser_list_observer.h"
 #include "chrome/browser/ui/browser_user_data.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_entry_observer.h"
 #include "content/public/browser/web_contents_observer.h"
 
 class Browser;
-class ReadAnythingController;
 class SidePanelRegistry;
 namespace views {
 class View;
@@ -29,9 +27,7 @@
 // ReadAnythingCoordinator
 //
 //  A class that coordinates the Read Anything feature. This class registers
-//  itself as a SidePanelEntry. It creates and owns the Read Anything controller
-//  and model. It also creates the Read Anything views when requested by the
-//  Side Panel controller.
+//  itself as a SidePanelEntry.
 //  The coordinator acts as the external-facing API for the Read Anything
 //  feature. Classes outside this feature should make calls to the coordinator.
 //  This class has the same lifetime as the browser.
@@ -47,20 +43,14 @@
     virtual void Activate(bool active) {}
     virtual void OnActivePageDistillable(bool distillable) {}
     virtual void OnCoordinatorDestroyed() = 0;
-    virtual void SetDefaultLanguageCode(const std::string& code) {}
   };
 
   void CreateAndRegisterEntry(SidePanelRegistry* global_registry);
   explicit ReadAnythingCoordinator(Browser* browser);
   ~ReadAnythingCoordinator() override;
 
-  ReadAnythingController* GetController();
-  ReadAnythingModel* GetModel();
-
   void AddObserver(ReadAnythingCoordinator::Observer* observer);
   void RemoveObserver(ReadAnythingCoordinator::Observer* observer);
-  void AddModelObserver(ReadAnythingModel::Observer* observer);
-  void RemoveModelObserver(ReadAnythingModel::Observer* observer);
 
   void OnReadAnythingSidePanelEntryShown();
   void OnReadAnythingSidePanelEntryHidden();
@@ -71,15 +61,12 @@
  private:
   friend class BrowserUserData<ReadAnythingCoordinator>;
   friend class ReadAnythingCoordinatorTest;
-  friend class ReadAnythingCoordinatorWebUIToolbarTest;
   friend class ReadAnythingCoordinatorScreen2xDataCollectionModeTest;
 
   void CreateAndRegisterEntriesForExistingWebContents(
       TabStripModel* tab_strip_model);
   void CreateAndRegisterEntryForWebContents(content::WebContents* web_contents);
 
-  // Used during construction to initialize the model with saved user prefs.
-  void InitModelWithUserPrefs();
   // Starts the delay for showing the IPH after the tab has changed.
   void StartPageChangeDelay();
   // Occurs when the timer set when changing tabs is finished.
@@ -125,8 +112,6 @@
   void OnLocalSidePanelSwitchDelayTimeout();
 
   std::string default_language_code_;
-  std::unique_ptr<ReadAnythingModel> model_;
-  std::unique_ptr<ReadAnythingController> controller_;
 
   const base::flat_set<std::string> distillable_urls_;
 
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc
index 95941a2..91806f1 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc
@@ -16,7 +16,6 @@
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/frame/test_with_browser_view.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_web_view.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_entry.h"
@@ -53,8 +52,7 @@
     base::test::ScopedFeatureList features;
     scoped_feature_list_.InitWithFeatures(
         {features::kReadAnythingDocsIntegration,
-         features::kReadAnythingLocalSidePanel,
-         features::kReadAnythingWebUIToolbar},
+         features::kReadAnythingLocalSidePanel},
         {});
     TestWithBrowserView::SetUp();
 
@@ -97,12 +95,6 @@
   // Wrapper methods around the ReadAnythingCoordinator. These do nothing more
   // than keep the below tests less verbose (simple pass-throughs).
 
-  ReadAnythingController* GetController() {
-    return read_anything_coordinator_->GetController();
-  }
-  ReadAnythingModel* GetModel() {
-    return read_anything_coordinator_->GetModel();
-  }
   void AddObserver(ReadAnythingCoordinator::Observer* observer) {
     read_anything_coordinator_->AddObserver(observer);
   }
@@ -150,22 +142,6 @@
 // these tests on asan mac.
 #if !BUILDFLAG(IS_MAC) || !defined(ADDRESS_SANITIZER)
 
-TEST_F(ReadAnythingCoordinatorTest, ModelAndControllerPersist) {
-  // Model and controller are constructed when ReadAnythingCoordinator is
-  // constructed, before Side Panel is shown.
-  EXPECT_NE(nullptr, GetModel());
-  EXPECT_NE(nullptr, GetController());
-
-  side_panel_coordinator_->Show(SidePanelEntry::Id::kReadAnything);
-  EXPECT_NE(nullptr, GetModel());
-  EXPECT_NE(nullptr, GetController());
-
-  // Model and controller are not destroyed when Side Panel is closed.
-  side_panel_coordinator_->Close();
-  EXPECT_NE(nullptr, GetModel());
-  EXPECT_NE(nullptr, GetController());
-}
-
 TEST_F(ReadAnythingCoordinatorTest, ContainerViewsAreUnique) {
   auto view1 = CreateContainerView();
   auto view2 = CreateContainerView();
@@ -266,46 +242,13 @@
                CreateContainerView()->GetClassName());
 }
 
-class ReadAnythingCoordinatorWebUIToolbarTest : public TestWithBrowserView {
- public:
-  void SetUp() override {
-    base::test::ScopedFeatureList features;
-    scoped_feature_list_.InitWithFeatures(
-        {}, {features::kReadAnythingWebUIToolbar});
-    TestWithBrowserView::SetUp();
-
-    read_anything_coordinator_ =
-        ReadAnythingCoordinator::GetOrCreateForBrowser(browser());
-  }
-
-  void TearDown() override {
-    read_anything_coordinator_ = nullptr;
-    TestWithBrowserView::TearDown();
-  }
-
-  std::unique_ptr<views::View> CreateContainerView() {
-    return read_anything_coordinator_->CreateContainerView();
-  }
-
- protected:
-  raw_ptr<ReadAnythingCoordinator> read_anything_coordinator_;
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-TEST_F(ReadAnythingCoordinatorWebUIToolbarTest,
-       WithWebUIFlagEnabled_ShowsWebUIToolbar) {
-  ASSERT_STREQ("ReadAnythingContainerView",
-               CreateContainerView()->GetClassName());
-}
-
 class ReadAnythingCoordinatorScreen2xDataCollectionModeTest
     : public TestWithBrowserView {
  public:
   void SetUp() override {
     base::test::ScopedFeatureList features;
     scoped_feature_list_.InitWithFeatures(
-        {features::kDataCollectionModeForScreen2x},
-        {features::kReadAnythingWebUIToolbar});
+        {features::kDataCollectionModeForScreen2x}, {});
     TestWithBrowserView::SetUp();
 
     side_panel_coordinator_ =
@@ -329,8 +272,9 @@
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
+// TODO(40851192): Re-enable this test once the data collection script is fixed.
 TEST_F(ReadAnythingCoordinatorScreen2xDataCollectionModeTest,
-       OnBrowserSetLastActive_SidePanelIsVisible) {
+       DISABLED_OnBrowserSetLastActive_SidePanelIsVisible) {
   Browser* browser = browser_view()->browser();
   OnBrowserSetLastActive(browser);
 
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.cc
deleted file mode 100644
index 7b8c3d3a..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.h"
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h"
-#include "chrome/common/accessibility/read_anything_constants.h"
-#include "chrome/grit/generated_resources.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/metadata/metadata_impl_macros.h"
-#include "ui/base/models/combobox_model.h"
-#include "ui/base/models/image_model.h"
-#include "ui/base/models/menu_model.h"
-#include "ui/views/controls/combobox/combobox_menu_model.h"
-
-ReadAnythingFontCombobox::ReadAnythingFontCombobox(
-    ReadAnythingFontCombobox::Delegate* delegate)
-    : Combobox(std::move(delegate->GetFontComboboxModel())),
-      delegate_(std::move(delegate)) {
-  SetTooltipTextAndAccessibleName(
-      l10n_util::GetStringUTF16(IDS_READING_MODE_FONT_NAME_COMBOBOX_LABEL));
-  SetCallback(
-      base::BindRepeating(&ReadAnythingFontCombobox::FontNameChangedCallback,
-                          weak_pointer_factory_.GetWeakPtr()));
-
-  SetBorderColorId(ui::kColorSidePanelComboboxBorder);
-  SetMenuModel(std::make_unique<ComboboxMenuModel>(this, GetModel()));
-  SetFocusBehavior(FocusBehavior::ALWAYS);
-  SetEventHighlighting(true);
-}
-
-void ReadAnythingFontCombobox::GetAccessibleNodeData(
-    ui::AXNodeData* node_data) {
-  Combobox::GetAccessibleNodeData(node_data);
-  node_data->SetDescription(
-      GetModel()->GetDropDownTextAt(GetSelectedIndex().value()));
-}
-
-void ReadAnythingFontCombobox::FontNameChangedCallback() {
-  if (delegate_)
-    delegate_->OnFontChoiceChanged(GetSelectedIndex().value());
-}
-
-gfx::Size ReadAnythingFontCombobox::GetMinimumSize() const {
-  return gfx::Size(kMinimumComboboxWidth, CalculatePreferredSize({}).height());
-}
-
-void ReadAnythingFontCombobox::SetFocusRingColorId(
-    ui::ColorId focus_ring_color) {
-  DCHECK(views::FocusRing::Get(this));
-  views::FocusRing::Get(this)->SetColorId(focus_ring_color);
-}
-
-void ReadAnythingFontCombobox::SetDropdownColorIds(ui::ColorId background_color,
-                                                   ui::ColorId foreground_color,
-                                                   ui::ColorId selected_color) {
-  delegate_->GetFontComboboxModel()->SetForegroundColorId(foreground_color);
-  delegate_->GetFontComboboxModel()->SetBackgroundColorId(background_color);
-  delegate_->GetFontComboboxModel()->SetSelectedBackgroundColorId(
-      selected_color);
-}
-
-BEGIN_METADATA(ReadAnythingFontCombobox)
-END_METADATA
-
-ReadAnythingFontCombobox::~ReadAnythingFontCombobox() = default;
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.h
deleted file mode 100644
index 21b5f58b..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_FONT_COMBOBOX_H_
-#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_FONT_COMBOBOX_H_
-
-#include "base/memory/raw_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h"
-#include "ui/base/metadata/metadata_header_macros.h"
-#include "ui/base/metadata/metadata_impl_macros.h"
-#include "ui/base/models/combobox_model.h"
-#include "ui/views/controls/combobox/combobox.h"
-
-class ReadAnythingFontCombobox : public views::Combobox {
-  METADATA_HEADER(ReadAnythingFontCombobox, views::Combobox)
-
- public:
-  class Delegate {
-   public:
-    virtual void OnFontChoiceChanged(int new_index) = 0;
-    virtual ReadAnythingFontModel* GetFontComboboxModel() = 0;
-  };
-
-  explicit ReadAnythingFontCombobox(
-      ReadAnythingFontCombobox::Delegate* delegate);
-  ReadAnythingFontCombobox(const ReadAnythingFontCombobox&) = delete;
-  ReadAnythingFontCombobox& operator=(const ReadAnythingFontCombobox&) = delete;
-  ~ReadAnythingFontCombobox() override;
-
-  void SetDropdownColorIds(ui::ColorId foreground_color,
-                           ui::ColorId background_color,
-                           ui::ColorId selected_color);
-
-  // views::Combobox:
-  gfx::Size GetMinimumSize() const override;
-
-  void SetFocusRingColorId(ui::ColorId focus_ring_color);
-
- private:
-  void FontNameChangedCallback();
-
-  // views::View:
-  void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
-
-  raw_ptr<ReadAnythingFontCombobox::Delegate, DanglingUntriaged> delegate_;
-
-  base::WeakPtrFactory<ReadAnythingFontCombobox> weak_pointer_factory_{this};
-};
-
-#endif  // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_FONT_COMBOBOX_H_
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.cc
deleted file mode 100644
index a951ad5c..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.h"
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_model.h"
-#include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h"
-#include "chrome/common/accessibility/read_anything_constants.h"
-#include "ui/base/metadata/metadata_impl_macros.h"
-#include "ui/gfx/paint_vector_icon.h"
-#include "ui/views/accessibility/view_accessibility.h"
-#include "ui/views/animation/ink_drop.h"
-#include "ui/views/controls/button/image_button_factory.h"
-#include "ui/views/controls/highlight_path_generator.h"
-#include "ui/views/controls/menu/menu_runner.h"
-
-ReadAnythingMenuButton::ReadAnythingMenuButton(
-    base::RepeatingCallback<void()> callback,
-    const gfx::VectorIcon& icon,
-    const std::u16string& tooltip,
-    ReadAnythingMenuModel* menu_model)
-    : MenuButton(base::BindRepeating(&ReadAnythingMenuButton::ButtonPressed,
-                                     base::Unretained(this))) {
-  ConfigureInkDropForToolbar(this);
-  views::InstallCircleHighlightPathGenerator(this);
-  SetIcon(icon, kIconSize, /* icon_color= */ gfx::kPlaceholderColor,
-          /* focus_ring_color= */ gfx::kPlaceholderColor);
-  GetViewAccessibility().SetName(tooltip);
-  SetTooltipText(tooltip);
-  SetFocusBehavior(FocusBehavior::ALWAYS);
-  SetMenuModel(menu_model);
-  if (menu_model_)
-    menu_model_->SetCallback(std::move(callback));
-}
-
-ReadAnythingMenuButton::~ReadAnythingMenuButton() = default;
-
-bool ReadAnythingMenuButton::IsGroupFocusTraversable() const {
-  // Only the first item in the toolbar should be reachable with tab
-  return false;
-}
-
-void ReadAnythingMenuButton::ButtonPressed() {
-  menu_runner_ = std::make_unique<views::MenuRunner>(
-      menu_model_.get(),
-      views::MenuRunner::COMBOBOX | views::MenuRunner::HAS_MNEMONICS);
-
-  gfx::Point screen_loc;
-  views::View::ConvertPointToScreen(this, &screen_loc);
-  gfx::Rect bounds(screen_loc, this->size());
-
-  menu_runner_->RunMenuAt(GetWidget()->GetTopLevelWidget(), button_controller(),
-                          bounds, views::MenuAnchorPosition::kTopLeft,
-                          ui::MENU_SOURCE_NONE);
-}
-
-void ReadAnythingMenuButton::SetMenuModel(ReadAnythingMenuModel* menu_model) {
-  menu_model_ = menu_model;
-}
-
-ReadAnythingMenuModel* ReadAnythingMenuButton::GetMenuModel() const {
-  return menu_model_;
-}
-
-std::optional<size_t> ReadAnythingMenuButton::GetSelectedIndex() const {
-  if (!menu_model_) {
-    return std::nullopt;
-  }
-  return menu_model_->GetSelectedIndex();
-}
-
-void ReadAnythingMenuButton::SetIcon(const gfx::VectorIcon& icon,
-                                     int icon_size,
-                                     ui::ColorId icon_color,
-                                     ui::ColorId focus_ring_color) {
-  SetImageModel(views::Button::STATE_NORMAL,
-                ui::ImageModel::FromVectorIcon(icon, icon_color, icon_size));
-  DCHECK(views::InkDrop::Get(this));
-  DCHECK(views::FocusRing::Get(this));
-  views::InkDrop::Get(this)->SetBaseColorId(icon_color);
-  views::FocusRing::Get(this)->SetColorId(focus_ring_color);
-}
-
-void ReadAnythingMenuButton::SetDropdownColorIds(ui::ColorId background_color,
-                                                 ui::ColorId foreground_color,
-                                                 ui::ColorId selected_color) {
-  menu_model_->SetSubmenuBackgroundColorId(background_color);
-  menu_model_->SetForegroundColorId(foreground_color);
-  menu_model_->SetSelectedBackgroundColorId(selected_color);
-}
-
-BEGIN_METADATA(ReadAnythingMenuButton)
-ADD_PROPERTY_METADATA(ReadAnythingMenuModel*, MenuModel)
-END_METADATA
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.h
deleted file mode 100644
index 403fdc86..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_MENU_BUTTON_H_
-#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_MENU_BUTTON_H_
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h"
-#include "ui/base/metadata/metadata_header_macros.h"
-#include "ui/views/controls/button/menu_button.h"
-
-namespace views {
-class MenuRunner;
-}  // namespace views
-
-class ReadAnythingMenuModel;
-
-class ReadAnythingMenuButton : public views::MenuButton {
-  METADATA_HEADER(ReadAnythingMenuButton, views::MenuButton)
-
- public:
-  ReadAnythingMenuButton(base::RepeatingCallback<void()> callback,
-                         const gfx::VectorIcon& icon,
-                         const std::u16string& tooltip,
-                         ReadAnythingMenuModel* menu_model);
-  ReadAnythingMenuButton(const ReadAnythingMenuButton&) = delete;
-  ReadAnythingMenuButton& operator=(const ReadAnythingMenuButton&) = delete;
-  ~ReadAnythingMenuButton() override;
-
-  // views::MenuButton
-  bool IsGroupFocusTraversable() const override;
-
-  void SetMenuModel(ReadAnythingMenuModel* menu_model);
-  ReadAnythingMenuModel* GetMenuModel() const;
-  std::optional<size_t> GetSelectedIndex() const;
-  void SetIcon(const gfx::VectorIcon& icon,
-               int icon_size,
-               ui::ColorId icon_color,
-               ui::ColorId focus_ring_color);
-  void SetDropdownColorIds(ui::ColorId background_color,
-                           ui::ColorId foreground_color,
-                           ui::ColorId selected_color);
-
- private:
-  void ButtonPressed();
-
-  raw_ptr<ReadAnythingMenuModel> menu_model_;
-  std::unique_ptr<views::MenuRunner> menu_runner_;
-};
-
-#endif  // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_MENU_BUTTON_H_
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_model.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_model.cc
deleted file mode 100644
index bb44071..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_model.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_model.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingMenuModel
-///////////////////////////////////////////////////////////////////////////////
-
-ReadAnythingMenuModel::ReadAnythingMenuModel() : ui::SimpleMenuModel(this) {}
-
-ReadAnythingMenuModel::~ReadAnythingMenuModel() = default;
-
-void ReadAnythingMenuModel::SetCallback(
-    base::RepeatingCallback<void()> callback) {
-  callback_ = std::move(callback);
-}
-
-bool ReadAnythingMenuModel::IsCommandIdChecked(int command_id) const {
-  return selected_index_.has_value() &&
-         static_cast<size_t>(command_id) == selected_index_.value();
-}
-
-void ReadAnythingMenuModel::ExecuteCommand(int command_id, int event_flags) {
-  selected_index_ = command_id;
-  if (callback_)
-    callback_.Run();
-}
-
-void ReadAnythingMenuModel::SetSelectedIndex(size_t index) {
-  selected_index_ = index;
-}
-
-bool ReadAnythingMenuModel::IsValidIndex(size_t index) {
-  return false;
-}
-
-std::optional<ui::ColorId> ReadAnythingMenuModel::GetForegroundColorId(
-    size_t index) {
-  return foreground_color_id_;
-}
-
-std::optional<ui::ColorId> ReadAnythingMenuModel::GetSubmenuBackgroundColorId(
-    size_t index) {
-  return submenu_background_color_id_;
-}
-
-std::optional<ui::ColorId> ReadAnythingMenuModel::GetSelectedBackgroundColorId(
-    size_t index) {
-  return selected_color_id_;
-}
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_model.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_model.h
deleted file mode 100644
index 2a60b04d..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_model.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_MENU_MODEL_H_
-#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_MENU_MODEL_H_
-
-#include <optional>
-
-#include "ui/base/models/simple_menu_model.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingMenuModel
-//
-//  This class makes the menu (dropdown) for the ReadAnythingMenuButton.
-//
-class ReadAnythingMenuModel : public ui::SimpleMenuModel,
-                              public ui::SimpleMenuModel::Delegate {
- public:
-  ReadAnythingMenuModel();
-  ReadAnythingMenuModel(const ReadAnythingMenuModel&) = delete;
-  ReadAnythingMenuModel& operator=(const ReadAnythingMenuModel&) = delete;
-  ~ReadAnythingMenuModel() override;
-
-  // ui::SimpleMenuModel::Delegate:
-  bool IsCommandIdChecked(int command_id) const override;
-  void ExecuteCommand(int command_id, int event_flags) override;
-
-  virtual bool IsValidIndex(size_t index);
-  void SetSelectedIndex(size_t index);
-  std::optional<size_t> GetSelectedIndex() const { return selected_index_; }
-  void SetCallback(base::RepeatingCallback<void()> callback);
-
-  std::optional<ui::ColorId> GetForegroundColorId(size_t index) override;
-  std::optional<ui::ColorId> GetSubmenuBackgroundColorId(size_t index) override;
-  std::optional<ui::ColorId> GetSelectedBackgroundColorId(
-      size_t index) override;
-
-  void SetForegroundColorId(ui::ColorId foreground_color) {
-    foreground_color_id_ = foreground_color;
-  }
-
-  void SetSubmenuBackgroundColorId(ui::ColorId background_color) {
-    submenu_background_color_id_ = background_color;
-  }
-
-  void SetSelectedBackgroundColorId(ui::ColorId selected_color) {
-    selected_color_id_ = selected_color;
-  }
-
- private:
-  std::optional<size_t> selected_index_ = std::nullopt;
-  base::RepeatingClosure callback_;
-  std::optional<ui::ColorId> foreground_color_id_;
-  std::optional<ui::ColorId> submenu_background_color_id_;
-  std::optional<ui::ColorId> selected_color_id_;
-};
-
-#endif  // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_MENU_MODEL_H_
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc
deleted file mode 100644
index 28580274..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.cc
+++ /dev/null
@@ -1,525 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/check.h"
-#include "base/containers/contains.h"
-#include "base/ranges/algorithm.h"
-#include "base/strings/stringprintf.h"
-#include "chrome/app/vector_icons/vector_icons.h"
-#include "chrome/browser/ui/color/chrome_color_id.h"
-#include "chrome/common/accessibility/read_anything_constants.h"
-#include "chrome/grit/component_extension_resources.h"
-#include "chrome/grit/generated_resources.h"
-#include "ui/accessibility/accessibility_features.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/models/image_model.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/image/image_skia_operations.h"
-#include "ui/gfx/paint_vector_icon.h"
-
-using read_anything::mojom::LetterSpacing;
-using read_anything::mojom::LineSpacing;
-
-ReadAnythingModel::ReadAnythingModel()
-    : font_name_(string_constants::kReadAnythingPlaceholderFontName),
-      font_scale_(kReadAnythingDefaultFontScale),
-      font_model_(std::make_unique<ReadAnythingFontModel>()),
-      colors_model_(std::make_unique<ReadAnythingColorsModel>()),
-      line_spacing_model_(std::make_unique<ReadAnythingLineSpacingModel>()),
-      letter_spacing_model_(
-          std::make_unique<ReadAnythingLetterSpacingModel>()) {}
-
-ReadAnythingModel::~ReadAnythingModel() = default;
-
-void ReadAnythingModel::Init(const std::string& lang_code,
-                             const std::string& font_name,
-                             double font_scale,
-                             bool links_enabled,
-                             bool images_enabled,
-                             read_anything::mojom::Colors colors,
-                             LineSpacing line_spacing,
-                             LetterSpacing letter_spacing) {
-  font_model_->SetDefaultLanguage(lang_code);
-
-  // If this profile has previously selected choices that were saved to
-  // prefs, check they are still a valid, and then assign if so.
-  size_t font_index = font_model_->GetFontNameIndex(font_name);
-  if (font_model_->IsValidFontIndex(font_index)) {
-    font_model_->SetSelectedIndex(font_index);
-  }
-
-  font_scale_ = GetValidFontScale(font_scale);
-
-  links_enabled_ = links_enabled;
-  images_enabled_ = images_enabled;
-
-  size_t colors_index = static_cast<size_t>(colors);
-  if (colors_model_->IsValidIndex(colors_index)) {
-    colors_model_->SetSelectedIndex(colors_index);
-  }
-
-  // LineSpacing contains a deprecated value, so it doesn't correspond exactly
-  // to drop-down indices.
-  size_t line_spacing_index =
-      line_spacing_model_->GetIndexForLineSpacing(line_spacing);
-  if (line_spacing_model_->IsValidIndex(line_spacing_index)) {
-    line_spacing_model_->SetSelectedIndex(line_spacing_index);
-  }
-
-  // LetterSpacing contains a deprecated value, so it doesn't correspond exactly
-  // to drop-down indices.
-  size_t letter_spacing_index =
-      letter_spacing_model_->GetIndexForLetterSpacing(letter_spacing);
-  if (letter_spacing_model_->IsValidIndex(letter_spacing_index)) {
-    letter_spacing_model_->SetSelectedIndex(letter_spacing_index);
-  }
-
-  font_name_ = font_model_->GetFontNameAt(font_model_->GetSelectedIndex());
-  colors_combobox_index_ = colors_model_->GetSelectedIndex().value();
-  auto& initial_colors = colors_model_->GetColorsAt(colors_combobox_index_);
-  foreground_color_id_ = initial_colors.foreground_color_id;
-  background_color_id_ = initial_colors.background_color_id;
-  separator_color_id_ = initial_colors.separator_color_id;
-  dropdown_color_id_ = initial_colors.dropdown_color_id;
-  selected_dropdown_color_id_ = initial_colors.selected_dropdown_color_id;
-  focus_ring_color_id_ = initial_colors.focus_ring_color_id;
-
-  line_spacing_ = line_spacing_model_->GetLineSpacingAt(
-      line_spacing_model_->GetSelectedIndex().value());
-  letter_spacing_ = letter_spacing_model_->GetLetterSpacingAt(
-      letter_spacing_model_->GetSelectedIndex().value());
-}
-
-void ReadAnythingModel::AddObserver(Observer* obs) {
-  observers_.AddObserver(obs);
-  if (!features::IsReadAnythingWebUIToolbarEnabled()) {
-    NotifyThemeChanged();
-  }
-}
-
-void ReadAnythingModel::RemoveObserver(Observer* obs) {
-  observers_.RemoveObserver(obs);
-}
-
-void ReadAnythingModel::SetSelectedFontByIndex(size_t new_index) {
-  // Check that the index is valid.
-  DCHECK(font_model_->IsValidFontIndex(new_index));
-
-  // Keep track of current selection for GetDefaultIndex().
-  font_model_->SetSelectedIndex(new_index);
-
-  // Update state and notify listeners
-  font_name_ = font_model_->GetFontNameAt(new_index);
-  NotifyThemeChanged();
-}
-
-void ReadAnythingModel::SetSelectedColorsByIndex(size_t new_index) {
-  // Check that the index is valid.
-  DCHECK(colors_model_->IsValidIndex(new_index));
-
-  colors_combobox_index_ = new_index;
-  auto& new_colors = colors_model_->GetColorsAt(new_index);
-  foreground_color_id_ = new_colors.foreground_color_id;
-  background_color_id_ = new_colors.background_color_id;
-  separator_color_id_ = new_colors.separator_color_id;
-  dropdown_color_id_ = new_colors.dropdown_color_id;
-  selected_dropdown_color_id_ = new_colors.selected_dropdown_color_id;
-  focus_ring_color_id_ = new_colors.focus_ring_color_id;
-
-  NotifyThemeChanged();
-}
-
-void ReadAnythingModel::SetSelectedLineSpacingByIndex(size_t new_index) {
-  // Check that the index is valid.
-  DCHECK(line_spacing_model_->IsValidIndex(new_index));
-
-  line_spacing_ = line_spacing_model_->GetLineSpacingAt(new_index);
-  NotifyThemeChanged();
-}
-
-void ReadAnythingModel::SetSelectedLetterSpacingByIndex(size_t new_index) {
-  // Check that the index is valid.
-  DCHECK(letter_spacing_model_->IsValidIndex(new_index));
-
-  letter_spacing_ = letter_spacing_model_->GetLetterSpacingAt(new_index);
-  NotifyThemeChanged();
-}
-
-double ReadAnythingModel::GetValidFontScale(double font_scale) {
-  if (font_scale < kReadAnythingMinimumFontScale) {
-    return kReadAnythingMinimumFontScale;
-  }
-  if (font_scale > kReadAnythingMaximumFontScale) {
-    return kReadAnythingMaximumFontScale;
-  }
-  return font_scale;
-}
-
-// TODO(crbug.com/40802192): Update with text scaling approach based on UI/UX
-// feedback.
-void ReadAnythingModel::DecreaseTextSize() {
-  font_scale_ -= kReadAnythingFontScaleIncrement;
-  if (font_scale_ < kReadAnythingMinimumFontScale) {
-    font_scale_ = kReadAnythingMinimumFontScale;
-  }
-
-  NotifyThemeChanged();
-}
-
-void ReadAnythingModel::IncreaseTextSize() {
-  font_scale_ += kReadAnythingFontScaleIncrement;
-  if (font_scale_ > kReadAnythingMaximumFontScale) {
-    font_scale_ = kReadAnythingMaximumFontScale;
-  }
-
-  NotifyThemeChanged();
-}
-
-void ReadAnythingModel::SetLinksEnabled(bool enabled) {
-  links_enabled_ = enabled;
-  NotifyThemeChanged();
-}
-
-void ReadAnythingModel::SetImagesEnabled(bool enabled) {
-  images_enabled_ = enabled;
-  NotifyThemeChanged();
-}
-
-void ReadAnythingModel::OnSystemThemeChanged() {
-  NotifyThemeChanged();
-}
-
-void ReadAnythingModel::NotifyThemeChanged() {
-  for (Observer& obs : observers_) {
-    obs.OnReadAnythingThemeChanged(
-        font_name_, font_scale_, links_enabled_, images_enabled_,
-        foreground_color_id_, background_color_id_, separator_color_id_,
-        dropdown_color_id_, selected_dropdown_color_id_, focus_ring_color_id_,
-        line_spacing_, letter_spacing_);
-  }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingFontModel
-///////////////////////////////////////////////////////////////////////////////
-
-ReadAnythingFontModel::ReadAnythingFontModel() {}
-
-// If you change these fonts, please also update read_anything_constants.h
-void ReadAnythingFontModel::SetDefaultLanguage(const std::string& lang) {
-  if (base::Contains(kLanguagesSupportedByPoppins, lang)) {
-    font_choices_.emplace_back(u"Poppins");
-  }
-  font_choices_.emplace_back(u"Sans-serif");
-  font_choices_.emplace_back(u"Serif");
-  if (base::Contains(kLanguagesSupportedByComicNeue, lang)) {
-    font_choices_.emplace_back(u"Comic Neue");
-  }
-  if (base::Contains(kLanguagesSupportedByLexendDeca, lang)) {
-    font_choices_.emplace_back(u"Lexend Deca");
-  }
-  if (base::Contains(kLanguagesSupportedByEbGaramond, lang)) {
-    font_choices_.emplace_back(u"EB Garamond");
-  }
-  if (base::Contains(kLanguagesSupportedByStixTwoText, lang)) {
-    font_choices_.emplace_back(u"STIX Two Text");
-  }
-  if (base::Contains(kLanguagesSupportedByAndika, lang)) {
-    font_choices_.emplace_back(u"Andika");
-  }
-  font_choices_.shrink_to_fit();
-}
-
-bool ReadAnythingFontModel::IsValidFontIndex(size_t index) {
-  return index < GetItemCount();
-}
-
-size_t ReadAnythingFontModel::GetFontNameIndex(std::string font_name) {
-  auto it = base::ranges::find(font_choices_, base::UTF8ToUTF16(font_name));
-  return static_cast<size_t>(it - font_choices_.begin());
-}
-
-// ui::Combobox needs a default option to show whenever Read Anything is
-// reopened in the same browser window.
-std::optional<size_t> ReadAnythingFontModel::GetDefaultIndex() const {
-  return selected_index_;
-}
-
-std::optional<size_t> ReadAnythingFontModel::GetDefaultIndexForTesting() {
-  return selected_index_;
-}
-
-void ReadAnythingFontModel::SetSelectedIndex(size_t index) {
-  selected_index_ = index;
-}
-
-size_t ReadAnythingFontModel::GetItemCount() const {
-  return font_choices_.size();
-}
-
-std::u16string ReadAnythingFontModel::GetItemAt(size_t index) const {
-  return GetDropDownTextAt(index);
-}
-
-std::u16string ReadAnythingFontModel::GetDropDownTextAt(size_t index) const {
-  DCHECK_LT(index, GetItemCount());
-  return font_choices_[index];
-}
-
-std::string ReadAnythingFontModel::GetFontNameAt(size_t index) {
-  DCHECK_LT(index, GetItemCount());
-  return base::UTF16ToUTF8(font_choices_[index]);
-}
-
-std::optional<ui::ColorId>
-ReadAnythingFontModel::GetDropdownForegroundColorIdAt(size_t index) const {
-  return foreground_color_id_;
-}
-
-std::optional<ui::ColorId>
-ReadAnythingFontModel::GetDropdownBackgroundColorIdAt(size_t index) const {
-  return background_color_id_;
-}
-
-std::optional<ui::ColorId>
-ReadAnythingFontModel::GetDropdownSelectedBackgroundColorIdAt(
-    size_t index) const {
-  return selected_color_id_;
-}
-
-ReadAnythingFontModel::~ReadAnythingFontModel() = default;
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingColorsModel
-///////////////////////////////////////////////////////////////////////////////
-ReadAnythingColorsModel::ColorInfo::ColorInfo(
-    std::u16string name,
-    int icon_asset,
-    ui::ColorId foreground_color_id,
-    ui::ColorId background_color_id,
-    ui::ColorId separator_color_id,
-    ui::ColorId dropdown_color_id,
-    ui::ColorId selected_dropdown_color_id,
-    ui::ColorId focus_ring_color_id)
-    : name(name),
-      icon_asset(icon_asset),
-      foreground_color_id(foreground_color_id),
-      background_color_id(background_color_id),
-      separator_color_id(separator_color_id),
-      dropdown_color_id(dropdown_color_id),
-      selected_dropdown_color_id(selected_dropdown_color_id),
-      focus_ring_color_id(focus_ring_color_id) {}
-ReadAnythingColorsModel::ColorInfo::ColorInfo(const ColorInfo& other) = default;
-ReadAnythingColorsModel::ColorInfo::ColorInfo(ColorInfo&&) = default;
-ReadAnythingColorsModel::ColorInfo&
-ReadAnythingColorsModel::ColorInfo::operator=(const ColorInfo&) = default;
-ReadAnythingColorsModel::ColorInfo&
-ReadAnythingColorsModel::ColorInfo::operator=(ColorInfo&&) = default;
-ReadAnythingColorsModel::ColorInfo::~ColorInfo() = default;
-
-ReadAnythingColorsModel::ReadAnythingColorsModel() {
-  // Define the possible sets of colors available to the user.
-  ColorInfo kDefaultColors = {
-      l10n_util::GetStringUTF16(IDS_READING_MODE_DEFAULT_COLOR_LABEL),
-      IDS_READING_MODE_DEFAULT_PNG,
-      kColorReadAnythingForeground,
-      kColorReadAnythingBackground,
-      kColorReadAnythingSeparator,
-      kColorReadAnythingDropdownBackground,
-      kColorReadAnythingDropdownSelected,
-      kColorReadAnythingFocusRingBackground};
-
-  ColorInfo kLightColors = {
-      l10n_util::GetStringUTF16(IDS_READING_MODE_LIGHT_COLOR_LABEL),
-      IDS_READING_MODE_LIGHT_PNG,
-      kColorReadAnythingForegroundLight,
-      kColorReadAnythingBackgroundLight,
-      kColorReadAnythingSeparatorLight,
-      kColorReadAnythingDropdownBackgroundLight,
-      kColorReadAnythingDropdownSelectedLight,
-      kColorReadAnythingFocusRingBackgroundLight};
-
-  ColorInfo kDarkColors = {
-      l10n_util::GetStringUTF16(IDS_READING_MODE_DARK_COLOR_LABEL),
-      IDS_READING_MODE_DARK_PNG,
-      kColorReadAnythingForegroundDark,
-      kColorReadAnythingBackgroundDark,
-      kColorReadAnythingSeparatorDark,
-      kColorReadAnythingDropdownBackgroundDark,
-      kColorReadAnythingDropdownSelectedDark,
-      kColorReadAnythingFocusRingBackgroundDark};
-
-  ColorInfo kYellowColors = {
-      l10n_util::GetStringUTF16(IDS_READING_MODE_YELLOW_COLOR_LABEL),
-      IDS_READING_MODE_YELLOW_PNG,
-      kColorReadAnythingForegroundYellow,
-      kColorReadAnythingBackgroundYellow,
-      kColorReadAnythingSeparatorYellow,
-      kColorReadAnythingDropdownBackgroundYellow,
-      kColorReadAnythingDropdownSelectedYellow,
-      kColorReadAnythingFocusRingBackgroundYellow};
-
-  ColorInfo kBlueColors = {
-      l10n_util::GetStringUTF16(IDS_READING_MODE_BLUE_COLOR_LABEL),
-      IDS_READING_MODE_BLUE_PNG,
-      kColorReadAnythingForegroundBlue,
-      kColorReadAnythingBackgroundBlue,
-      kColorReadAnythingSeparatorBlue,
-      kColorReadAnythingDropdownBackgroundBlue,
-      kColorReadAnythingDropdownSelectedBlue,
-      kColorReadAnythingFocusRingBackgroundBlue};
-
-  colors_choices_.emplace_back(kDefaultColors);
-  colors_choices_.emplace_back(kLightColors);
-  colors_choices_.emplace_back(kDarkColors);
-  colors_choices_.emplace_back(kYellowColors);
-  colors_choices_.emplace_back(kBlueColors);
-  colors_choices_.shrink_to_fit();
-
-  for (std::vector<ColorInfo>::size_type i = 0; i < colors_choices_.size();
-       i++) {
-    AddCheckItem(i, colors_choices_[i].name);
-    SetIcon(i, GetDropDownIconAt(i));
-  }
-}
-bool ReadAnythingColorsModel::IsValidIndex(size_t index) {
-  return index < colors_choices_.size();
-}
-
-ReadAnythingColorsModel::ColorInfo& ReadAnythingColorsModel::GetColorsAt(
-    size_t index) {
-  return colors_choices_[index];
-}
-
-ui::ImageModel ReadAnythingColorsModel::GetDropDownIconAt(size_t index) const {
-  const gfx::ImageSkia* icon_skia_asset =
-      ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
-          colors_choices_[index].icon_asset);
-  DCHECK(icon_skia_asset);
-
-  return ui::ImageModel::FromImageSkia(
-      gfx::ImageSkiaOperations::CreateResizedImage(
-          *icon_skia_asset, skia::ImageOperations::ResizeMethod::RESIZE_GOOD,
-          gfx::Size(kColorsIconSize, kColorsIconSize)));
-}
-
-ReadAnythingColorsModel::~ReadAnythingColorsModel() = default;
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingLineSpacingModel
-///////////////////////////////////////////////////////////////////////////////
-
-ReadAnythingLineSpacingModel::ReadAnythingLineSpacingModel() {
-  // Define the line spacing options available to the user.
-  LineSpacingInfo kStandard = {
-      LineSpacing::kStandard,
-      l10n_util::GetStringUTF16(IDS_READING_MODE_SPACING_COMBOBOX_STANDARD),
-      kReadAnythingLineSpacingStandardIcon};
-  LineSpacingInfo kLoose = {
-      LineSpacing::kLoose,
-      l10n_util::GetStringUTF16(IDS_READING_MODE_SPACING_COMBOBOX_LOOSE),
-      kReadAnythingLineSpacingLooseIcon};
-  LineSpacingInfo kVeryLoose = {
-      LineSpacing::kVeryLoose,
-      l10n_util::GetStringUTF16(IDS_READING_MODE_SPACING_COMBOBOX_VERY_LOOSE),
-      kReadAnythingLineSpacingVeryLooseIcon};
-
-  lines_choices_.emplace_back(kStandard);
-  lines_choices_.emplace_back(kLoose);
-  lines_choices_.emplace_back(kVeryLoose);
-  lines_choices_.shrink_to_fit();
-
-  for (std::vector<LetterSpacing>::size_type i = 0; i < lines_choices_.size();
-       i++) {
-    AddCheckItem(i, lines_choices_[i].name);
-    SetIcon(i,
-            ui::ImageModel::FromVectorIcon(lines_choices_[i].icon_asset,
-                                           ui::kColorIcon, kSpacingIconSize));
-  }
-}
-
-bool ReadAnythingLineSpacingModel::IsValidIndex(size_t index) {
-  return index < lines_choices_.size();
-}
-
-size_t ReadAnythingLineSpacingModel::GetIndexForLineSpacing(
-    LineSpacing line_spacing) {
-  switch (line_spacing) {
-    // If we read the deprecated value, choose the closest option.
-    case LineSpacing::kTightDeprecated:
-    case LineSpacing::kStandard:
-      return 0;
-    case LineSpacing::kLoose:
-      return 1;
-    case LineSpacing::kVeryLoose:
-      return 2;
-  }
-}
-
-LineSpacing ReadAnythingLineSpacingModel::GetLineSpacingAt(size_t index) {
-  return lines_choices_[index].enum_value;
-}
-
-ReadAnythingLineSpacingModel::~ReadAnythingLineSpacingModel() = default;
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingLetterSpacingModel
-///////////////////////////////////////////////////////////////////////////////
-ReadAnythingLetterSpacingModel::ReadAnythingLetterSpacingModel() {
-  LetterSpacingInfo kStandard = {
-      LetterSpacing::kStandard,
-      l10n_util::GetStringUTF16(IDS_READING_MODE_SPACING_COMBOBOX_STANDARD),
-      kReadAnythingLetterSpacingStandardIcon};
-  LetterSpacingInfo kWide = {
-      LetterSpacing::kWide,
-      l10n_util::GetStringUTF16(IDS_READING_MODE_SPACING_COMBOBOX_WIDE),
-      kReadAnythingLetterSpacingWideIcon};
-  LetterSpacingInfo kVeryWide = {
-      LetterSpacing::kVeryWide,
-      l10n_util::GetStringUTF16(IDS_READING_MODE_SPACING_COMBOBOX_VERY_WIDE),
-      kReadAnythingLetterSpacingVeryWideIcon};
-
-  letters_choices_.emplace_back(kStandard);
-  letters_choices_.emplace_back(kWide);
-  letters_choices_.emplace_back(kVeryWide);
-  letters_choices_.shrink_to_fit();
-
-  for (std::vector<LetterSpacing>::size_type i = 0; i < letters_choices_.size();
-       i++) {
-    AddCheckItem(i, letters_choices_[i].name);
-    SetIcon(i,
-            ui::ImageModel::FromVectorIcon(letters_choices_[i].icon_asset,
-                                           ui::kColorIcon, kSpacingIconSize));
-  }
-}
-
-bool ReadAnythingLetterSpacingModel::IsValidIndex(size_t index) {
-  return index < letters_choices_.size();
-}
-
-size_t ReadAnythingLetterSpacingModel::GetIndexForLetterSpacing(
-    LetterSpacing letter_spacing) {
-  switch (letter_spacing) {
-    // If we read the deprecated value, choose the closest option.
-    case LetterSpacing::kTightDeprecated:
-    case LetterSpacing::kStandard:
-      return 0;
-    case LetterSpacing::kWide:
-      return 1;
-    case LetterSpacing::kVeryWide:
-      return 2;
-  }
-}
-
-LetterSpacing ReadAnythingLetterSpacingModel::GetLetterSpacingAt(size_t index) {
-  return letters_choices_[index].enum_value;
-}
-
-ReadAnythingLetterSpacingModel::~ReadAnythingLetterSpacingModel() = default;
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h
deleted file mode 100644
index 194a05e..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h
+++ /dev/null
@@ -1,341 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_MODEL_H_
-#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_MODEL_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/memory/raw_ptr_exclusion.h"
-#include "base/observer_list.h"
-#include "base/observer_list_types.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/ui/color/chrome_color_id.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_model.h"
-#include "chrome/common/accessibility/read_anything.mojom.h"
-#include "chrome/common/accessibility/read_anything_constants.h"
-#include "ui/base/models/combobox_model.h"
-
-using read_anything::mojom::LetterSpacing;
-using read_anything::mojom::LineSpacing;
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingFontModel
-//
-//  A class that stores the data for the font combobox.
-//  This class is owned by the ReadAnythingModel and has the same lifetime as
-//  the browser.
-//
-class ReadAnythingFontModel : public ui::ComboboxModel {
- public:
-  ReadAnythingFontModel();
-  ReadAnythingFontModel(const ReadAnythingFontModel&) = delete;
-  ReadAnythingFontModel& operator=(const ReadAnythingFontModel&) = delete;
-  ~ReadAnythingFontModel() override;
-
-  // The name of the font
-  std::u16string name;
-
-  std::string GetFontNameAt(size_t index);
-  bool IsValidFontIndex(size_t index);
-  void SetDefaultLanguage(const std::string& lang);
-  size_t GetFontNameIndex(std::string font_name);
-  void SetSelectedIndex(size_t index);
-  size_t GetSelectedIndex() { return selected_index_; }
-
-  std::optional<ui::ColorId> GetDropdownForegroundColorIdAt(
-      size_t index) const override;
-  std::optional<ui::ColorId> GetDropdownBackgroundColorIdAt(
-      size_t index) const override;
-  std::optional<ui::ColorId> GetDropdownSelectedBackgroundColorIdAt(
-      size_t index) const override;
-
-  void SetForegroundColorId(ui::ColorId foreground_color) {
-    foreground_color_id_ = foreground_color;
-  }
-
-  void SetBackgroundColorId(ui::ColorId background_color) {
-    background_color_id_ = background_color;
-  }
-
-  void SetSelectedBackgroundColorId(ui::ColorId selected_color) {
-    selected_color_id_ = selected_color;
-  }
-
-  // Used by tests only.
-  std::optional<size_t> GetDefaultIndexForTesting();
-
- protected:
-  // ui::Combobox implementation:
-  std::optional<size_t> GetDefaultIndex() const override;
-  size_t GetItemCount() const override;
-  std::u16string GetItemAt(size_t index) const override;
-  std::u16string GetDropDownTextAt(size_t index) const override;
-
- private:
-  // Styled font names for the drop down options in front-end.
-  std::vector<std::u16string> font_choices_;
-
-  size_t selected_index_ = 0;
-
-  std::optional<ui::ColorId> foreground_color_id_;
-  std::optional<ui::ColorId> background_color_id_;
-  std::optional<ui::ColorId> selected_color_id_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingColorsModel
-//
-//  A class that stores the data for the colors combobox.
-//  This class is owned by the ReadAnythingModel and has the same lifetime as
-//  the browser.
-//
-class ReadAnythingColorsModel : public ReadAnythingMenuModel {
- public:
-  // Simple struct to hold the various colors to keep code cleaner.
-  struct ColorInfo {
-    ColorInfo(std::u16string name,
-              int icon_asset,
-              ui::ColorId foreground_color_id,
-              ui::ColorId background_color_id,
-              ui::ColorId separator_color_id,
-              ui::ColorId dropdown_color_id,
-              ui::ColorId selected_color_id,
-              ui::ColorId focus_ring_color_id);
-    ColorInfo(const ColorInfo& other);
-    ColorInfo(ColorInfo&&);
-    ColorInfo& operator=(const ColorInfo&);
-    ColorInfo& operator=(ColorInfo&&);
-    ~ColorInfo();
-
-    // The name of the colors, e.g. Default, Light, Dark.
-    std::u16string name;
-
-    // The resources value/identifier for the icon image asset.
-    int icon_asset;
-
-    // The foreground color, used for text and icon hints.
-    ui::ColorId foreground_color_id;
-
-    // The background color, used for text background.
-    ui::ColorId background_color_id;
-
-    // The separator color, used for visual separators between elements in the
-    // toolbar.
-    ui::ColorId separator_color_id;
-
-    // The color of the dropdown menu, used for the combobox menu model.
-    ui::ColorId dropdown_color_id;
-
-    // The selected / hover color of the dropdown menu, used for the combobox
-    // menu model.
-    ui::ColorId selected_dropdown_color_id;
-
-    // The color of the focus ring, used for all elements in the toolbar.
-    ui::ColorId focus_ring_color_id;
-  };
-
-  ReadAnythingColorsModel();
-  ReadAnythingColorsModel(const ReadAnythingColorsModel&) = delete;
-  ReadAnythingColorsModel& operator=(const ReadAnythingColorsModel&) = delete;
-  ~ReadAnythingColorsModel() override;
-
-  bool IsValidIndex(size_t index) override;
-  ColorInfo& GetColorsAt(size_t index);
-  ui::ImageModel GetDropDownIconAt(size_t index) const;
-
- private:
-  // Individual combobox choices for colors presented in front-end.
-  std::vector<ColorInfo> colors_choices_;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ReadAnythingLineSpacingModel
-//
-//  A class that stores the data for the colors combobox.
-//  This class is owned by the ReadAnythingModel and has the same lifetime as
-//  the browser.
-//
-class ReadAnythingLineSpacingModel : public ReadAnythingMenuModel {
- public:
-  ReadAnythingLineSpacingModel();
-  ReadAnythingLineSpacingModel(const ReadAnythingLineSpacingModel&) = delete;
-  ReadAnythingLineSpacingModel& operator=(const ReadAnythingLineSpacingModel&) =
-      delete;
-  ~ReadAnythingLineSpacingModel() override;
-
-  // Simple struct to hold the various spacings to keep code cleaner.
-  struct LineSpacingInfo {
-    // The enum value of the line spacing.
-    read_anything::mojom::LineSpacing enum_value;
-
-    // The name of the line spacing, e.g. Standard, Loose, Very Loose.
-    std::u16string name;
-
-    // The resources value/identifier for the icon image asset.
-    // RAW_PTR_EXCLUSION: Never allocated by PartitionAlloc (always points to a
-    // global), so there is no benefit to using a raw_ptr, only cost.
-    RAW_PTR_EXCLUSION const gfx::VectorIcon& icon_asset;
-  };
-
-  bool IsValidIndex(size_t index) override;
-  size_t GetIndexForLineSpacing(read_anything::mojom::LineSpacing line_spacing);
-  read_anything::mojom::LineSpacing GetLineSpacingAt(size_t index);
-
- private:
-  // Names for the drop down options in front-end.
-  std::vector<LineSpacingInfo> lines_choices_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingLetterSpacingModel
-//
-//  A class that stores the data for the letter spacing combobox.
-//  This class is owned by the ReadAnythingModel and has the same lifetime as
-//  the browser.
-//
-
-class ReadAnythingLetterSpacingModel : public ReadAnythingMenuModel {
- public:
-  ReadAnythingLetterSpacingModel();
-  ReadAnythingLetterSpacingModel(const ReadAnythingLetterSpacingModel&) =
-      delete;
-  ReadAnythingLetterSpacingModel& operator=(
-      const ReadAnythingLetterSpacingModel&) = delete;
-  ~ReadAnythingLetterSpacingModel() override;
-
-  // Simple struct to hold the various spacings to keep code cleaner.
-  struct LetterSpacingInfo {
-    // The enum value of the letter spacing.
-    read_anything::mojom::LetterSpacing enum_value;
-
-    // The name of the letter spacing, e.g. Standard, Wide, Very Wide.
-    std::u16string name;
-
-    // The resources value/identifier for the icon image asset.
-    // RAW_PTR_EXCLUSION: Never allocated by PartitionAlloc (always points to a
-    // global), so there is no benefit to using a raw_ptr, only cost.
-    RAW_PTR_EXCLUSION const gfx::VectorIcon& icon_asset;
-  };
-
-  bool IsValidIndex(size_t index) override;
-  size_t GetIndexForLetterSpacing(
-      read_anything::mojom::LetterSpacing letter_spacing);
-  read_anything::mojom::LetterSpacing GetLetterSpacingAt(size_t index);
-
- private:
-  // Letter spacing choices for the drop down options in front-end.
-  std::vector<LetterSpacingInfo> letters_choices_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingModel
-//
-//  A class that stores data for the Read Anything feature.
-//  This class is owned by the ReadAnythingCoordinator and has the same lifetime
-//  as the browser.
-//
-class ReadAnythingModel {
- public:
-  class Observer : public base::CheckedObserver {
-   public:
-    virtual void OnReadAnythingThemeChanged(
-        const std::string& font_name,
-        double font_scale,
-        bool links_enabled,
-        bool images_enabled,
-        ui::ColorId foreground_color_id,
-        ui::ColorId background_color_id,
-        ui::ColorId separator_color_id,
-        ui::ColorId dropdown_color_id,
-        ui::ColorId selected_color_id,
-        ui::ColorId focus_ring_color_id,
-        read_anything::mojom::LineSpacing line_spacing,
-        read_anything::mojom::LetterSpacing letter_spacing) = 0;
-  };
-
-  ReadAnythingModel();
-  ReadAnythingModel(const ReadAnythingModel&) = delete;
-  ReadAnythingModel& operator=(const ReadAnythingModel&) = delete;
-  ~ReadAnythingModel();
-
-  void Init(const std::string& lang_code,
-            const std::string& font_name,
-            double font_scale,
-            bool links_enabled,
-            bool images_enabled,
-            read_anything::mojom::Colors colors,
-            read_anything::mojom::LineSpacing line_spacing,
-            read_anything::mojom::LetterSpacing letter_spacing);
-
-  void AddObserver(Observer* obs);
-  void RemoveObserver(Observer* obs);
-
-  void SetSelectedFontByIndex(size_t new_index);
-  double GetValidFontScale(double font_scale);
-  void DecreaseTextSize();
-  void IncreaseTextSize();
-  void SetLinksEnabled(bool enabled);
-  void SetImagesEnabled(bool enabled);
-  void SetSelectedColorsByIndex(size_t new_index);
-  void SetSelectedLineSpacingByIndex(size_t new_index);
-  void SetSelectedLetterSpacingByIndex(size_t new_index);
-  void OnSystemThemeChanged();
-
-  ReadAnythingFontModel* GetFontModel() { return font_model_.get(); }
-  double GetFontScale() { return font_scale_; }
-  ReadAnythingColorsModel* GetColorsModel() { return colors_model_.get(); }
-  ReadAnythingLineSpacingModel* GetLineSpacingModel() {
-    return line_spacing_model_.get();
-  }
-  read_anything::mojom::LineSpacing line_spacing() { return line_spacing_; }
-  ReadAnythingLetterSpacingModel* GetLetterSpacingModel() {
-    return letter_spacing_model_.get();
-  }
-  read_anything::mojom::LetterSpacing letter_spacing() {
-    return letter_spacing_;
-  }
-
-  bool GetLinksEnabled() { return links_enabled_; }
-  bool GetImagesEnabled() { return images_enabled_; }
-
- private:
-  void NotifyThemeChanged();
-
-  // State:
-
-  // Members of read_anything::mojom::ReadAnythingTheme:
-  std::string font_name_ = string_constants::kReadAnythingPlaceholderFontName;
-  ui::ColorId foreground_color_id_ = kColorReadAnythingForeground;
-  ui::ColorId background_color_id_ = kColorReadAnythingBackground;
-
-  // Additional theme colors.
-  ui::ColorId separator_color_id_ = kColorReadAnythingSeparator;
-  ui::ColorId dropdown_color_id_ = kColorReadAnythingDropdownBackground;
-  ui::ColorId selected_dropdown_color_id_ = kColorReadAnythingDropdownSelected;
-  ui::ColorId focus_ring_color_id_ = kColorReadAnythingFocusRingBackground;
-
-  // A scale multiplier for font size (internal use only, not shown to user).
-  float font_scale_ = kReadAnythingDefaultFontScale;
-
-  bool links_enabled_ = kReadAnythingDefaultLinksEnabled;
-  bool images_enabled_ = kReadAnythingDefaultImagesEnabled;
-
-  read_anything::mojom::LineSpacing line_spacing_ = LineSpacing::kDefaultValue;
-  read_anything::mojom::LetterSpacing letter_spacing_ =
-      LetterSpacing::kDefaultValue;
-
-  // Currently selected index for colors combobox
-  int colors_combobox_index_ = 0;
-
-  base::ObserverList<Observer> observers_;
-  const std::unique_ptr<ReadAnythingFontModel> font_model_;
-  const std::unique_ptr<ReadAnythingColorsModel> colors_model_;
-  const std::unique_ptr<ReadAnythingLineSpacingModel> line_spacing_model_;
-  const std::unique_ptr<ReadAnythingLetterSpacingModel> letter_spacing_model_;
-};
-
-#endif  // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_MODEL_H_
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc
deleted file mode 100644
index b5165b41..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc
+++ /dev/null
@@ -1,275 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h"
-
-#include <vector>
-
-#include "base/feature_list.h"
-#include "build/build_config.h"
-#include "chrome/browser/ui/ui_features.h"
-#include "chrome/browser/ui/views/frame/test_with_browser_view.h"
-#include "chrome/common/accessibility/read_anything_constants.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "ui/accessibility/accessibility_features.h"
-#include "ui/accessibility/ax_updates_and_events.h"
-
-using testing::_;
-using testing::FloatNear;
-
-// TODO(b/40275871): These tests should be removed once the ReadAnythingWebUI
-// flag is fully rolled out.
-class MockReadAnythingModelObserver : public ReadAnythingModel::Observer {
- public:
-  MOCK_METHOD(void,
-              OnReadAnythingThemeChanged,
-              (const std::string& font_name,
-               double font_scale,
-               bool links_enabled,
-               bool images_enabled,
-               ui::ColorId foreground_color_id,
-               ui::ColorId background_color_id,
-               ui::ColorId separator_color_id,
-               ui::ColorId dropdown_color_id,
-               ui::ColorId selected_color_id,
-               ui::ColorId focus_ring_color_id,
-               read_anything::mojom::LineSpacing line_spacing,
-               read_anything::mojom::LetterSpacing letter_spacing),
-              (override));
-};
-
-class ReadAnythingModelTest : public TestWithBrowserView {
- public:
-  void SetUp() override {
-    scoped_feature_list_.InitWithFeatures(
-        {}, {features::kReadAnythingWebUIToolbar});
-    TestWithBrowserView::SetUp();
-
-    model_ = std::make_unique<ReadAnythingModel>();
-  }
-
-  // Wrapper methods around the ReadAnythingModel. These do nothing more
-  // than keep the below tests less verbose (simple pass-throughs).
-
-  ReadAnythingFontModel* GetFontModel() { return model_->GetFontModel(); }
-
-  // Initializing the model will populate the font model with options that work
-  // with the input language.
-  void InitModel(std::string language = "en") {
-    std::string font_name;
-    model_->Init(language, font_name, 0.5, true, false,
-                 read_anything::mojom::Colors::kDefaultValue,
-                 read_anything::mojom::LineSpacing::kLoose,
-                 read_anything::mojom::LetterSpacing::kStandard);
-  }
-
- protected:
-  std::unique_ptr<ReadAnythingModel> model_;
-
-  MockReadAnythingModelObserver model_observer_1_;
-  MockReadAnythingModelObserver model_observer_2_;
-  MockReadAnythingModelObserver model_observer_3_;
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-// TODO(crbug.com/40286096): Test is flaky on all platforms.
-TEST_F(ReadAnythingModelTest,
-       DISABLED_AddingModelObserverNotifiesAllObservers) {
-  model_->AddObserver(&model_observer_1_);
-
-  EXPECT_CALL(model_observer_1_,
-              OnReadAnythingThemeChanged(_, _, _, _, _, _, _, _, _, _, _, _))
-      .Times(1);
-
-  EXPECT_CALL(model_observer_2_,
-              OnReadAnythingThemeChanged(_, _, _, _, _, _, _, _, _, _, _, _))
-      .Times(1);
-
-  model_->AddObserver(&model_observer_2_);
-}
-
-TEST_F(ReadAnythingModelTest, RemovedModelObserversDoNotReceiveNotifications) {
-  model_->AddObserver(&model_observer_1_);
-  model_->AddObserver(&model_observer_2_);
-
-  EXPECT_CALL(model_observer_1_,
-              OnReadAnythingThemeChanged(_, _, _, _, _, _, _, _, _, _, _, _))
-      .Times(1);
-
-  EXPECT_CALL(model_observer_2_,
-              OnReadAnythingThemeChanged(_, _, _, _, _, _, _, _, _, _, _, _))
-      .Times(0);
-
-  EXPECT_CALL(model_observer_3_,
-              OnReadAnythingThemeChanged(_, _, _, _, _, _, _, _, _, _, _, _))
-      .Times(1);
-
-  model_->RemoveObserver(&model_observer_2_);
-  model_->AddObserver(&model_observer_3_);
-}
-
-TEST_F(ReadAnythingModelTest, NotificationsOnSetSelectedFontIndexaa) {
-  InitModel();
-  model_->AddObserver(&model_observer_1_);
-
-  EXPECT_CALL(model_observer_1_,
-              OnReadAnythingThemeChanged(_, _, _, _, _, _, _, _, _, _, _, _))
-      .Times(1);
-
-  model_->SetSelectedFontByIndex(2);
-}
-
-TEST_F(ReadAnythingModelTest, NotificationsOnDecreasedFontSize) {
-  model_->AddObserver(&model_observer_1_);
-
-  EXPECT_CALL(model_observer_1_,
-              OnReadAnythingThemeChanged(_, _, _, _, _, _, _, _, _, _, _, _))
-      .Times(1);
-
-  model_->DecreaseTextSize();
-
-  EXPECT_NEAR(model_->GetFontScale(), 0.75, 0.01);
-}
-
-TEST_F(ReadAnythingModelTest, NotificationsOnIncreasedFontSize) {
-  model_->AddObserver(&model_observer_1_);
-
-  EXPECT_CALL(model_observer_1_,
-              OnReadAnythingThemeChanged(_, _, _, _, _, _, _, _, _, _, _, _))
-      .Times(1);
-
-  model_->IncreaseTextSize();
-
-  EXPECT_NEAR(model_->GetFontScale(), 1.25, 0.01);
-}
-
-TEST_F(ReadAnythingModelTest, NotificationsOnSetSelectedColorsIndex) {
-  model_->AddObserver(&model_observer_1_);
-
-  EXPECT_CALL(model_observer_1_,
-              OnReadAnythingThemeChanged(_, _, _, _, _, _, _, _, _, _, _, _))
-      .Times(1);
-
-  model_->SetSelectedColorsByIndex(2);
-}
-
-TEST_F(ReadAnythingModelTest, NotificationsOnSetSelectedLineSpacingIndex) {
-  model_->AddObserver(&model_observer_1_);
-
-  EXPECT_CALL(model_observer_1_,
-              OnReadAnythingThemeChanged(_, _, _, _, _, _, _, _, _, _, _, _))
-      .Times(1);
-
-  model_->SetSelectedLineSpacingByIndex(2);
-}
-
-TEST_F(ReadAnythingModelTest, NotificationsOnSetSelectedLetterSpacingIndex) {
-  model_->AddObserver(&model_observer_1_);
-
-  EXPECT_CALL(model_observer_1_,
-              OnReadAnythingThemeChanged(_, _, _, _, _, _, _, _, _, _, _, _))
-      .Times(1);
-
-  model_->SetSelectedLetterSpacingByIndex(2);
-}
-
-TEST_F(ReadAnythingModelTest, NotificationsOnSystemThemeChanged) {
-  model_->AddObserver(&model_observer_1_);
-
-  EXPECT_CALL(model_observer_1_,
-              OnReadAnythingThemeChanged(_, _, _, _, _, _, _, _, _, _, _, _))
-      .Times(1);
-
-  model_->OnSystemThemeChanged();
-}
-
-TEST_F(ReadAnythingModelTest, NotificationOnSetLinksEnabled) {
-  model_->AddObserver(&model_observer_1_);
-
-  EXPECT_CALL(model_observer_1_,
-              OnReadAnythingThemeChanged(_, _, _, _, _, _, _, _, _, _, _, _))
-      .Times(1);
-
-  model_->SetLinksEnabled(false);
-}
-
-TEST_F(ReadAnythingModelTest, MinimumFontScaleIsEnforced) {
-  std::string font_name;
-  std::string language;
-  model_->Init(language, font_name, 0.5, true, false,
-               read_anything::mojom::Colors::kDefaultValue,
-               read_anything::mojom::LineSpacing::kLoose,
-               read_anything::mojom::LetterSpacing::kStandard);
-  model_->DecreaseTextSize();
-  EXPECT_NEAR(model_->GetFontScale(), 0.5, 0.01);
-}
-
-TEST_F(ReadAnythingModelTest, MaximumFontScaleIsEnforced) {
-  std::string font_name;
-  std::string language;
-  model_->Init(language, font_name, 4.5, true, false,
-               read_anything::mojom::Colors::kDefaultValue,
-               read_anything::mojom::LineSpacing::kLoose,
-               read_anything::mojom::LetterSpacing::kStandard);
-  model_->IncreaseTextSize();
-  EXPECT_NEAR(model_->GetFontScale(), 4.5, 0.01);
-}
-
-TEST_F(ReadAnythingModelTest, FontModelGetFontNameEnglishOptions) {
-  InitModel();
-  EXPECT_EQ("Poppins", GetFontModel()->GetFontNameAt(0));
-  EXPECT_EQ("Sans-serif", GetFontModel()->GetFontNameAt(1));
-  EXPECT_EQ("Serif", GetFontModel()->GetFontNameAt(2));
-  EXPECT_EQ("Comic Neue", GetFontModel()->GetFontNameAt(3));
-  EXPECT_EQ("Lexend Deca", GetFontModel()->GetFontNameAt(4));
-  EXPECT_EQ("EB Garamond", GetFontModel()->GetFontNameAt(5));
-  EXPECT_EQ("STIX Two Text", GetFontModel()->GetFontNameAt(6));
-  EXPECT_EQ("Andika", GetFontModel()->GetFontNameAt(7));
-}
-
-TEST_F(ReadAnythingModelTest, FontModelGetFontNameChineseOptions) {
-  InitModel("zh");
-  EXPECT_EQ("Sans-serif", GetFontModel()->GetFontNameAt(0));
-  EXPECT_EQ("Serif", GetFontModel()->GetFontNameAt(1));
-}
-
-TEST_F(ReadAnythingModelTest, FontModelGetFontNameVietnameseOptions) {
-  InitModel("vi");
-  EXPECT_EQ("Sans-serif", GetFontModel()->GetFontNameAt(0));
-  EXPECT_EQ("Serif", GetFontModel()->GetFontNameAt(1));
-  EXPECT_EQ("Lexend Deca", GetFontModel()->GetFontNameAt(2));
-  EXPECT_EQ("EB Garamond", GetFontModel()->GetFontNameAt(3));
-  EXPECT_EQ("STIX Two Text", GetFontModel()->GetFontNameAt(4));
-}
-
-TEST_F(ReadAnythingModelTest, DefaultIndexSetOnSetSelectedFontByIndex) {
-  InitModel();
-  size_t testIndex = 2;
-  model_->SetSelectedFontByIndex(testIndex);
-  EXPECT_EQ(testIndex, GetFontModel()->GetDefaultIndexForTesting().value());
-}
-
-TEST_F(ReadAnythingModelTest, FontModelHasDefaultNullOptColors) {
-  EXPECT_FALSE(GetFontModel()->GetDropdownForegroundColorIdAt(0).has_value());
-  EXPECT_FALSE(GetFontModel()->GetDropdownBackgroundColorIdAt(0).has_value());
-  EXPECT_FALSE(
-      GetFontModel()->GetDropdownSelectedBackgroundColorIdAt(0).has_value());
-}
-
-TEST_F(ReadAnythingModelTest, FontModelSetsDropdownAndForegroundColors) {
-  ReadAnythingColorsModel* color_model = model_->GetColorsModel();
-  ReadAnythingColorsModel::ColorInfo color_info = color_model->GetColorsAt(2);
-
-  GetFontModel()->SetForegroundColorId(color_info.foreground_color_id);
-  GetFontModel()->SetBackgroundColorId(color_info.dropdown_color_id);
-  GetFontModel()->SetSelectedBackgroundColorId(
-      color_info.selected_dropdown_color_id);
-
-  EXPECT_EQ(color_info.foreground_color_id,
-            GetFontModel()->GetDropdownForegroundColorIdAt(0).value());
-  EXPECT_EQ(color_info.dropdown_color_id,
-            GetFontModel()->GetDropdownBackgroundColorIdAt(0).value());
-  EXPECT_EQ(color_info.selected_dropdown_color_id,
-            GetFontModel()->GetDropdownSelectedBackgroundColorIdAt(0).value());
-}
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.cc
index 0c76a9c..87c4d51 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.cc
@@ -13,11 +13,8 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_tab_helper.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_container_view.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_web_view.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_registry.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_web_ui_view.h"
 #include "chrome/browser/ui/webui/side_panel/read_anything/read_anything_prefs.h"
@@ -39,83 +36,7 @@
 
 ReadAnythingSidePanelController::ReadAnythingSidePanelController(
     content::WebContents* web_contents)
-    : web_contents_(web_contents) {
-  // Create the model and initialize it with user prefs (if present).
-  model_ = std::make_unique<ReadAnythingModel>();
-  InitModelWithUserPrefs();
-
-  // Create the controller.
-  controller_ =
-      std::make_unique<ReadAnythingController>(model_.get(), web_contents_);
-}
-
-void ReadAnythingSidePanelController::InitModelWithUserPrefs() {
-  if (!Profile::FromBrowserContext(web_contents_->GetBrowserContext()) ||
-      !Profile::FromBrowserContext(web_contents_->GetBrowserContext())
-           ->GetPrefs()) {
-    return;
-  }
-
-  // Get user's default language to check for compatible fonts.
-  language::LanguageModel* language_model =
-      LanguageModelManagerFactory::GetForBrowserContext(
-          Profile::FromBrowserContext(web_contents_->GetBrowserContext()))
-          ->GetPrimaryModel();
-  std::string prefs_lang = language_model->GetLanguages().front().lang_code;
-  prefs_lang = language::ExtractBaseLanguage(prefs_lang);
-
-  std::string prefs_font_name =
-      Profile::FromBrowserContext(web_contents_->GetBrowserContext())
-          ->GetPrefs()
-          ->GetString(prefs::kAccessibilityReadAnythingFontName);
-
-  double prefs_font_scale =
-      Profile::FromBrowserContext(web_contents_->GetBrowserContext())
-          ->GetPrefs()
-          ->GetDouble(prefs::kAccessibilityReadAnythingFontScale);
-
-  bool prefs_links_enabled =
-      Profile::FromBrowserContext(web_contents_->GetBrowserContext())
-          ->GetPrefs()
-          ->GetBoolean(prefs::kAccessibilityReadAnythingLinksEnabled);
-
-  bool prefs_images_enabled =
-      Profile::FromBrowserContext(web_contents_->GetBrowserContext())
-          ->GetPrefs()
-          ->GetBoolean(prefs::kAccessibilityReadAnythingImagesEnabled);
-
-  read_anything::mojom::Colors prefs_colors =
-      static_cast<read_anything::mojom::Colors>(
-          Profile::FromBrowserContext(web_contents_->GetBrowserContext())
-              ->GetPrefs()
-              ->GetInteger(prefs::kAccessibilityReadAnythingColorInfo));
-
-  read_anything::mojom::LineSpacing prefs_line_spacing =
-      static_cast<read_anything::mojom::LineSpacing>(
-          Profile::FromBrowserContext(web_contents_->GetBrowserContext())
-              ->GetPrefs()
-              ->GetInteger(prefs::kAccessibilityReadAnythingLineSpacing));
-
-  read_anything::mojom::LetterSpacing prefs_letter_spacing =
-      static_cast<read_anything::mojom::LetterSpacing>(
-          Profile::FromBrowserContext(web_contents_->GetBrowserContext())
-              ->GetPrefs()
-              ->GetInteger(prefs::kAccessibilityReadAnythingLetterSpacing));
-
-  model_->Init(
-      /* lang code = */ prefs_lang,
-      /* font name = */ prefs_font_name,
-      /* font scale = */ prefs_font_scale,
-      /* links enabled = */ prefs_links_enabled,
-      /* images_enabled = */ prefs_images_enabled,
-      /* colors = */ prefs_colors,
-      /* line spacing = */ prefs_line_spacing,
-      /* letter spacing = */ prefs_letter_spacing);
-  default_language_code_ = prefs_lang;
-  for (ReadAnythingSidePanelController::Observer& obs : observers_) {
-    obs.SetDefaultLanguageCode(prefs_lang);
-  }
-}
+    : web_contents_(web_contents) {}
 
 ReadAnythingSidePanelController::~ReadAnythingSidePanelController() {
   // Inform observers when |this| is destroyed so they can do their own cleanup.
@@ -155,23 +76,16 @@
 void ReadAnythingSidePanelController::AddPageHandlerAsObserver(
     base::WeakPtr<ReadAnythingUntrustedPageHandler> page_handler) {
   AddObserver(page_handler.get());
-  AddModelObserver(page_handler.get());
 }
 
 void ReadAnythingSidePanelController::RemovePageHandlerAsObserver(
     base::WeakPtr<ReadAnythingUntrustedPageHandler> page_handler) {
   RemoveObserver(page_handler.get());
-  RemoveModelObserver(page_handler.get());
 }
 
 void ReadAnythingSidePanelController::AddObserver(
     ReadAnythingSidePanelController::Observer* observer) {
   observers_.AddObserver(observer);
-
-  // InitModelWithUserPrefs where default_language_code_ is set may be called
-  // before all observerers have been added, so ensure that observers are
-  // updated with the correct language code as they're added.
-  observer->SetDefaultLanguageCode(default_language_code_);
 }
 
 void ReadAnythingSidePanelController::RemoveObserver(
@@ -179,18 +93,6 @@
   observers_.RemoveObserver(observer);
 }
 
-void ReadAnythingSidePanelController::AddModelObserver(
-    ReadAnythingModel::Observer* observer) {
-  DCHECK(model_);
-  model_->AddObserver(observer);
-}
-
-void ReadAnythingSidePanelController::RemoveModelObserver(
-    ReadAnythingModel::Observer* observer) {
-  DCHECK(model_);
-  model_->RemoveObserver(observer);
-}
-
 void ReadAnythingSidePanelController::OnEntryShown(SidePanelEntry* entry) {
   CHECK_EQ(entry->key().id(), SidePanelEntry::Id::kReadAnything);
   if (Browser* browser = chrome::FindBrowserWithTab(web_contents_)) {
@@ -218,23 +120,5 @@
   auto web_view = std::make_unique<ReadAnythingSidePanelWebView>(
       Profile::FromBrowserContext(web_contents_->GetBrowserContext()));
 
-  if (features::IsReadAnythingWebUIToolbarEnabled()) {
-    return std::move(web_view);
-  }
-
-  // Create the views.
-  auto toolbar = std::make_unique<ReadAnythingToolbarView>(
-      this,
-      /*toolbar_delegate=*/controller_.get(),
-      /*font_combobox_delegate=*/controller_.get());
-
-  // Create the component.
-  // Note that a side panel controller would normally maintain ownership of
-  // these objects, but objects extending {ui/views/view.h} prefer ownership
-  // over raw pointers (View ownership is typically managed by the View
-  // hierarchy, rather than by outside controllers).
-  auto container_view = std::make_unique<ReadAnythingContainerView>(
-      this, std::move(toolbar), std::move(web_view));
-
-  return std::move(container_view);
+  return std::move(web_view);
 }
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.h
index b7ac52e3..fdd37b3 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.h
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.h
@@ -6,7 +6,6 @@
 #define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_SIDE_PANEL_CONTROLLER_H_
 
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_tab_helper.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_entry_observer.h"
 
 namespace content {
@@ -17,7 +16,6 @@
 class View;
 }  // namespace views
 
-class ReadAnythingController;
 class ReadAnythingUntrustedPageHandler;
 
 // A per-tab class that facilitates the showing of the Read Anything side panel.
@@ -28,7 +26,6 @@
    public:
     virtual void Activate(bool active) {}
     virtual void OnSidePanelControllerDestroyed() = 0;
-    virtual void SetDefaultLanguageCode(const std::string& code) {}
   };
   explicit ReadAnythingSidePanelController(content::WebContents* web_contents);
   ReadAnythingSidePanelController(const ReadAnythingSidePanelController&) =
@@ -51,18 +48,12 @@
 
   void AddObserver(ReadAnythingSidePanelController::Observer* observer);
   void RemoveObserver(ReadAnythingSidePanelController::Observer* observer);
-  void AddModelObserver(ReadAnythingModel::Observer* observer);
-  void RemoveModelObserver(ReadAnythingModel::Observer* observer);
 
  private:
-  // Used during construction to initialize the model with saved user prefs.
-  void InitModelWithUserPrefs();
   // Creates the container view and all its child views for side panel entry.
   std::unique_ptr<views::View> CreateContainerView();
 
   std::string default_language_code_;
-  std::unique_ptr<ReadAnythingModel> model_;
-  std::unique_ptr<ReadAnythingController> controller_;
 
   base::ObserverList<ReadAnythingSidePanelController::Observer> observers_;
 
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toggle_button_view.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toggle_button_view.cc
deleted file mode 100644
index 6c25f18f..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toggle_button_view.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2024 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_toggle_button_view.h"
-
-#include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h"
-#include "ui/base/metadata/metadata_impl_macros.h"
-#include "ui/base/models/image_model.h"
-#include "ui/views/controls/button/image_button.h"
-#include "ui/views/controls/button/image_button_factory.h"
-#include "ui/views/controls/highlight_path_generator.h"
-
-ReadAnythingToggleButtonView::ReadAnythingToggleButtonView(
-    bool initial_toggled_state,
-    views::ImageButton::PressedCallback callback,
-    const std::u16string& toggled_tooltip,
-    const std::u16string& untoggled_tooltip)
-    : views::ToggleImageButton(std::move(callback)) {
-  ConfigureInkDropForToolbar(this);
-  views::InstallCircleHighlightPathGenerator(this);
-  SetTooltipText(untoggled_tooltip);
-  SetToggledTooltipText(toggled_tooltip);
-
-  SetToggled(initial_toggled_state);
-}
-
-ReadAnythingToggleButtonView::~ReadAnythingToggleButtonView() = default;
-
-void ReadAnythingToggleButtonView::UpdateIcons(
-    const gfx::VectorIcon& toggled_icon,
-    const gfx::VectorIcon& untoggled_icon,
-    int icon_size,
-    ui::ColorId icon_color,
-    ui::ColorId focus_ring_color) {
-  views::SetImageFromVectorIconWithColorId(this, untoggled_icon, icon_color,
-                                           icon_color, icon_size);
-  views::SetToggledImageFromVectorIconWithColorId(
-      this, toggled_icon, icon_color, icon_color, icon_size);
-  auto* focus_ring = views::FocusRing::Get(this);
-  CHECK(focus_ring);
-  focus_ring->SetColorId(focus_ring_color);
-}
-
-bool ReadAnythingToggleButtonView::IsGroupFocusTraversable() const {
-  // Only the first item in the toolbar should be reachable with tab.
-  return false;
-}
-
-BEGIN_METADATA(ReadAnythingToggleButtonView)
-END_METADATA
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toggle_button_view.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toggle_button_view.h
deleted file mode 100644
index 95d321b..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toggle_button_view.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2024 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_TOGGLE_BUTTON_VIEW_H_
-#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_TOGGLE_BUTTON_VIEW_H_
-
-#include <string>
-
-#include "base/functional/callback_forward.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_button_view.h"
-#include "ui/base/metadata/metadata_header_macros.h"
-#include "ui/color/color_id.h"
-#include "ui/gfx/vector_icon_types.h"
-#include "ui/views/controls/button/image_button.h"
-
-class ReadAnythingToggleButtonView : public views::ToggleImageButton {
-  METADATA_HEADER(ReadAnythingToggleButtonView, views::ToggleImageButton)
- public:
-  ReadAnythingToggleButtonView(bool initial_toggled_state,
-                               views::ImageButton::PressedCallback callback,
-                               const std::u16string& toggled_tooltip,
-                               const std::u16string& untoggled_tooltip);
-  ReadAnythingToggleButtonView(const ReadAnythingToggleButtonView&) = delete;
-  ReadAnythingToggleButtonView& operator=(const ReadAnythingToggleButtonView&) =
-      delete;
-  ~ReadAnythingToggleButtonView() override;
-
-  void UpdateIcons(const gfx::VectorIcon& toggled_icon,
-                   const gfx::VectorIcon& untoggled_icon,
-                   int icon_size,
-                   ui::ColorId icon_color,
-                   ui::ColorId focus_ring_color);
-
-  bool IsGroupFocusTraversable() const override;
-};
-
-#endif  // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_TOGGLE_BUTTON_VIEW_H_
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.cc
deleted file mode 100644
index 5bc88701..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.cc
+++ /dev/null
@@ -1,338 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h"
-
-#include <algorithm>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "chrome/app/vector_icons/vector_icons.h"
-#include "chrome/browser/ui/color/chrome_color_id.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_toggle_button_view.h"
-#include "chrome/common/accessibility/read_anything_constants.h"
-#include "chrome/grit/generated_resources.h"
-#include "ui/accessibility/accessibility_features.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/metadata/metadata_impl_macros.h"
-#include "ui/color/color_id.h"
-#include "ui/color/color_provider.h"
-#include "ui/gfx/color_palette.h"
-#include "ui/gfx/color_utils.h"
-#include "ui/gfx/geometry/geometry_export.h"
-#include "ui/gfx/paint_vector_icon.h"
-#include "ui/views/background.h"
-#include "ui/views/controls/button/image_button_factory.h"
-#include "ui/views/controls/combobox/combobox.h"
-#include "ui/views/controls/highlight_path_generator.h"
-#include "ui/views/controls/separator.h"
-#include "ui/views/layout/box_layout.h"
-#include "ui/views/layout/flex_layout.h"
-
-// TODO(crbug.com/40909106): Remove unused constructor when the
-// ReadAnythingLocalSidePanel flag is removed.
-ReadAnythingToolbarView::ReadAnythingToolbarView(
-    ReadAnythingCoordinator* coordinator,
-    ReadAnythingToolbarView::Delegate* toolbar_delegate,
-    ReadAnythingFontCombobox::Delegate* font_combobox_delegate)
-    : delegate_(toolbar_delegate), coordinator_(std::move(coordinator)) {
-  coordinator_->AddObserver(this);
-  Init(toolbar_delegate, font_combobox_delegate);
-  // Start observing model after views creation so initial theme is applied.
-  coordinator_->AddModelObserver(this);
-}
-
-ReadAnythingToolbarView::ReadAnythingToolbarView(
-    ReadAnythingSidePanelController* controller,
-    ReadAnythingToolbarView::Delegate* toolbar_delegate,
-    ReadAnythingFontCombobox::Delegate* font_combobox_delegate)
-    : delegate_(toolbar_delegate), controller_(std::move(controller)) {
-  controller_->AddObserver(this);
-  Init(toolbar_delegate, font_combobox_delegate);
-  // Start observing model after views creation so initial theme is applied.
-  controller_->AddModelObserver(this);
-}
-
-void ReadAnythingToolbarView::Init(
-    ReadAnythingToolbarView::Delegate* toolbar_delegate,
-    ReadAnythingFontCombobox::Delegate* font_combobox_delegate) {
-  // Set a FlexLayout LayoutManager for this view.
-  SetLayoutManager(std::make_unique<views::FlexLayout>())
-      ->SetOrientation(views::LayoutOrientation::kHorizontal)
-      .SetDefault(views::kMarginsKey, gfx::Insets::VH(0, kButtonPadding))
-      .SetMainAxisAlignment(views::LayoutAlignment::kStart)
-      .SetInteriorMargin(gfx::Insets(kInternalInsets));
-
-  // Create a font selection combobox for the toolbar. The font combobox uses
-  // a custom MenuModel, so we have a separate View for it for convenience.
-  auto combobox =
-      std::make_unique<ReadAnythingFontCombobox>(font_combobox_delegate);
-
-  // Font combobox should shrink as panel gets smaller.
-  combobox->SetProperty(
-      views::kFlexBehaviorKey,
-      views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToMinimum));
-  combobox->SetGroup(kToolbarGroupId);
-
-  // Create the decrease/increase text size buttons.
-  auto decrease_size_button = std::make_unique<ReadAnythingButtonView>(
-      base::BindRepeating(&ReadAnythingToolbarView::DecreaseFontSizeCallback,
-                          weak_pointer_factory_.GetWeakPtr()),
-      l10n_util::GetStringUTF16(
-          IDS_READING_MODE_DECREASE_FONT_SIZE_BUTTON_LABEL));
-  decrease_size_button->SetProperty(views::kCrossAxisAlignmentKey,
-                                    views::LayoutAlignment::kCenter);
-  decrease_size_button->SetGroup(kToolbarGroupId);
-
-  auto increase_size_button = std::make_unique<ReadAnythingButtonView>(
-      base::BindRepeating(&ReadAnythingToolbarView::IncreaseFontSizeCallback,
-                          weak_pointer_factory_.GetWeakPtr()),
-      l10n_util::GetStringUTF16(
-          IDS_READING_MODE_INCREASE_FONT_SIZE_BUTTON_LABEL));
-  increase_size_button->SetProperty(views::kCrossAxisAlignmentKey,
-                                    views::LayoutAlignment::kCenter);
-  increase_size_button->SetGroup(kToolbarGroupId);
-
-  // Create link toggle button.
-  auto toggle_links_button = std::make_unique<ReadAnythingToggleButtonView>(
-      delegate_->GetLinksEnabled(),
-      base::BindRepeating(&ReadAnythingToolbarView::LinksToggledCallback,
-                          weak_pointer_factory_.GetWeakPtr()),
-      l10n_util::GetStringUTF16(IDS_READING_MODE_DISABLE_LINKS_BUTTON_LABEL),
-      l10n_util::GetStringUTF16(IDS_READING_MODE_ENABLE_LINKS_BUTTON_LABEL));
-
-  toggle_links_button->SetProperty(views::kCrossAxisAlignmentKey,
-                                   views::LayoutAlignment::kCenter);
-  toggle_links_button->SetGroup(kToolbarGroupId);
-
-  // Create theme selection menubutton.
-  auto colors_button = std::make_unique<ReadAnythingMenuButton>(
-      base::BindRepeating(&ReadAnythingToolbarView::ChangeColorsCallback,
-                          weak_pointer_factory_.GetWeakPtr()),
-      kPaletteIcon,
-      l10n_util::GetStringUTF16(IDS_READING_MODE_COLORS_COMBOBOX_LABEL),
-      delegate_->GetColorsModel());
-  colors_button->SetGroup(kToolbarGroupId);
-
-  // Create line spacing menubutton.
-  auto line_spacing_button = std::make_unique<ReadAnythingMenuButton>(
-      base::BindRepeating(&ReadAnythingToolbarView::ChangeLineSpacingCallback,
-                          weak_pointer_factory_.GetWeakPtr()),
-      kReadAnythingLineSpacingIcon,
-      l10n_util::GetStringUTF16(IDS_READING_MODE_LINE_SPACING_COMBOBOX_LABEL),
-      delegate_->GetLineSpacingModel());
-  line_spacing_button->SetGroup(kToolbarGroupId);
-
-  // Create letter spacing menubutton.
-  auto letter_spacing_button = std::make_unique<ReadAnythingMenuButton>(
-      base::BindRepeating(&ReadAnythingToolbarView::ChangeLetterSpacingCallback,
-                          weak_pointer_factory_.GetWeakPtr()),
-      kReadAnythingLetterSpacingIcon,
-      l10n_util::GetStringUTF16(IDS_READING_MODE_LETTER_SPACING_COMBOBOX_LABEL),
-      delegate_->GetLetterSpacingModel());
-  letter_spacing_button->SetGroup(kToolbarGroupId);
-
-  // Add all views as children.
-  font_combobox_ = AddChildView(std::move(combobox));
-  AddChildView(Separator());
-  decrease_text_size_button_ = AddChildView(std::move(decrease_size_button));
-  increase_text_size_button_ = AddChildView(std::move(increase_size_button));
-  AddChildView(Separator());
-  toggle_links_button_ = AddChildView(std::move(toggle_links_button));
-  colors_button_ = AddChildView(std::move(colors_button));
-  line_spacing_button_ = AddChildView(std::move(line_spacing_button));
-  letter_spacing_button_ = AddChildView(std::move(letter_spacing_button));
-}
-
-void ReadAnythingToolbarView::OnThemeChanged() {
-  views::View::OnThemeChanged();
-  if (delegate_) {
-    delegate_->OnSystemThemeChanged();
-  }
-}
-
-// After this view is added to the widget, we have access to the color provider
-// to apply the initial theme skcolors.
-void ReadAnythingToolbarView::AddedToWidget() {
-  ChangeColorsCallback();
-}
-
-void ReadAnythingToolbarView::DecreaseFontSizeCallback() {
-  if (delegate_) {
-    delegate_->OnFontSizeChanged(/* increase = */ false);
-  }
-}
-
-void ReadAnythingToolbarView::IncreaseFontSizeCallback() {
-  if (delegate_) {
-    delegate_->OnFontSizeChanged(/* increase = */ true);
-  }
-}
-
-void ReadAnythingToolbarView::ChangeColorsCallback() {
-  if (delegate_) {
-    delegate_->OnColorsChanged(colors_button_->GetSelectedIndex().value_or(0));
-  }
-}
-
-void ReadAnythingToolbarView::ChangeLineSpacingCallback() {
-  if (delegate_) {
-    delegate_->OnLineSpacingChanged(
-        line_spacing_button_->GetSelectedIndex().value_or(1));
-  }
-}
-
-void ReadAnythingToolbarView::ChangeLetterSpacingCallback() {
-  if (delegate_) {
-    delegate_->OnLetterSpacingChanged(
-        letter_spacing_button_->GetSelectedIndex().value_or(0));
-  }
-}
-
-void ReadAnythingToolbarView::LinksToggledCallback() {
-  const bool toggled = !toggle_links_button_->GetToggled();
-  toggle_links_button_->SetToggled(toggled);
-  if (delegate_) {
-    delegate_->OnLinksEnabledChanged(toggled);
-  }
-}
-
-void ReadAnythingToolbarView::OnCoordinatorDestroyed() {
-  // When the coordinator that created |this| is destroyed, clean up pointers.
-  coordinator_ = nullptr;
-  CleanUp();
-}
-
-void ReadAnythingToolbarView::OnSidePanelControllerDestroyed() {
-  // When the side panel controller that created |this| is destroyed, clean up
-  // pointers.
-  controller_ = nullptr;
-  CleanUp();
-}
-
-void ReadAnythingToolbarView::CleanUp() {
-  delegate_ = nullptr;
-  font_combobox_->SetModel(nullptr);
-  colors_button_->SetMenuModel(nullptr);
-  line_spacing_button_->SetMenuModel(nullptr);
-  letter_spacing_button_->SetMenuModel(nullptr);
-}
-
-void ReadAnythingToolbarView::OnReadAnythingThemeChanged(
-    const std::string& font_name,
-    double font_scale,
-    bool links_enabled,
-    bool images_enabled,
-    ui::ColorId foreground_color_id,
-    ui::ColorId background_color_id,
-    ui::ColorId separator_color_id,
-    ui::ColorId dropdown_color_id,
-    ui::ColorId selected_dropdown_color_id,
-    ui::ColorId focus_ring_color_id,
-    read_anything::mojom::LineSpacing line_spacing,
-    read_anything::mojom::LetterSpacing letter_spacing) {
-  if (font_scale > kReadAnythingMinimumFontScale) {
-    decrease_text_size_button_->Enable();
-  } else {
-    decrease_text_size_button_->Disable();
-  }
-  if (font_scale < kReadAnythingMaximumFontScale) {
-    increase_text_size_button_->Enable();
-  } else {
-    increase_text_size_button_->Disable();
-  }
-
-  if (!GetColorProvider()) {
-    return;
-  }
-
-  SetBackground(views::CreateThemedSolidBackground(background_color_id));
-  font_combobox_->SetBackgroundColorId(background_color_id);
-  font_combobox_->SetFocusRingColorId(focus_ring_color_id);
-  colors_button_->SetBackground(
-      views::CreateThemedSolidBackground(background_color_id));
-  line_spacing_button_->SetBackground(
-      views::CreateThemedSolidBackground(background_color_id));
-  letter_spacing_button_->SetBackground(
-      views::CreateThemedSolidBackground(background_color_id));
-
-  decrease_text_size_button_->UpdateIcon(kTextDecreaseIcon, kFontSizeIconSize,
-                                         foreground_color_id,
-                                         focus_ring_color_id);
-
-  increase_text_size_button_->UpdateIcon(kTextIncreaseIcon, kFontSizeIconSize,
-                                         foreground_color_id,
-                                         focus_ring_color_id);
-
-  toggle_links_button_->UpdateIcons(
-      kReadAnythingLinksEnabledIcon, kReadAnythingLinksDisabledIcon,
-      kLinkToggleIconSize, foreground_color_id, focus_ring_color_id);
-
-  colors_button_->SetIcon(kPaletteIcon, kIconSize, foreground_color_id,
-                          focus_ring_color_id);
-
-  line_spacing_button_->SetIcon(kReadAnythingLineSpacingIcon, kIconSize,
-                                foreground_color_id, focus_ring_color_id);
-  letter_spacing_button_->SetIcon(kReadAnythingLetterSpacingIcon, kIconSize,
-                                  foreground_color_id, focus_ring_color_id);
-
-  // Update the background colors for the dropdowns.
-  colors_button_->SetDropdownColorIds(dropdown_color_id, foreground_color_id,
-                                      selected_dropdown_color_id);
-  letter_spacing_button_->SetDropdownColorIds(
-      dropdown_color_id, foreground_color_id, selected_dropdown_color_id);
-  line_spacing_button_->SetDropdownColorIds(
-      dropdown_color_id, foreground_color_id, selected_dropdown_color_id);
-  font_combobox_->SetDropdownColorIds(dropdown_color_id, foreground_color_id,
-                                      selected_dropdown_color_id);
-
-  for (views::Separator* separator : separators_) {
-    separator->SetColorId(separator_color_id);
-  }
-
-  font_combobox_->SetForegroundColorId(foreground_color_id);
-}
-
-std::unique_ptr<views::View> ReadAnythingToolbarView::Separator() {
-  // Create a simple separator with padding to be inserted into views.
-  auto separator_container = std::make_unique<views::View>();
-
-  auto separator_layout_manager = std::make_unique<views::BoxLayout>(
-      views::BoxLayout::Orientation::kHorizontal);
-  separator_layout_manager->set_inside_border_insets(
-      gfx::Insets(kButtonPadding)
-          .set_top(kSeparatorTopBottomPadding)
-          .set_bottom(kSeparatorTopBottomPadding));
-
-  separator_container->SetLayoutManager(std::move(separator_layout_manager));
-
-  auto separator = std::make_unique<views::Separator>();
-  separators_.push_back(
-      separator_container->AddChildView(std::move(separator)));
-
-  return separator_container;
-}
-
-void ReadAnythingToolbarView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
-  node_data->role = ax::mojom::Role::kToolbar;
-  node_data->SetNameChecked(
-      l10n_util::GetStringUTF16(IDS_READING_MODE_TOOLBAR_LABEL));
-}
-
-ReadAnythingToolbarView::~ReadAnythingToolbarView() {
-  // If |this| is being destroyed before the associated coordinator or side
-  // panel controller, then remove |this| as an observer.
-  if (features::IsReadAnythingLocalSidePanelEnabled() && controller_) {
-    controller_->RemoveObserver(this);
-    controller_->RemoveModelObserver(this);
-  } else if (coordinator_) {
-    coordinator_->RemoveObserver(this);
-    coordinator_->RemoveModelObserver(this);
-  }
-}
-
-BEGIN_METADATA(ReadAnythingToolbarView)
-END_METADATA
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h
deleted file mode 100644
index a0e688b..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_toolbar_view.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_TOOLBAR_VIEW_H_
-#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_TOOLBAR_VIEW_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/memory/raw_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_button_view.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_font_combobox.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_button.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_menu_model.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_toggle_button_view.h"
-#include "ui/base/metadata/metadata_header_macros.h"
-#include "ui/base/metadata/metadata_impl_macros.h"
-#include "ui/base/models/combobox_model.h"
-#include "ui/views/controls/combobox/combobox.h"
-#include "ui/views/controls/separator.h"
-#include "ui/views/view.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingToolbarView
-//
-//  The toolbar for Read Anything.
-//  This class is either created by the ReadAnythingCoordinator (when the side
-//  panel entry is global) or the ReadAnythingSidePanelController (when the side
-//  panel entry is local) and owned by the ReadAnythingContainerView. It has the
-//  same lifetime as the Side Panel view.
-//
-class ReadAnythingToolbarView
-    : public views::View,
-      public ReadAnythingModel::Observer,
-      public ReadAnythingCoordinator::Observer,
-      public ReadAnythingSidePanelController::Observer {
-  METADATA_HEADER(ReadAnythingToolbarView, views::View)
-
- public:
-  class Delegate {
-   public:
-    virtual void OnFontSizeChanged(bool increase) = 0;
-    virtual void OnColorsChanged(int new_index) = 0;
-    virtual ReadAnythingMenuModel* GetColorsModel() = 0;
-    virtual void OnLineSpacingChanged(int new_index) = 0;
-    virtual ReadAnythingMenuModel* GetLineSpacingModel() = 0;
-    virtual void OnLetterSpacingChanged(int new_index) = 0;
-    virtual ReadAnythingMenuModel* GetLetterSpacingModel() = 0;
-    virtual void OnSystemThemeChanged() = 0;
-    virtual void OnLinksEnabledChanged(bool is_enabled) = 0;
-    virtual bool GetLinksEnabled() = 0;
-    virtual void OnImagesEnabledChanged(bool is_enabled) = 0;
-    virtual bool GetImagesEnabled() = 0;
-  };
-
-  ReadAnythingToolbarView(
-      ReadAnythingCoordinator* coordinator,
-      ReadAnythingToolbarView::Delegate* toolbar_delegate,
-      ReadAnythingFontCombobox::Delegate* font_combobox_delegate);
-  ReadAnythingToolbarView(
-      ReadAnythingSidePanelController* controller,
-      ReadAnythingToolbarView::Delegate* toolbar_delegate,
-      ReadAnythingFontCombobox::Delegate* font_combobox_delegate);
-  ReadAnythingToolbarView(const ReadAnythingToolbarView&) = delete;
-  ReadAnythingToolbarView& operator=(const ReadAnythingToolbarView&) = delete;
-  ~ReadAnythingToolbarView() override;
-
-  // ReadAnythingModel::Observer:
-  void OnReadAnythingThemeChanged(
-      const std::string& font_name,
-      double font_scale,
-      bool links_enabled,
-      bool images_enabled,
-      ui::ColorId foreground_color_id,
-      ui::ColorId background_color_id,
-      ui::ColorId separator_color_id,
-      ui::ColorId dropdown_color_id,
-      ui::ColorId selected_dropdown_color_id,
-      ui::ColorId focus_ring_color_id,
-      read_anything::mojom::LineSpacing line_spacing,
-      read_anything::mojom::LetterSpacing letter_spacing) override;
-
-  // ReadAnythingCoordinator::Observer:
-  void OnCoordinatorDestroyed() override;
-  // ReadAnythingSidePanelController::Observer:
-  void OnSidePanelControllerDestroyed() override;
-
- private:
-  friend class ReadAnythingToolbarViewTest;
-
-  void Init(ReadAnythingToolbarView::Delegate* toolbar_delegate,
-            ReadAnythingFontCombobox::Delegate* font_combobox_delegate);
-  void DecreaseFontSizeCallback();
-  void IncreaseFontSizeCallback();
-  void ChangeColorsCallback();
-  void ChangeLineSpacingCallback();
-  void ChangeLetterSpacingCallback();
-  void LinksToggledCallback();
-  void CleanUp();
-
-  // views::View:
-  void AddedToWidget() override;
-  void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
-  // Called when the system theme changes.
-  void OnThemeChanged() override;
-
-  std::unique_ptr<views::View> Separator();
-
-  raw_ptr<ReadAnythingFontCombobox> font_combobox_;
-  raw_ptr<ReadAnythingButtonView> decrease_text_size_button_;
-  raw_ptr<ReadAnythingButtonView> increase_text_size_button_;
-  raw_ptr<ReadAnythingToggleButtonView> toggle_links_button_;
-  raw_ptr<ReadAnythingMenuButton> colors_button_;
-  raw_ptr<ReadAnythingMenuButton> line_spacing_button_;
-  raw_ptr<ReadAnythingMenuButton> letter_spacing_button_;
-  std::vector<raw_ptr<views::Separator>> separators_;
-
-  raw_ptr<ReadAnythingToolbarView::Delegate> delegate_;
-  raw_ptr<ReadAnythingCoordinator> coordinator_;
-  raw_ptr<ReadAnythingSidePanelController> controller_;
-
-  base::WeakPtrFactory<ReadAnythingToolbarView> weak_pointer_factory_{this};
-};
-
-#endif  // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_TOOLBAR_VIEW_H_
diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
index 40549e0..964004c 100644
--- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
+++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
@@ -65,8 +65,8 @@
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/peak_gpu_memory_tracker_factory.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/common/peak_gpu_memory_tracker.h"
 #include "ipc/ipc_message.h"
 #include "third_party/metrics_proto/omnibox_event.pb.h"
 #include "ui/base/models/list_selection_model.h"
@@ -285,9 +285,9 @@
 
 void BrowserTabStripController::SelectTab(int model_index,
                                           const ui::Event& event) {
-  std::unique_ptr<content::PeakGpuMemoryTracker> tracker =
-      content::PeakGpuMemoryTracker::Create(
-          content::PeakGpuMemoryTracker::Usage::CHANGE_TAB);
+  std::unique_ptr<input::PeakGpuMemoryTracker> tracker =
+      content::PeakGpuMemoryTrackerFactory::Create(
+          input::PeakGpuMemoryTracker::Usage::CHANGE_TAB);
 
   TabStripUserGestureDetails gesture_detail(
       TabStripUserGestureDetails::GestureType::kOther, event.time_stamp());
@@ -303,7 +303,7 @@
   tabstrip_->GetWidget()
       ->GetCompositor()
       ->RequestSuccessfulPresentationTimeForNextFrame(base::BindOnce(
-          [](std::unique_ptr<content::PeakGpuMemoryTracker> tracker,
+          [](std::unique_ptr<input::PeakGpuMemoryTracker> tracker,
              const viz::FrameTimingDetails& frame_timing_details) {
             // This callback will be ran once the ui::Compositor presents the
             // next frame for the |tabstrip_|. The destruction of |tracker| will
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
index 0c64a195..edde5d4 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -35,6 +35,7 @@
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
+#include "chrome/browser/ui/tabs/features.h"
 #include "chrome/browser/ui/tabs/tab_group.h"
 #include "chrome/browser/ui/tabs/tab_group_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -559,7 +560,7 @@
   DetachToBrowserTabDragControllerTest() {
     std::vector<base::test::FeatureRef> enabled_features = {};
     if (std::get<0>(GetParam())) {
-      enabled_features.push_back(features::kSplitTabStrip);
+      enabled_features.push_back(tabs::kSplitTabStrip);
     }
     if (std::get<1>(GetParam())) {
       enabled_features.push_back(features::kTearOffWebAppTabOpensWebAppWindow);
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc
index b1a9f8d1..987bf14 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -47,6 +47,7 @@
 #include "chrome/browser/ui/browser_element_identifiers.h"
 #include "chrome/browser/ui/color/chrome_color_id.h"
 #include "chrome/browser/ui/layout_constants.h"
+#include "chrome/browser/ui/tabs/features.h"
 #include "chrome/browser/ui/tabs/tab_group_theme.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/tabs/tab_types.h"
@@ -129,7 +130,7 @@
     TabStrip* tab_strip,
     TabHoverCardController* hover_card_controller,
     TabDragContext* drag_context) {
-  if (base::FeatureList::IsEnabled(features::kSplitTabStrip)) {
+  if (base::FeatureList::IsEnabled(tabs::kSplitTabStrip)) {
     return std::make_unique<CompoundTabContainer>(
         *tab_strip, hover_card_controller, drag_context, *tab_strip, tab_strip);
   }
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest_base.cc b/chrome/browser/ui/web_applications/web_app_browsertest_base.cc
index b07f64d..84a5aba 100644
--- a/chrome/browser/ui/web_applications/web_app_browsertest_base.cc
+++ b/chrome/browser/ui/web_applications/web_app_browsertest_base.cc
@@ -250,15 +250,27 @@
 void WebAppBrowserTestBase::SetUp() {
   https_server_.AddDefaultHandlers(GetChromeTestDataDir());
   webapps::TestAppBannerManagerDesktop::SetUp();
-  InProcessBrowserTest::SetUp();
+#if BUILDFLAG(IS_CHROMEOS)
+  ChromeOSBrowserUITest::SetUp();
+#else
+  MixinBasedInProcessBrowserTest::SetUp();
+#endif
 }
 
 void WebAppBrowserTestBase::TearDown() {
-  InProcessBrowserTest::TearDown();
+#if BUILDFLAG(IS_CHROMEOS)
+  ChromeOSBrowserUITest::TearDown();
+#else
+  MixinBasedInProcessBrowserTest::TearDown();
+#endif
 }
 
 void WebAppBrowserTestBase::SetUpInProcessBrowserTestFixture() {
-  InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
+#if BUILDFLAG(IS_CHROMEOS)
+  ChromeOSBrowserUITest::SetUpInProcessBrowserTestFixture();
+#else
+  MixinBasedInProcessBrowserTest::SetUpInProcessBrowserTestFixture();
+#endif
   cert_verifier_.SetUpInProcessBrowserTestFixture();
   create_services_subscription_ =
       BrowserContextDependencyManager::GetInstance()
@@ -268,7 +280,11 @@
 }
 
 void WebAppBrowserTestBase::TearDownInProcessBrowserTestFixture() {
-  InProcessBrowserTest::TearDownInProcessBrowserTestFixture();
+#if BUILDFLAG(IS_CHROMEOS)
+  ChromeOSBrowserUITest::TearDownInProcessBrowserTestFixture();
+#else
+  MixinBasedInProcessBrowserTest::TearDownInProcessBrowserTestFixture();
+#endif
   cert_verifier_.TearDownInProcessBrowserTestFixture();
 }
 
@@ -284,7 +300,12 @@
     CloseAllAshBrowserWindows();
   }
 #endif
-  InProcessBrowserTest::TearDownOnMainThread();
+
+#if BUILDFLAG(IS_CHROMEOS)
+  ChromeOSBrowserUITest::TearDownOnMainThread();
+#else
+  MixinBasedInProcessBrowserTest::TearDownOnMainThread();
+#endif
 }
 
 void WebAppBrowserTestBase::SetUpCommandLine(
@@ -301,7 +322,12 @@
   }
 #endif
 
-  InProcessBrowserTest::SetUpOnMainThread();
+#if BUILDFLAG(IS_CHROMEOS)
+  ChromeOSBrowserUITest::SetUpOnMainThread();
+#else
+  MixinBasedInProcessBrowserTest::SetUpOnMainThread();
+#endif
+
   host_resolver()->AddRule("*", "127.0.0.1");
   ASSERT_TRUE(https_server()->Start());
 
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest_base.h b/chrome/browser/ui/web_applications/web_app_browsertest_base.h
index dc50b22..d61dd83 100644
--- a/chrome/browser/ui/web_applications/web_app_browsertest_base.h
+++ b/chrome/browser/ui/web_applications/web_app_browsertest_base.h
@@ -13,7 +13,7 @@
 #include "chrome/browser/web_applications/web_app_callback_app_identity.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
 #include "chrome/browser/web_applications/web_app_ui_manager.h"
-#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/mixin_based_in_process_browser_test.h"
 #include "components/webapps/common/web_app_id.h"
 #include "content/public/test/content_mock_cert_verifier.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
@@ -42,7 +42,7 @@
 #if BUILDFLAG(IS_CHROMEOS)
 class WebAppBrowserTestBase : public ChromeOSBrowserUITest {
 #else
-class WebAppBrowserTestBase : public InProcessBrowserTest {
+class WebAppBrowserTestBase : public MixinBasedInProcessBrowserTest {
 #endif
  public:
   WebAppBrowserTestBase();
diff --git a/chrome/browser/ui/webauthn/transport_hover_list_model.h b/chrome/browser/ui/webauthn/transport_hover_list_model.h
index 37195b9..fd3f637 100644
--- a/chrome/browser/ui/webauthn/transport_hover_list_model.h
+++ b/chrome/browser/ui/webauthn/transport_hover_list_model.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "chrome/browser/ui/webauthn/hover_list_model.h"
 #include "chrome/browser/webauthn/authenticator_request_dialog_model.h"
 #include "ui/base/models/image_model.h"
@@ -36,7 +37,8 @@
   size_t GetPreferredItemCount() const override;
 
  private:
-  const base::span<const AuthenticatorRequestDialogModel::Mechanism>
+  const base::raw_span<const AuthenticatorRequestDialogModel::Mechanism,
+                       DanglingUntriaged>
       mechanisms_;
   const std::vector<int> mechanism_indices_to_display_;
 };
diff --git a/chrome/browser/ui/webui/ash/chrome_web_ui_configs_chromeos.cc b/chrome/browser/ui/webui/ash/chrome_web_ui_configs_chromeos.cc
index 6415580..256fed7 100644
--- a/chrome/browser/ui/webui/ash/chrome_web_ui_configs_chromeos.cc
+++ b/chrome/browser/ui/webui/ash/chrome_web_ui_configs_chromeos.cc
@@ -315,7 +315,9 @@
   map.AddWebUIConfig(std::make_unique<multidevice::ProximityAuthUIConfig>());
   map.AddWebUIConfig(std::make_unique<RecorderAppUIConfig>());
   map.AddWebUIConfig(std::make_unique<RemoteMaintenanceCurtainUIConfig>());
-  map.AddWebUIConfig(MakeSanitizeUIConfig());
+  if (base::FeatureList::IsEnabled(ash::features::kSanitize)) {
+    map.AddWebUIConfig(MakeSanitizeUIConfig());
+  }
   map.AddWebUIConfig(
       MakeComponentConfigWithDelegate<ScanningUIConfig, ScanningUI,
                                       ChromeScanningAppDelegate>());
diff --git a/chrome/browser/ui/webui/ash/sanitize_dialog.cc b/chrome/browser/ui/webui/ash/sanitize_dialog.cc
new file mode 100644
index 0000000..660645f
--- /dev/null
+++ b/chrome/browser/ui/webui/ash/sanitize_dialog.cc
@@ -0,0 +1,69 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/ash/sanitize_dialog.h"
+
+#include "ash/webui/sanitize_ui/sanitize_ui.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
+
+namespace ash {
+namespace {
+std::string GetUrlForPage(SanitizeDialog::SanitizePage page) {
+  switch (page) {
+    case SanitizeDialog::SanitizePage::kDefault:
+      return kChromeUISanitizeAppURL;
+  }
+}
+}  // namespace
+
+const int kSanitizeWindowWidth = 680;
+const int kSanitizeWindowHeight = 672;
+
+// static
+void SanitizeDialog::ShowDialog(SanitizeDialog::SanitizePage page,
+                                gfx::NativeWindow parent) {
+  auto* profile = ProfileManager::GetPrimaryUserProfile();
+  auto* browser =
+      ash::FindSystemWebAppBrowser(profile, ash::SystemWebAppType::OS_SANITIZE);
+  if (browser) {
+    browser->window()->Close();
+  }
+  // Close any existing Sanitize dialog before reopening.
+  MaybeCloseExistingDialog();
+  SanitizeDialog* dialog = new SanitizeDialog(page);
+  dialog->ShowSystemDialog(parent);
+}
+
+void SanitizeDialog::MaybeCloseExistingDialog() {
+  SystemWebDialogDelegate* existing_dialog =
+      SystemWebDialogDelegate::FindInstance(kSanitizeDialogId);
+  if (existing_dialog) {
+    existing_dialog->Close();
+  }
+}
+
+SanitizeDialog::SanitizeDialog(SanitizeDialog::SanitizePage page)
+    : SystemWebDialogDelegate(GURL(GetUrlForPage(page)),
+                              /*title=*/std::u16string()) {}
+
+SanitizeDialog::~SanitizeDialog() = default;
+
+std::string SanitizeDialog::Id() {
+  return dialog_id_;
+}
+
+void SanitizeDialog::GetDialogSize(gfx::Size* size) const {
+  const display::Display display =
+      display::Screen::GetScreen()->GetPrimaryDisplay();
+  gfx::Size display_size = display.size();
+  display_size = gfx::Size(kSanitizeWindowWidth, kSanitizeWindowHeight);
+  *size = display_size;
+}
+
+}  // namespace ash
diff --git a/chrome/browser/ui/webui/ash/sanitize_dialog.h b/chrome/browser/ui/webui/ash/sanitize_dialog.h
new file mode 100644
index 0000000..0394a27
--- /dev/null
+++ b/chrome/browser/ui/webui/ash/sanitize_dialog.h
@@ -0,0 +1,49 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_ASH_SANITIZE_DIALOG_H_
+#define CHROME_BROWSER_UI_WEBUI_ASH_SANITIZE_DIALOG_H_
+
+#include "chrome/browser/ui/webui/ash/system_web_dialog_delegate.h"
+#include "ui/gfx/native_widget_types.h"
+
+namespace ash {
+
+namespace {
+
+// ID used to check if there are any other instances of the dialog open.
+constexpr char kSanitizeDialogId[] = "sanitize-dialog";
+
+}  // namespace
+
+class SanitizeDialog : public SystemWebDialogDelegate {
+ public:
+  // Used to differentiate between different pages in the app.
+  enum class SanitizePage { kDefault };
+  // `page` is the initial page shown when the app is opened.
+  static void ShowDialog(SanitizePage page = SanitizePage::kDefault,
+                         gfx::NativeWindow parent = gfx::NativeWindow());
+
+  // Closes an existing dialog if it exists.
+  static void MaybeCloseExistingDialog();
+
+ protected:
+  explicit SanitizeDialog(SanitizePage page);
+  ~SanitizeDialog() override;
+
+  SanitizeDialog(const SanitizeDialog&) = delete;
+  SanitizeDialog& operator=(const SanitizeDialog&) = delete;
+
+  // SystemWebDialogDelegate
+  std::string Id() override;
+
+  // ui::WebDialogDelegate
+  void GetDialogSize(gfx::Size* size) const override;
+
+ private:
+  const std::string dialog_id_ = kSanitizeDialogId;
+};
+}  // namespace ash
+
+#endif  // CHROME_BROWSER_UI_WEBUI_ASH_SANITIZE_DIALOG_H_
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/BUILD.gn b/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/BUILD.gn
index c6dc430..7ce6d0a1 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/BUILD.gn
+++ b/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/BUILD.gn
@@ -17,5 +17,6 @@
   public_deps = [
     "//ash/public/mojom:input_device_settings",
     "//mojo/public/mojom/base",
+    "//ui/events/ash/mojom",
   ]
 }
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.cc b/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.cc
index dacbd86..8eeac68 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.cc
@@ -718,21 +718,10 @@
   std::move(callback).Run(std::move(choices));
 }
 
-void InputDeviceSettingsProvider::HasLauncherButton(
-    HasLauncherButtonCallback callback) {
-  DCHECK(features::IsInputDeviceSettingsSplitEnabled());
-  DCHECK(InputDeviceSettingsController::Get());
-
-  auto keyboards =
-      InputDeviceSettingsController::Get()->GetConnectedKeyboards();
-  for (const ::ash::mojom::KeyboardPtr& keyboard : keyboards) {
-    if (keyboard->meta_key == ::ui::mojom::MetaKey::kLauncher) {
-      std::move(callback).Run(true);
-      return;
-    }
-  }
-
-  std::move(callback).Run(/*has_launcher_button=*/false);
+void InputDeviceSettingsProvider::GetMetaKeyToDisplay(
+    GetMetaKeyToDisplayCallback callback) {
+  std::move(callback).Run(
+      Shell::Get()->keyboard_capability()->GetMetaKeyToDisplay());
 }
 
 void InputDeviceSettingsProvider::OnReceiveHasKeyboardBacklight(
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.h b/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.h
index f039b44..a334438 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.h
@@ -148,7 +148,7 @@
   void OnWidgetDestroyed(views::Widget* widget) override;
 
   void SetWidgetForTesting(views::Widget* widget);
-  void HasLauncherButton(HasLauncherButtonCallback callback) override;
+  void GetMetaKeyToDisplay(GetMetaKeyToDisplayCallback callback) override;
   void HasKeyboardBacklight(HasKeyboardBacklightCallback callback) override;
   void HasAmbientLightSensor(HasAmbientLightSensorCallback callback) override;
   void IsRgbKeyboardSupported(IsRgbKeyboardSupportedCallback callback) override;
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.mojom b/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.mojom
index 00b05558..f4cedef 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.mojom
+++ b/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.mojom
@@ -6,6 +6,7 @@
 
 import "ash/public/mojom/input_device_settings.mojom";
 import "ash/public/mojom/accelerator_actions.mojom";
+import "ui/events/ash/mojom/meta_key.mojom";
 
 // Represents the options for user in the dropdown of button customization.
 struct ActionChoice {
@@ -166,11 +167,10 @@
   GetActionsForGraphicsTabletButtonCustomization() =>
       (array<ActionChoice> options);
 
-  // Returns whether any of the keyboards has launcher button.
-  // True if the keyboard has launcher button as meta key and we display the
-  // launcher icon in settings. False if the keyboard has other buttons as meta
-  // key and we display the search icon in settings.
-  HasLauncherButton() => (bool has_launcher_button);
+  // Returns the meta key to display in the UI to represent the overall current
+  // keyboard situation. This will only return either Launcher, Search, or
+  // LauncherRefresh.
+  GetMetaKeyToDisplay() => (ui.mojom.MetaKey meta_key);
 
   // Returns whether the internal keyboard has a backlight.
   HasKeyboardBacklight() => (bool has_keyboard_backlight);
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider_unittest.cc b/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider_unittest.cc
index 7b61152..fe2b248d 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider_unittest.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider_unittest.cc
@@ -1243,24 +1243,6 @@
   EXPECT_EQ(*expected_button, fake_observer.last_pressed_button());
 }
 
-TEST_F(InputDeviceSettingsProviderTest, HasLauncherButton) {
-  base::test::TestFuture<bool> future;
-
-  controller_->AddKeyboard(kKeyboard2.Clone());
-  controller_->AddKeyboard(kKeyboard3.Clone());
-
-  provider_->HasLauncherButton(future.GetCallback());
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_FALSE(future.Get<0>());
-  future.Clear();
-  controller_->AddKeyboard(kKeyboard1.Clone());
-  provider_->HasLauncherButton(future.GetCallback());
-  base::RunLoop().RunUntilIdle();
-
-  EXPECT_TRUE(future.Get<0>());
-}
-
 TEST_F(InputDeviceSettingsProviderTest, HasKeyboardBacklight) {
   base::test::TestFuture<bool> future;
 
diff --git a/chrome/browser/ui/webui/downloads/downloads_ui.cc b/chrome/browser/ui/webui/downloads/downloads_ui.cc
index 3ca51f607..a9a6e41 100644
--- a/chrome/browser/ui/webui/downloads/downloads_ui.cc
+++ b/chrome/browser/ui/webui/downloads/downloads_ui.cc
@@ -85,6 +85,7 @@
       {"openDownloadsFolder", IDS_DOWNLOAD_LINK_OPEN_DOWNLOADS_FOLDER},
       {"moreActions", IDS_DOWNLOAD_MORE_ACTIONS},
       {"search", IDS_DOWNLOAD_HISTORY_SEARCH},
+      {"inIncognito", IDS_DOWNLOAD_IN_INCOGNITO},
 
       // No results message that shows instead of the downloads list.
       {"noDownloads", IDS_DOWNLOAD_NO_DOWNLOADS},
@@ -95,8 +96,6 @@
       {"statusRemoved", IDS_DOWNLOAD_FILE_REMOVED},
 
       // Dangerous file.
-      {"dangerSave", IDS_CONFIRM_DOWNLOAD},
-      {"dangerRestore", IDS_CONFIRM_DOWNLOAD_RESTORE},
       {"dangerDiscard", IDS_DISCARD_DOWNLOAD},
       {"dangerReview", IDS_REVIEW_DOWNLOAD},
 
@@ -118,21 +117,17 @@
       {"promptForLocalPasswordScanningDesc",
        IDS_BLOCK_REASON_PROMPT_FOR_LOCAL_PASSWORD_SCANNING},
       {"controlDeepScan", IDS_DOWNLOAD_DEEP_SCAN_UPDATED},
-      {"controlBypassDeepScan", IDS_DOWNLOAD_BYPASS_DEEP_SCAN_UPDATED},
       {"controlLocalPasswordScan", IDS_DOWNLOAD_LOCAL_PASSWORD_SCAN},
 
       // Controls.
       {"controlPause", IDS_DOWNLOAD_LINK_PAUSE},
       {"controlCancel", IDS_DOWNLOAD_LINK_CANCEL},
       {"controlResume", IDS_DOWNLOAD_LINK_RESUME},
-      {"controlRemoveFromList", IDS_DOWNLOAD_LINK_REMOVE},
-      {"controlRemoveFromListAriaLabel", IDS_DOWNLOAD_LINK_REMOVE_ARIA_LABEL},
       {"controlRetry", IDS_DOWNLOAD_LINK_RETRY},
       {"controlledByUrl", IDS_DOWNLOAD_BY_EXTENSION_URL},
       {"controlOpenNow", IDS_OPEN_DOWNLOAD_NOW},
       {"controlOpenAnyway", IDS_OPEN_DOWNLOAD_ANYWAY},
       {"toastClearedAll", IDS_DOWNLOAD_TOAST_CLEARED_ALL},
-      {"toastRemovedFromList", IDS_DOWNLOAD_TOAST_REMOVED_FROM_LIST},
       {"toastDeletedFromHistoryStillOnDevice",
        IDS_DOWNLOADS_TOAST_DELETED_FROM_HISTORY_STILL_ON_DEVICE},
       {"toastDeletedFromHistory", IDS_DOWNLOADS_TOAST_DELETED_FROM_HISTORY},
@@ -170,14 +165,24 @@
       {"warningBypassDialogLearnMoreLink",
        IDS_DOWNLOAD_WARNING_BYPASS_DIALOG_LEARN_MORE_LINK},
       {"warningBypassDialogCancel", IDS_CANCEL},
+
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
       // ESB Download Row Promo
       {"esbDownloadRowPromoString", IDS_DOWNLOAD_ROW_ESB_PROMOTION},
       {"esbDownloadRowPromoA11y", IDS_DOWNLOAD_ROW_ESB_PROMO_A11Y},
 #endif
-      // Dangerous File
+
+      // Strings describing reasons for blocked downloads.
       {"noSafeBrowsingDesc",
        IDS_BLOCK_DOWNLOAD_REASON_UNVERIFIED_NO_SAFE_BROWSING},
+      {"dangerFileDesc", IDS_BLOCK_DOWNLOAD_REASON_DANGEROUS_FILETYPE},
+      {"dangerDownloadDesc", IDS_BLOCK_DOWNLOAD_REASON_DANGEROUS},
+      {"dangerDownloadCookieTheft",
+       IDS_BLOCK_DOWNLOAD_REASON_DANGEROUS_COOKIE_THEFT},
+      {"dangerDownloadCookieTheftAndAccountDesc",
+       IDS_BLOCK_DOWNLOAD_REASON_DANGEROUS_COOKIE_THEFT_AND_ACCOUNT},
+      {"dangerSettingsDesc", IDS_BLOCK_DOWNLOAD_REASON_POTENTIALLY_UNWANTED},
+      {"insecureDownloadDesc", IDS_BLOCK_DOWNLOAD_REASON_INSECURE},
 
       {"referrerLine", IDS_DOWNLOADS_PAGE_REFERRER_LINE},
   };
@@ -186,53 +191,16 @@
   source->AddBoolean(
       "showReferrerUrl",
       base::FeatureList::IsEnabled(safe_browsing::kDownloadsPageReferrerUrl));
-  // New chrome://downloads icons, colors, strings, etc. to be consistent with
-  // download bubble.
-  // TODO(chlily): Temporarily hardcoding true in order to remove base::Feature
-  // and references. This will be cleaned up shortly.
-  bool improved_download_warnings_ux = true;
-  source->AddBoolean("improvedDownloadWarningsUX",
-                     improved_download_warnings_ux);
-  source->AddLocalizedString("dangerFileDesc",
-                             improved_download_warnings_ux
-                                 ? IDS_BLOCK_DOWNLOAD_REASON_DANGEROUS_FILETYPE
-                                 : IDS_BLOCK_REASON_GENERIC_DOWNLOAD);
-  source->AddLocalizedString("dangerDownloadDesc",
-                             improved_download_warnings_ux
-                                 ? IDS_BLOCK_DOWNLOAD_REASON_DANGEROUS
-                                 : IDS_BLOCK_REASON_DANGEROUS_DOWNLOAD);
-  source->AddLocalizedString(
-      "dangerDownloadCookieTheft",
-      improved_download_warnings_ux
-          ? IDS_BLOCK_DOWNLOAD_REASON_DANGEROUS_COOKIE_THEFT
-          : IDS_BLOCK_REASON_DANGEROUS_DOWNLOAD);
-  source->AddLocalizedString(
-      "dangerDownloadCookieTheftAndAccountDesc",
-      improved_download_warnings_ux
-          ? IDS_BLOCK_DOWNLOAD_REASON_DANGEROUS_COOKIE_THEFT_AND_ACCOUNT
-          : IDS_BLOCK_REASON_DANGEROUS_DOWNLOAD);
   source->AddLocalizedString(
       "dangerUncommonDesc",
       requests_ap_verdicts
           ? IDS_BLOCK_REASON_UNCOMMON_DOWNLOAD_IN_ADVANCED_PROTECTION
-          : (improved_download_warnings_ux
-                 ? IDS_BLOCK_DOWNLOAD_REASON_UNCOMMON
-                 : IDS_BLOCK_REASON_UNCOMMON_DOWNLOAD));
+          : IDS_BLOCK_DOWNLOAD_REASON_UNCOMMON);
   source->AddLocalizedString(
       "dangerUncommonSuspiciousArchiveDesc",
       requests_ap_verdicts
           ? IDS_BLOCK_REASON_UNCOMMON_DOWNLOAD_IN_ADVANCED_PROTECTION
-          : (improved_download_warnings_ux
-                 ? IDS_BLOCK_DOWNLOAD_REASON_UNCOMMON_SUSPICIOUS_ARCHIVE
-                 : IDS_BLOCK_REASON_UNCOMMON_DOWNLOAD));
-  source->AddLocalizedString(
-      "dangerSettingsDesc", improved_download_warnings_ux
-                                ? IDS_BLOCK_DOWNLOAD_REASON_POTENTIALLY_UNWANTED
-                                : IDS_BLOCK_REASON_UNWANTED_DOWNLOAD);
-  source->AddLocalizedString("insecureDownloadDesc",
-                             improved_download_warnings_ux
-                                 ? IDS_BLOCK_DOWNLOAD_REASON_INSECURE
-                                 : IDS_BLOCK_REASON_INSECURE_DOWNLOAD);
+          : IDS_BLOCK_DOWNLOAD_REASON_UNCOMMON_SUSPICIOUS_ARCHIVE);
 
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // Download Row ESB Promo:
@@ -255,8 +223,6 @@
                      prefs->GetBoolean(prefs::kAllowDeletingBrowserHistory) &&
                          !profile->IsChild());
 
-  source->AddLocalizedString("inIncognito", IDS_DOWNLOAD_IN_INCOGNITO);
-
   // The URL to open when the user clicks on "Learn more" for a blocked
   // dangerous file.
   source->AddString("blockedLearnMoreUrl",
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
index 63c43e42..a049bdb 100644
--- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
+++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
@@ -606,6 +606,10 @@
        IDS_NTP_MODULES_TAB_RESUMPTION_DEVICE_PREFIX},
       {"modulesMostRelevantTabResumptionDismissAll",
        IDS_NTP_MODULES_MOST_RELEVANT_TAB_RESUMPTION_DISMISS_BUTTON},
+      {"modulesMostRelevantTabResumptionTitle",
+       IDS_NTP_MODULES_MOST_RELEVANT_TAB_RESUMPTION_TITLE},
+      {"modulesMostRelevantTabResumptionSeeMore",
+       IDS_NTP_MODULES_MOST_RELEVANT_TAB_RESUMPTION_SEE_MORE},
 
       // Middle slot promo.
       {"undoDismissPromoButtonToast", IDS_NTP_UNDO_DISMISS_PROMO_BUTTON_TOAST},
diff --git a/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc b/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc
index 560daa8..eca6bef 100644
--- a/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc
+++ b/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc
@@ -225,7 +225,7 @@
     MOJOM_TO_PROTO_SIGNAL(length_of_url);
     MOJOM_TO_PROTO_SIGNAL(site_engagement);
     MOJOM_TO_PROTO_SIGNAL(allowed_to_be_default_match);
-    PROTO_TO_MOJOM_SIGNAL(search_suggest_relevance);
+    MOJOM_TO_PROTO_SIGNAL(search_suggest_relevance);
 
     return signals;
   }
diff --git a/chrome/browser/ui/webui/policy/policy_ui.cc b/chrome/browser/ui/webui/policy/policy_ui.cc
index a698afb..fec359c 100644
--- a/chrome/browser/ui/webui/policy/policy_ui.cc
+++ b/chrome/browser/ui/webui/policy/policy_ui.cc
@@ -266,6 +266,10 @@
 
 // static
 base::Value PolicyUI::GetSchema(Profile* profile) {
+  if (!profile->GetPolicySchemaRegistryService()) {
+    return base::Value();
+  }
+
   policy::SchemaRegistry* registry =
       profile->GetPolicySchemaRegistryService()->registry();
   static const policy::PolicyDomain kDomains[] = {
diff --git a/chrome/browser/ui/webui/settings/reset_settings_handler.cc b/chrome/browser/ui/webui/settings/reset_settings_handler.cc
index 014ebfd..94f1b76 100644
--- a/chrome/browser/ui/webui/settings/reset_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/reset_settings_handler.cc
@@ -36,6 +36,7 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/webui/ash/settings/pref_names.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
@@ -72,8 +73,7 @@
 const char ResetSettingsHandler::kCctResetSettingsHash[] = "cct";
 
 // static
-void ResetSettingsHandler::RegisterLocalStatePrefs(
-    PrefRegistrySimple* registry) {
+void ResetSettingsHandler::RegisterProfilePrefs(PrefRegistrySimple* registry) {
   registry->RegisterBooleanPref(ash::settings::prefs::kSanitizeCompleted,
                                 false);
 }
@@ -405,7 +405,7 @@
 
 void ResetSettingsHandler::OnSanitizeDone() {
   setting_snapshot_.reset();
-  PrefService* prefs = g_browser_process->local_state();
+  PrefService* prefs = ProfileManager::GetPrimaryUserProfile()->GetPrefs();
   prefs->SetBoolean(ash::settings::prefs::kSanitizeCompleted, true);
   prefs->CommitPendingWrite();
   chrome::AttemptRestart();
diff --git a/chrome/browser/ui/webui/settings/reset_settings_handler.h b/chrome/browser/ui/webui/settings/reset_settings_handler.h
index 38ee13b3..7f527d2e 100644
--- a/chrome/browser/ui/webui/settings/reset_settings_handler.h
+++ b/chrome/browser/ui/webui/settings/reset_settings_handler.h
@@ -34,7 +34,7 @@
   // profile settings URL.
   static const char kCctResetSettingsHash[];
 
-  static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
+  static void RegisterProfilePrefs(PrefRegistrySimple* registry);
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   static bool ShouldShowResetProfileBanner(Profile* profile);
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_app_browsertest.cc b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_app_browsertest.cc
index d0ca2e3..cbb0f4a 100644
--- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_app_browsertest.cc
+++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_app_browsertest.cc
@@ -77,32 +77,6 @@
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateTheme_FontName) {
-  ASSERT_TRUE(RunTest("update_theme_font_name.js"));
-}
-
-IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, DISABLED_UpdateTheme_FontSize) {
-  ASSERT_TRUE(RunTest("update_theme_font_size.js"));
-}
-
-IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, UpdateTheme_ForegroundColor) {
-  ASSERT_TRUE(RunTest("update_theme_foreground_color.js"));
-}
-
-IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest,
-                       DISABLED_UpdateTheme_BackgroundColor) {
-  ASSERT_TRUE(RunTest("update_theme_background_color.js"));
-}
-
-IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest, DISABLED_UpdateTheme_LineSpacing) {
-  ASSERT_TRUE(RunTest("update_theme_line_spacing.js"));
-}
-
-IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest,
-                       DISABLED_UpdateTheme_LetterSpacing) {
-  ASSERT_TRUE(RunTest("update_theme_letter_spacing.js"));
-}
-
 // TODO(crbug.com/40910623): unflake and re-enable
 IN_PROC_BROWSER_TEST_F(ReadAnythingAppTest,
                        DISABLED_ConnectedCallback_ShowLoadingScreen) {
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.cc b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.cc
index 9f69772..7e2cbde 100644
--- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.cc
+++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.cc
@@ -16,17 +16,19 @@
 #include "chrome/browser/accessibility/pdf_ocr_controller.h"
 #include "chrome/browser/accessibility/pdf_ocr_controller_factory.h"
 #include "chrome/browser/browser_features.h"
+#include "chrome/browser/language/language_model_manager_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/screen_ai/screen_ai_service_router.h"
 #include "chrome/browser/screen_ai/screen_ai_service_router_factory.h"
 #include "chrome/browser/translate/chrome_translate_client.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_controller.h"
 #include "chrome/browser/ui/webui/side_panel/read_anything/read_anything_prefs.h"
 #include "chrome/common/accessibility/read_anything.mojom-forward.h"
 #include "chrome/common/accessibility/read_anything.mojom.h"
 #include "chrome/common/accessibility/read_anything_constants.h"
+#include "components/language/core/browser/language_model.h"
+#include "components/language/core/browser/language_model_manager.h"
 #include "components/language/core/common/locale_util.h"
 #include "components/pdf/common/pdf_util.h"
 #include "components/prefs/pref_service.h"
@@ -56,7 +58,6 @@
 
 using read_anything::mojom::ErrorCode;
 using read_anything::mojom::InstallationState;
-using read_anything::mojom::ReadAnythingTheme;
 using read_anything::mojom::UntrustedPage;
 using read_anything::mojom::UntrustedPageHandler;
 using read_anything::mojom::VoicePackInstallationState;
@@ -253,54 +254,60 @@
     coordinator_ = ReadAnythingCoordinator::FromBrowser(browser_.get());
     if (coordinator_) {
       coordinator_->AddObserver(this);
-      coordinator_->AddModelObserver(this);
     }
   }
 
-  if (features::IsReadAnythingWebUIToolbarEnabled()) {
-    PrefService* prefs = browser_->profile()->GetPrefs();
-    double speechRate =
-        features::IsReadAnythingReadAloudEnabled()
-            ? prefs->GetDouble(prefs::kAccessibilityReadAnythingSpeechRate)
-            : kReadAnythingDefaultSpeechRate;
-    read_anything::mojom::HighlightGranularity highlightGranularity =
-        features::IsReadAnythingReadAloudEnabled()
-            ? static_cast<read_anything::mojom::HighlightGranularity>(
-                  prefs->GetDouble(
-                      prefs::kAccessibilityReadAnythingHighlightGranularity))
-            : read_anything::mojom::HighlightGranularity::kDefaultValue;
-    base::Value::Dict voices = base::Value::Dict();
-    if (features::IsReadAnythingReadAloudEnabled()) {
-      if (features::IsReadAloudAutoVoiceSwitchingEnabled()) {
-        voices =
-            prefs->GetDict(prefs::kAccessibilityReadAnythingVoiceName).Clone();
-      } else {
-        std::string voice_name =
-            prefs->GetString(prefs::kAccessibilityReadAnythingVoiceName);
-        if (!voice_name.empty()) {
-          voices.Set("", voice_name);
-        }
+  PrefService* prefs = browser_->profile()->GetPrefs();
+  double speechRate =
+      features::IsReadAnythingReadAloudEnabled()
+          ? prefs->GetDouble(prefs::kAccessibilityReadAnythingSpeechRate)
+          : kReadAnythingDefaultSpeechRate;
+  read_anything::mojom::HighlightGranularity highlightGranularity =
+      features::IsReadAnythingReadAloudEnabled()
+          ? static_cast<read_anything::mojom::HighlightGranularity>(
+                prefs->GetDouble(
+                    prefs::kAccessibilityReadAnythingHighlightGranularity))
+          : read_anything::mojom::HighlightGranularity::kDefaultValue;
+  base::Value::Dict voices = base::Value::Dict();
+  if (features::IsReadAnythingReadAloudEnabled()) {
+    if (features::IsReadAloudAutoVoiceSwitchingEnabled()) {
+      voices =
+          prefs->GetDict(prefs::kAccessibilityReadAnythingVoiceName).Clone();
+    } else {
+      std::string voice_name =
+          prefs->GetString(prefs::kAccessibilityReadAnythingVoiceName);
+      if (!voice_name.empty()) {
+        voices.Set("", voice_name);
       }
     }
-    page_->OnSettingsRestoredFromPrefs(
-        static_cast<read_anything::mojom::LineSpacing>(
-            prefs->GetInteger(prefs::kAccessibilityReadAnythingLineSpacing)),
-        static_cast<read_anything::mojom::LetterSpacing>(
-            prefs->GetInteger(prefs::kAccessibilityReadAnythingLetterSpacing)),
-        prefs->GetString(prefs::kAccessibilityReadAnythingFontName),
-        prefs->GetDouble(prefs::kAccessibilityReadAnythingFontScale),
-        prefs->GetBoolean(prefs::kAccessibilityReadAnythingLinksEnabled),
-        prefs->GetBoolean(prefs::kAccessibilityReadAnythingImagesEnabled),
-        static_cast<read_anything::mojom::Colors>(
-            prefs->GetInteger(prefs::kAccessibilityReadAnythingColorInfo)),
-        speechRate, std::move(voices),
-        features::IsReadAnythingReadAloudEnabled()
-            ? prefs->GetList(prefs::kAccessibilityReadAnythingLanguagesEnabled)
-                  .Clone()
-            : base::Value::List(),
-        highlightGranularity);
   }
 
+  page_->OnSettingsRestoredFromPrefs(
+      static_cast<read_anything::mojom::LineSpacing>(
+          prefs->GetInteger(prefs::kAccessibilityReadAnythingLineSpacing)),
+      static_cast<read_anything::mojom::LetterSpacing>(
+          prefs->GetInteger(prefs::kAccessibilityReadAnythingLetterSpacing)),
+      prefs->GetString(prefs::kAccessibilityReadAnythingFontName),
+      prefs->GetDouble(prefs::kAccessibilityReadAnythingFontScale),
+      prefs->GetBoolean(prefs::kAccessibilityReadAnythingLinksEnabled),
+      prefs->GetBoolean(prefs::kAccessibilityReadAnythingImagesEnabled),
+      static_cast<read_anything::mojom::Colors>(
+          prefs->GetInteger(prefs::kAccessibilityReadAnythingColorInfo)),
+      speechRate, std::move(voices),
+      features::IsReadAnythingReadAloudEnabled()
+          ? prefs->GetList(prefs::kAccessibilityReadAnythingLanguagesEnabled)
+                .Clone()
+          : base::Value::List(),
+      highlightGranularity);
+
+  // Get user's default language to check for compatible fonts.
+  language::LanguageModel* language_model =
+      LanguageModelManagerFactory::GetForBrowserContext(browser_->profile())
+          ->GetPrimaryModel();
+  std::string prefs_lang = language_model->GetLanguages().front().lang_code;
+  prefs_lang = language::ExtractBaseLanguage(prefs_lang);
+  SetDefaultLanguageCode(prefs_lang);
+
   if (features::IsReadAnythingWithScreen2xEnabled()) {
     screen_ai::ScreenAIServiceRouterFactory::GetForBrowserContext(
         browser_->profile())
@@ -345,7 +352,6 @@
     // |this| from the observer lists. In the cases where the coordinator is
     // destroyed first, these will have been destroyed before this call.
     coordinator_->RemoveObserver(this);
-    coordinator_->RemoveModelObserver(this);
   }
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -607,37 +613,6 @@
   web_snapshotter_->RequestSnapshot(main_observer_->web_contents());
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingModel::Observer:
-///////////////////////////////////////////////////////////////////////////////
-
-void ReadAnythingUntrustedPageHandler::OnReadAnythingThemeChanged(
-    const std::string& font_name,
-    double font_scale,
-    bool links_enabled,
-    bool images_enabled,
-    ui::ColorId foreground_color_id,
-    ui::ColorId background_color_id,
-    ui::ColorId separator_color_id,
-    ui::ColorId dropdown_color_id,
-    ui::ColorId selected_dropdown_color_id,
-    ui::ColorId focus_ring_color_id,
-    read_anything::mojom::LineSpacing line_spacing,
-    read_anything::mojom::LetterSpacing letter_spacing) {
-  // Elsewhere in this file, `web_contents` refers to the active web contents
-  // in the tab strip. In this case, `web_contents` refers to the web contents
-  // hosting the WebUI.
-  content::WebContents* web_contents = web_ui_->GetWebContents();
-  SkColor foreground_skcolor =
-      web_contents->GetColorProvider().GetColor(foreground_color_id);
-  SkColor background_skcolor =
-      web_contents->GetColorProvider().GetColor(background_color_id);
-
-  page_->OnThemeChanged(ReadAnythingTheme::New(
-      font_name, font_scale, links_enabled, images_enabled, foreground_skcolor,
-      background_skcolor, line_spacing, letter_spacing));
-}
-
 void ReadAnythingUntrustedPageHandler::SetDefaultLanguageCode(
     const std::string& code) {
   default_language_code_ = code;
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.h b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.h
index fb55ded..71f4e50 100644
--- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.h
+++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.h
@@ -11,14 +11,14 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/safe_ref.h"
 #include "base/memory/weak_ptr.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_tab_helper.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_model.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.h"
+#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_tab_helper.h"
 #include "chrome/browser/ui/webui/side_panel/read_anything/read_anything_snapshotter.h"
 #include "chrome/common/accessibility/read_anything.mojom.h"
+#include "chrome/common/accessibility/read_anything_constants.h"
 #include "components/translate/core/browser/translate_client.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
@@ -86,7 +86,6 @@
 #endif
     public ui::AXActionHandlerObserver,
     public read_anything::mojom::UntrustedPageHandler,
-    public ReadAnythingModel::Observer,
     public ReadAnythingCoordinator::Observer,
     public ReadAnythingSidePanelController::Observer,
     public translate::TranslateDriver::LanguageDetectionObserver,
@@ -156,25 +155,11 @@
   void OnCollapseSelection() override;
   void OnSnapshotRequested() override;
 
-  // ReadAnythingModel::Observer:
-  void OnReadAnythingThemeChanged(
-      const std::string& font_name,
-      double font_scale,
-      bool links_enabled,
-      bool images_enabled,
-      ui::ColorId foreground_color_id,
-      ui::ColorId background_color_id,
-      ui::ColorId separator_color_id,
-      ui::ColorId dropdown_color_id,
-      ui::ColorId selected_dropdown_color_id,
-      ui::ColorId focus_ring_color_id,
-      read_anything::mojom::LineSpacing line_spacing,
-      read_anything::mojom::LetterSpacing letter_spacing) override;
-
   // ReadAnythingCoordinator::Observer:
   void Activate(bool active) override;
   void OnCoordinatorDestroyed() override;
-  void SetDefaultLanguageCode(const std::string& code) override;
+
+  void SetDefaultLanguageCode(const std::string& code);
 
   // Sends the language code of the new page, or the default if a language can't
   // be determined.
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler_unittest.cc b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler_unittest.cc
index 4f08a3d..24f7de9 100644
--- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler_unittest.cc
+++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler_unittest.cc
@@ -59,9 +59,6 @@
                     ukm::SourceId ukm_source_id,
                     bool is_pdf));
   MOCK_METHOD(void, OnAXTreeDestroyed, (const ui::AXTreeID&));
-  MOCK_METHOD(void,
-              OnThemeChanged,
-              (read_anything::mojom::ReadAnythingThemePtr));
   MOCK_METHOD(void, SetLanguageCode, (const std::string&));
   MOCK_METHOD(void, SetDefaultLanguageCode, (const std::string&));
   MOCK_METHOD(void, ScreenAIServiceReady, ());
@@ -89,7 +86,7 @@
  public:
   void SetUp() override {
     scoped_feature_list_.InitWithFeatures(
-        {features::kReadAnythingWebUIToolbar, features::kReadAnythingReadAloud},
+        {features::kReadAnythingReadAloud},
         {features::kReadAnythingWithScreen2x, features::kPdfOcr});
     BrowserWithTestWindowTest::SetUp();
     web_contents_ = content::WebContents::Create(
@@ -268,7 +265,7 @@
  public:
   void SetUp() override {
     scoped_feature_list_.InitWithFeatures(
-        {features::kReadAnythingWebUIToolbar, features::kReadAnythingReadAloud,
+        {features::kReadAnythingReadAloud,
          features::kReadAloudAutoVoiceSwitching},
         {features::kReadAnythingWithScreen2x, features::kPdfOcr});
     BrowserWithTestWindowTest::SetUp();
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_ui.cc b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_ui.cc
index d2da2e6b..466c120 100644
--- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_ui.cc
+++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_ui.cc
@@ -24,7 +24,6 @@
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "read_anything_untrusted_ui.h"
-#include "ui/accessibility/accessibility_features.h"
 #include "ui/base/webui/web_ui_util.h"
 #include "ui/resources/grit/webui_resources.h"
 #include "ui/views/style/platform_style.h"
@@ -184,10 +183,8 @@
 void ReadAnythingUntrustedUI::BindInterface(
     mojo::PendingReceiver<color_change_listener::mojom::PageHandler>
         pending_receiver) {
-  if (features::IsReadAnythingWebUIToolbarEnabled()) {
-    color_provider_handler_ = std::make_unique<ui::ColorChangeHandler>(
-        web_ui()->GetWebContents(), std::move(pending_receiver));
-  }
+  color_provider_handler_ = std::make_unique<ui::ColorChangeHandler>(
+      web_ui()->GetWebContents(), std::move(pending_receiver));
 }
 
 void ReadAnythingUntrustedUI::BindInterface(
diff --git a/chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.cc b/chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.cc
index 396988d..66d436bb1 100644
--- a/chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.cc
+++ b/chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.cc
@@ -104,6 +104,8 @@
   source->AddLocalizedString(
       "chromeSigninDeclineText",
       IDS_SIGNIN_DICE_WEB_INTERCEPT_BUBBLE_CHROME_SIGNIN_DECLINE_TEXT);
+  source->AddLocalizedString("acceptButtonAriaLabel",
+                             IDS_SIGNIN_CONTINUE_AS_BUTTON_ACCESSIBILITY_LABEL);
 
   source->UseStringsJs();
   source->EnableReplaceI18nInJS();
diff --git a/chrome/browser/ui/webui/top_chrome/per_profile_webui_tracker.cc b/chrome/browser/ui/webui/top_chrome/per_profile_webui_tracker.cc
index 6f71c9a0..c7562056 100644
--- a/chrome/browser/ui/webui/top_chrome/per_profile_webui_tracker.cc
+++ b/chrome/browser/ui/webui/top_chrome/per_profile_webui_tracker.cc
@@ -9,6 +9,7 @@
 #include <set>
 
 #include "base/memory/raw_ptr.h"
+#include "base/observer_list.h"
 #include "chrome/browser/profiles/profile.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
@@ -30,6 +31,8 @@
   // PerProfileWebUITracker:
   void AddWebContents(content::WebContents* web_contents) override;
   bool ProfileHasWebUI(Profile* profile, std::string webui_url) const override;
+  void AddObserver(Observer* observer) override;
+  void RemoveObserver(Observer* observer) override;
 
  private:
   class WebContentsObserver;
@@ -41,6 +44,8 @@
                                   url::Origin old_origin,
                                   url::Origin new_origin);
 
+  base::ObserverList<Observer, /*check_empty=*/true> observers_;
+  // Observers of tracked WebContents.
   std::map<raw_ptr<content::WebContents>, std::unique_ptr<WebContentsObserver>>
       web_contents_observers_;
   // Maintains a multi-set of {profile, origin} pairs. Note that a multi-set is
@@ -107,10 +112,22 @@
   return profile_origin_set_.contains({profile, webui_origin});
 }
 
+void PerProfileWebUITrackerImpl::AddObserver(Observer* observer) {
+  observers_.AddObserver(observer);
+}
+
+void PerProfileWebUITrackerImpl::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
+
 void PerProfileWebUITrackerImpl::OnWebContentsDestroyed(
     content::WebContents* web_contents) {
   CHECK(web_contents_observers_.contains(web_contents));
   web_contents_observers_.erase(web_contents);
+
+  for (Observer& observer : observers_) {
+    observer.OnWebContentsDestroyed(web_contents);
+  }
 }
 
 void PerProfileWebUITrackerImpl::OnWebContentsOriginChanged(
diff --git a/chrome/browser/ui/webui/top_chrome/per_profile_webui_tracker.h b/chrome/browser/ui/webui/top_chrome/per_profile_webui_tracker.h
index 17d4e08..bf6816b 100644
--- a/chrome/browser/ui/webui/top_chrome/per_profile_webui_tracker.h
+++ b/chrome/browser/ui/webui/top_chrome/per_profile_webui_tracker.h
@@ -8,6 +8,8 @@
 #include <memory>
 #include <string>
 
+#include "base/observer_list_types.h"
+
 namespace content {
 class WebContents;
 }  // namespace content
@@ -20,6 +22,12 @@
 // status.
 class PerProfileWebUITracker {
  public:
+  class Observer : public base::CheckedObserver {
+   public:
+    // Called when a tracked WebContents is destroyed.
+    virtual void OnWebContentsDestroyed(content::WebContents* web_contents) = 0;
+  };
+
   static std::unique_ptr<PerProfileWebUITracker> Create();
 
   virtual ~PerProfileWebUITracker() = default;
@@ -34,6 +42,10 @@
   // state, crash state, or any errors.
   virtual bool ProfileHasWebUI(Profile* profile,
                                std::string webui_url) const = 0;
+
+  // Adds an observer that will be notified of tracked WebContents destroy.
+  virtual void AddObserver(Observer* observer) = 0;
+  virtual void RemoveObserver(Observer* observer) = 0;
 };
 
 #endif  // CHROME_BROWSER_UI_WEBUI_TOP_CHROME_PER_PROFILE_WEBUI_TRACKER_H_
diff --git a/chrome/browser/ui/webui/top_chrome/per_profile_webui_tracker_unittest.cc b/chrome/browser/ui/webui/top_chrome/per_profile_webui_tracker_unittest.cc
index 267b75b7..69111f5f 100644
--- a/chrome/browser/ui/webui/top_chrome/per_profile_webui_tracker_unittest.cc
+++ b/chrome/browser/ui/webui/top_chrome/per_profile_webui_tracker_unittest.cc
@@ -4,8 +4,10 @@
 
 #include "chrome/browser/ui/webui/top_chrome/per_profile_webui_tracker.h"
 
+#include "base/scoped_observation.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "content/public/test/web_contents_tester.h"
+#include "testing/gmock/include/gmock/gmock.h"
 
 namespace {
 constexpr char kWebUIUrl1[] = "chrome://example";
@@ -126,3 +128,26 @@
       ->NavigateAndCommit(GURL("about:blank"));
   EXPECT_FALSE(tracker()->ProfileHasWebUI(profile(), kWebUIUrl1));
 }
+
+class MockTrackerObserver : public PerProfileWebUITracker::Observer {
+ public:
+  MOCK_METHOD(void,
+              OnWebContentsDestroyed,
+              (content::WebContents*),
+              (override));
+};
+
+// Tests that the observer of tracker is notified of WebContents destroy.
+TEST_F(PerProfileWebUITrackerTest, Observer) {
+  std::unique_ptr<content::WebContents> web_contents = CreateTestWebContents();
+  ASSERT_EQ(web_contents->GetBrowserContext(), profile());
+  tracker()->AddWebContents(web_contents.get());
+
+  MockTrackerObserver mock_observer;
+  base::ScopedObservation<PerProfileWebUITracker,
+                          PerProfileWebUITracker::Observer>
+      observation{&mock_observer};
+  EXPECT_CALL(mock_observer, OnWebContentsDestroyed(web_contents.get()));
+  observation.Observe(tracker());
+  web_contents.reset();
+}
diff --git a/chrome/browser/ui/webui/top_chrome/profile_preload_candidate_selector_unittest.cc b/chrome/browser/ui/webui/top_chrome/profile_preload_candidate_selector_unittest.cc
index e8b20f9..4217523 100644
--- a/chrome/browser/ui/webui/top_chrome/profile_preload_candidate_selector_unittest.cc
+++ b/chrome/browser/ui/webui/top_chrome/profile_preload_candidate_selector_unittest.cc
@@ -36,6 +36,8 @@
               ProfileHasWebUI,
               (Profile*, std::string webui_url),
               (const, override));
+  MOCK_METHOD(void, AddObserver, (Observer*), (override));
+  MOCK_METHOD(void, RemoveObserver, (Observer*), (override));
 };
 
 }  // namespace
diff --git a/chrome/browser/ui/webui/top_chrome/webui_contents_preload_manager.cc b/chrome/browser/ui/webui/top_chrome/webui_contents_preload_manager.cc
index 523496b..86ac1f00 100644
--- a/chrome/browser/ui/webui/top_chrome/webui_contents_preload_manager.cc
+++ b/chrome/browser/ui/webui/top_chrome/webui_contents_preload_manager.cc
@@ -8,12 +8,14 @@
 #include <optional>
 #include <string>
 
+#include "base/auto_reset.h"
 #include "base/containers/contains.h"
 #include "base/feature_list.h"
 #include "base/memory/memory_pressure_monitor.h"
 #include "base/memory/weak_ptr.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/no_destructor.h"
+#include "base/scoped_observation.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/task_manager/web_contents_tags.h"
 #include "chrome/browser/ui/browser.h"
@@ -25,8 +27,6 @@
 #include "chrome/browser/ui/webui/top_chrome/top_chrome_web_ui_controller.h"
 #include "chrome/common/webui_url_constants.h"
 #include "chrome/grit/generated_resources.h"
-#include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
-#include "components/keyed_service/core/keyed_service_shutdown_notifier.h"
 #include "content/public/browser/navigation_controller.h"
 #include "ui/base/models/menu_model.h"
 
@@ -48,27 +48,6 @@
   kMaxValue = kMiss,
 };
 
-// This factory is used to get notification for the browser context shutdown.
-class BrowserContextShutdownNotifierFactory
-    : public BrowserContextKeyedServiceShutdownNotifierFactory {
- public:
-  BrowserContextShutdownNotifierFactory(
-      const BrowserContextShutdownNotifierFactory&) = delete;
-  BrowserContextShutdownNotifierFactory& operator=(
-      const BrowserContextShutdownNotifierFactory&) = delete;
-
-  static BrowserContextShutdownNotifierFactory* GetInstance() {
-    static base::NoDestructor<BrowserContextShutdownNotifierFactory> s_factory;
-    return s_factory.get();
-  }
-
- private:
-  friend class base::NoDestructor<BrowserContextShutdownNotifierFactory>;
-  BrowserContextShutdownNotifierFactory()
-      : BrowserContextKeyedServiceShutdownNotifierFactory(
-            "WebUIContentsPreloadManager") {}
-};
-
 // A candidate selector that always preloads a fixed WebUI.
 class FixedCandidateSelector : public webui::PreloadCandidateSelector {
  public:
@@ -215,6 +194,7 @@
       std::make_unique<WebUIControllerEmbedderStub>();
 
   webui_tracker_ = PerProfileWebUITracker::Create();
+  webui_tracker_observation_.Observe(webui_tracker_.get());
   if (IsSmartPreloadEnabled()) {
     // Use ProfilePreloadCandidateSelector to find the WebUI with the
     // highest engagement score and is not present under the current profile.
@@ -236,14 +216,6 @@
   return s_instance.get();
 }
 
-// static
-void WebUIContentsPreloadManager::EnsureFactoryBuilt() {
-  // Ensure that the shutdown notifier factory is built.
-  // The profile service's dependency manager requires the service factory
-  // be registered at an early stage of browser lifetime.
-  BrowserContextShutdownNotifierFactory::GetInstance();
-}
-
 void WebUIContentsPreloadManager::WarmupForBrowser(Browser* browser) {
   // Most WebUIs, if not all, are hosted by a TYPE_NORMAL browser. This check
   // skips unnecessary preloading for the majority of WebUIs.
@@ -304,23 +276,40 @@
     return;
   }
 
+  // Usually destroying a WebContents may trigger preload, but if the
+  // destroy is caused by setting new preload contents, ignore it.
+  if (is_setting_preloaded_web_contents_) {
+    return;
+  }
+
   std::optional<GURL> preload_url = GetNextWebUIURLToPreload(browser_context);
   if (!preload_url.has_value()) {
     return;
   }
 
+  // Don't preload if already preloaded for this `browser_context`.
+  if (preloaded_web_contents_ &&
+      preloaded_web_contents_->GetBrowserContext() == browser_context &&
+      preloaded_web_contents_->GetVisibleURL().GetWithEmptyPath() ==
+          preload_url->GetWithEmptyPath()) {
+    return;
+  }
+
   SetPreloadedContents(CreateNewContents(browser_context, *preload_url));
 }
 
 void WebUIContentsPreloadManager::SetPreloadedContents(
     std::unique_ptr<content::WebContents> web_contents) {
   webui_controller_embedder_stub_->Detach();
-  StopObserveBrowserContextShutdown();
+  profile_observation_.Reset();
 
+  base::AutoReset<bool> is_setting_preloaded_web_contents(
+      &is_setting_preloaded_web_contents_, true);
   preloaded_web_contents_ = std::move(web_contents);
   if (preloaded_web_contents_) {
     webui_controller_embedder_stub_->AttachTo(preloaded_web_contents_.get());
-    ObserveBrowserContextShutdown();
+    profile_observation_.Observe(Profile::FromBrowserContext(
+        preloaded_web_contents_->GetBrowserContext()));
   }
 }
 
@@ -422,9 +411,7 @@
     return false;
   }
 
-  // Don't preload if already preloaded for this `browser_context`.
-  if (preloaded_web_contents_ &&
-      preloaded_web_contents_->GetBrowserContext() == browser_context) {
+  if (browser_context->ShutdownStarted()) {
     return false;
   }
 
@@ -439,30 +426,21 @@
   return true;
 }
 
-void WebUIContentsPreloadManager::ObserveBrowserContextShutdown() {
-  CHECK(preloaded_web_contents_);
-  // Cleans up the preloaded contents on browser context shutdown.
-  content::BrowserContext* browser_context =
-      preloaded_web_contents_->GetBrowserContext();
-  browser_context_shutdown_subscription_ =
-      BrowserContextShutdownNotifierFactory::GetInstance()
-          ->Get(browser_context)
-          ->Subscribe(base::BindRepeating(
-              &WebUIContentsPreloadManager::OnBrowserContextShutdown,
-              base::Unretained(this), browser_context));
-}
-
-void WebUIContentsPreloadManager::StopObserveBrowserContextShutdown() {
-  browser_context_shutdown_subscription_ = {};
-}
-
-void WebUIContentsPreloadManager::OnBrowserContextShutdown(
-    content::BrowserContext* browser_context) {
+void WebUIContentsPreloadManager::OnProfileWillBeDestroyed(Profile* profile) {
+  profile_observation_.Reset();
   if (!preloaded_web_contents_) {
     return;
   }
 
   webui_controller_embedder_stub_->Detach();
-  CHECK_EQ(preloaded_web_contents_->GetBrowserContext(), browser_context);
+  CHECK_EQ(preloaded_web_contents_->GetBrowserContext(), profile);
   preloaded_web_contents_.reset();
 }
+
+void WebUIContentsPreloadManager::OnWebContentsDestroyed(
+    content::WebContents* web_contents) {
+  // Triggers preloading when a WebUI is destroyed. Without this step, the
+  // preloaded content would only be the second highest engaged WebUI for
+  // the most time.
+  MaybePreloadForBrowserContext(web_contents->GetBrowserContext());
+}
diff --git a/chrome/browser/ui/webui/top_chrome/webui_contents_preload_manager.h b/chrome/browser/ui/webui/top_chrome/webui_contents_preload_manager.h
index c69f6b1c..66c78c2 100644
--- a/chrome/browser/ui/webui/top_chrome/webui_contents_preload_manager.h
+++ b/chrome/browser/ui/webui/top_chrome/webui_contents_preload_manager.h
@@ -8,6 +8,9 @@
 #include <optional>
 
 #include "base/callback_list.h"
+#include "base/scoped_observation.h"
+#include "chrome/browser/profiles/profile_observer.h"
+#include "chrome/browser/ui/webui/top_chrome/per_profile_webui_tracker.h"
 #include "chrome/browser/ui/webui/top_chrome/preload_candidate_selector.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/web_contents.h"
@@ -22,7 +25,8 @@
 //
 // To make a WebUI preloadable, update GetAllPreloadableWebUIURLs() and
 // ensure that tests pass.
-class WebUIContentsPreloadManager {
+class WebUIContentsPreloadManager : public ProfileObserver,
+                                    public PerProfileWebUITracker::Observer {
  public:
   enum class PreloadMode {
     // Preloads on calling `WarmupForBrowser()` and after every WebUI
@@ -52,7 +56,7 @@
   };
 
   WebUIContentsPreloadManager();
-  ~WebUIContentsPreloadManager();
+  ~WebUIContentsPreloadManager() override;
 
   WebUIContentsPreloadManager(const WebUIContentsPreloadManager&) = delete;
   WebUIContentsPreloadManager& operator=(const WebUIContentsPreloadManager&) =
@@ -60,10 +64,6 @@
 
   static WebUIContentsPreloadManager* GetInstance();
 
-  // Ensures that the keyed service factory for the browser context shutdown
-  // notification is built.
-  static void EnsureFactoryBuilt();
-
   // Warms up the preload manager. Depending on PreloadMode this may or may not
   // make a preloaded contents.
   void WarmupForBrowser(Browser* browser);
@@ -140,30 +140,43 @@
   bool ShouldPreloadForBrowserContext(
       content::BrowserContext* browser_context) const;
 
-  void ObserveBrowserContextShutdown();
-  void StopObserveBrowserContextShutdown();
-
   // Cleans up preloaded contents on browser context shutdown.
   void OnBrowserContextShutdown(content::BrowserContext* browser_context);
 
+  // ProfileObserver:
+  void OnProfileWillBeDestroyed(Profile* profile) override;
+
+  // PerProfileWebUITracker::Observer:
+  void OnWebContentsDestroyed(content::WebContents* web_contents) override;
+
   PreloadMode preload_mode_ = PreloadMode::kPreloadOnMakeContents;
 
   // Disable navigations for views unittests because they don't initialize
   // //content properly.
   bool is_navigation_disabled_for_test_ = false;
 
+  // Used to prevent the preload re-entrance due to destroying the old preload
+  // contents.
+  bool is_setting_preloaded_web_contents_ = false;
+
   std::unique_ptr<content::WebContents> preloaded_web_contents_;
 
   // Tracks the WebUI presence state under a profile.
   std::unique_ptr<PerProfileWebUITracker> webui_tracker_;
 
+  // Observes the tracker for WebContents destroy.
+  base::ScopedObservation<PerProfileWebUITracker,
+                          PerProfileWebUITracker::Observer>
+      webui_tracker_observation_{this};
+
   // PreloadCandidateSelector selects the next WebUI to preload.
   std::unique_ptr<webui::PreloadCandidateSelector> preload_candidate_selector_;
 
   // A stub WebUI page embdeder that captures the ready-to-show signal.
   std::unique_ptr<WebUIControllerEmbedderStub> webui_controller_embedder_stub_;
 
-  base::CallbackListSubscription browser_context_shutdown_subscription_;
+  // Observation of destroy of preload content's profile.
+  base::ScopedObservation<Profile, ProfileObserver> profile_observation_{this};
 };
 
 #endif  // CHROME_BROWSER_UI_WEBUI_TOP_CHROME_WEBUI_CONTENTS_PRELOAD_MANAGER_H_
diff --git a/chrome/browser/ui/webui/top_chrome/webui_contents_preload_manager_unittest.cc b/chrome/browser/ui/webui/top_chrome/webui_contents_preload_manager_unittest.cc
index 1451150..effe1c2 100644
--- a/chrome/browser/ui/webui/top_chrome/webui_contents_preload_manager_unittest.cc
+++ b/chrome/browser/ui/webui/top_chrome/webui_contents_preload_manager_unittest.cc
@@ -315,3 +315,32 @@
   EXPECT_EQ(result.web_contents->GetVisibleURL(), url1);
   EXPECT_EQ(preload_manager()->preloaded_web_contents()->GetVisibleURL(), url2);
 }
+
+// Tests that WebUI destroy may trigger new preloading.
+TEST_F(WebUIContentsPreloadManagerTest, PreloadOnWebUIDestroy) {
+  std::unique_ptr<content::BrowserContext> browser_context =
+      std::make_unique<TestingProfile>();
+  const GURL url1("chrome://example1"), url2("chrome://example2");
+
+  // URL1 is preferred over URL2.
+  ON_CALL(preload_candidate_selector(), GetURLToPreload(_))
+      .WillByDefault(Return(url1));
+  preload_manager()->MaybePreloadForBrowserContextForTesting(
+      browser_context.get());
+  // Initially, URL1 is preloaded.
+  EXPECT_EQ(preload_manager()->preloaded_web_contents()->GetVisibleURL(), url1);
+
+  // Now, show URL1, then URL2 is preloaded.
+  ON_CALL(preload_candidate_selector(), GetURLToPreload(_))
+      .WillByDefault(Return(url2));
+  MakeContentsResult result =
+      preload_manager()->MakeContents(url1, browser_context.get());
+  EXPECT_EQ(result.web_contents->GetVisibleURL(), url1);
+  EXPECT_EQ(preload_manager()->preloaded_web_contents()->GetVisibleURL(), url2);
+
+  // Destroy URL1. Since URL1 is preferred over URL2, URL1 should be preloaded.
+  ON_CALL(preload_candidate_selector(), GetURLToPreload(_))
+      .WillByDefault(Return(url1));
+  result.web_contents.reset();
+  EXPECT_EQ(preload_manager()->preloaded_web_contents()->GetVisibleURL(), url1);
+}
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_dev_tools_browsertest.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_dev_tools_browsertest.cc
index 581a22d9..7bf6fe6 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_dev_tools_browsertest.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_dev_tools_browsertest.cc
@@ -10,8 +10,11 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.h"
+#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
 #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
+#include "chrome/browser/web_applications/test/web_app_test_utils.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
@@ -27,6 +30,9 @@
 
 namespace web_app {
 
+namespace {
+constexpr std::string_view kTypeApp = "app";
+}
 class IsolatedWebAppDevToolsTest : public IsolatedWebAppBrowserTestHarness {
  protected:
   IsolatedWebAppUrlInfo InstallIsolatedWebApp() {
@@ -77,4 +83,55 @@
               Eq(profile()->GetDefaultStoragePartition()));
 }
 
+IN_PROC_BROWSER_TEST_F(IsolatedWebAppDevToolsTest, IwaIdentifiedAsApp) {
+  // 1) Install an Isolated Web App and check its type in DevTools
+  IsolatedWebAppUrlInfo url_info = InstallIsolatedWebApp();
+  Browser* iwa_app = LaunchWebAppBrowserAndWait(url_info.app_id());
+  scoped_refptr<content::DevToolsAgentHost> iwa_host =
+      content::DevToolsAgentHost::GetOrCreateFor(
+          iwa_app->tab_strip_model()->GetActiveWebContents());
+  const std::string& iwa_type = iwa_host->GetType();
+  EXPECT_EQ(kTypeApp, iwa_type);
+
+  // 2) Navigate to the Chrome Inspect page and check its js content
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(),
+                                           GURL(chrome::kChromeUIInspectURL)));
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  EXPECT_EQ(1, content::EvalJs(
+                   web_contents,
+                   "document.getElementById('apps-list').children.length"));
+  EXPECT_EQ("Isolated Web App",
+            content::EvalJs(web_contents,
+                            "document.getElementById('apps-list').children[0]."
+                            "getElementsByClassName('name')[0].innerText"));
+}
+
+IN_PROC_BROWSER_TEST_F(IsolatedWebAppDevToolsTest, PwaIdentifiedAsPage) {
+  // 1) Regression test to install PWA and make sure they still show as page
+  ASSERT_TRUE(embedded_test_server()->Start());
+  const GURL app_url = embedded_test_server()->GetURL("/simple.html");
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), app_url));
+  webapps::AppId pwa_id = web_app::test::InstallPwaForCurrentUrl(browser());
+  Browser* pwa_app =
+      web_app::LaunchWebAppBrowserAndWait(browser()->profile(), pwa_id);
+  scoped_refptr<content::DevToolsAgentHost> pwa_host =
+      content::DevToolsAgentHost::GetOrCreateFor(
+          pwa_app->tab_strip_model()->GetActiveWebContents());
+  const std::string& pwa_type = pwa_host->GetType();
+  EXPECT_EQ(content::DevToolsAgentHost::kTypePage, pwa_type);
+
+  // 2) Navigate to the Chrome Inspect page and check its js content
+  //    App list should be empty since PWA is identified as a page
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(),
+                                           GURL(chrome::kChromeUIInspectURL)));
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  EXPECT_EQ(0, content::EvalJs(
+                   web_contents,
+                   "document.getElementById('apps-list').children.length"));
+}
+
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/os_integration/file_handling_sub_manager.cc b/chrome/browser/web_applications/os_integration/file_handling_sub_manager.cc
index e653f87..01c6e350 100644
--- a/chrome/browser/web_applications/os_integration/file_handling_sub_manager.cc
+++ b/chrome/browser/web_applications/os_integration/file_handling_sub_manager.cc
@@ -193,14 +193,6 @@
                                   (result == Result::kOk));
       }).Then(std::move(callback));
 
-  // TODO(crbug.com/40214162): remove after fully deprecate old
-  // `InstallOsHooks/UninstallOsHooks` paths.
-  if (!HasFileHandling(desired_state)) {
-    ScopedRegistryUpdate update = provider_->sync_bridge_unsafe().BeginUpdate();
-    update->UpdateApp(app_id)->SetFileHandlerOsIntegrationState(
-        OsIntegrationState::kDisabled);
-  }
-
   UnregisterFileHandlersWithOs(app_id, profile_path_,
                                std::move(metrics_callback));
 }
@@ -220,14 +212,6 @@
                                   (result == Result::kOk));
       }).Then(std::move(callback));
 
-  // TODO(crbug.com/40214162): remove after fully deprecate old
-  // `InstallOsHooks/UninstallOsHooks` paths.
-  {
-    ScopedRegistryUpdate update = provider_->sync_bridge_unsafe().BeginUpdate();
-    update->UpdateApp(app_id)->SetFileHandlerOsIntegrationState(
-        OsIntegrationState::kEnabled);
-  }
-
   RegisterFileHandlersWithOs(
       app_id, provider_->registrar_unsafe().GetAppShortName(app_id),
       profile_path_,
diff --git a/chrome/browser/web_applications/os_integration/web_app_file_handler_manager.cc b/chrome/browser/web_applications/os_integration/web_app_file_handler_manager.cc
index e1d1c73..50860e1 100644
--- a/chrome/browser/web_applications/os_integration/web_app_file_handler_manager.cc
+++ b/chrome/browser/web_applications/os_integration/web_app_file_handler_manager.cc
@@ -64,61 +64,6 @@
   g_icons_supported_by_os_override = value;
 }
 
-void WebAppFileHandlerManager::EnableAndRegisterOsFileHandlers(
-    const webapps::AppId& app_id,
-    ResultCallback callback) {
-  SetOsIntegrationState(app_id, OsIntegrationState::kEnabled);
-
-  if (IsDisabledForTesting()) {
-    std::move(callback).Run(Result::kOk);
-    return;
-  }
-
-  if (!ShouldRegisterFileHandlersWithOs()) {
-    std::move(callback).Run(Result::kOk);
-    return;
-  }
-
-  const apps::FileHandlers* file_handlers = GetEnabledFileHandlers(app_id);
-  if (file_handlers) {
-    RegisterFileHandlersWithOs(
-        app_id, provider_->registrar_unsafe().GetAppShortName(app_id),
-        profile_->GetPath(), *file_handlers, std::move(callback));
-  } else {
-    // No file handlers registered.
-    std::move(callback).Run(Result::kOk);
-  }
-}
-
-void WebAppFileHandlerManager::DisableAndUnregisterOsFileHandlers(
-    const webapps::AppId& app_id,
-    ResultCallback callback) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
-  if (!ShouldOsIntegrationBeEnabled(app_id)) {
-    // No work is required.
-    std::move(callback).Run(Result::kOk);
-    return;
-  }
-
-  SetOsIntegrationState(app_id, OsIntegrationState::kDisabled);
-
-  if (IsDisabledForTesting()) {
-    std::move(callback).Run(Result::kOk);
-    return;
-  }
-
-  if (!ShouldRegisterFileHandlersWithOs()) {
-    // This enumeration signals if there was not an error. Exiting early here is
-    // WAI, so this is a success.
-    std::move(callback).Run(Result::kOk);
-    return;
-  }
-
-  UnregisterFileHandlersWithOs(app_id, profile_->GetPath(),
-                               std::move(callback));
-}
-
 const apps::FileHandlers* WebAppFileHandlerManager::GetEnabledFileHandlers(
     const webapps::AppId& app_id) const {
   if (ShouldOsIntegrationBeEnabled(app_id) &&
@@ -199,13 +144,6 @@
   return launch_infos;
 }
 
-void WebAppFileHandlerManager::SetOsIntegrationState(
-    const webapps::AppId& app_id,
-    OsIntegrationState os_state) {
-  ScopedRegistryUpdate update = provider_->sync_bridge_unsafe().BeginUpdate();
-  update->UpdateApp(app_id)->SetFileHandlerOsIntegrationState(os_state);
-}
-
 bool WebAppFileHandlerManager::ShouldOsIntegrationBeEnabled(
     const webapps::AppId& app_id) const {
   return !ShouldRegisterFileHandlersWithOs() ||
diff --git a/chrome/browser/web_applications/os_integration/web_app_file_handler_manager.h b/chrome/browser/web_applications/os_integration/web_app_file_handler_manager.h
index 29f41d2..274e1289 100644
--- a/chrome/browser/web_applications/os_integration/web_app_file_handler_manager.h
+++ b/chrome/browser/web_applications/os_integration/web_app_file_handler_manager.h
@@ -46,18 +46,6 @@
       const webapps::AppId& app_id,
       const std::vector<base::FilePath>& launch_files);
 
-  // Enables and registers OS specific file handlers for OSs that need them.
-  // Currently on Chrome OS, file handlers are enabled and registered as long as
-  // the app is installed.
-  void EnableAndRegisterOsFileHandlers(const webapps::AppId& app_id,
-                                       ResultCallback callback);
-
-  // Disables file handlers for all OSs and unregisters OS specific file
-  // handlers for OSs that need them. On Chrome OS file handlers are registered
-  // separately but they are still enabled and disabled here.
-  void DisableAndUnregisterOsFileHandlers(const webapps::AppId& app_id,
-                                          ResultCallback callback);
-
   // Gets all enabled file handlers for |app_id|. |nullptr| if the app has no
   // enabled file handlers. Note: The lifetime of the file handlers are tied to
   // the app they belong to.
@@ -78,20 +66,11 @@
   virtual bool IsDisabledForTesting();
 
  private:
-  // Sets whether `app_id` should have its File Handling abilities surfaces in
-  // the OS. In theory, this should match the actual OS integration state (e.g.
-  // the contents of the .desktop file on Linux), however, that's only enforced
-  // on a best-effort basis.
-  void SetOsIntegrationState(const webapps::AppId& app_id,
-                             OsIntegrationState os_state);
-
   // Indicates whether file handlers should be OS-registered for an app. As with
   // `SetOsIntegrationState()`, there may be a mismatch with the actual OS
   // registry.
   bool ShouldOsIntegrationBeEnabled(const webapps::AppId& app_id) const;
 
-  static bool disable_automatic_file_handler_cleanup_for_testing_;
-
   [[maybe_unused]] const raw_ptr<Profile, DanglingUntriaged> profile_;
   raw_ptr<WebAppProvider> provider_ = nullptr;
 
diff --git a/chrome/browser/web_applications/proto/web_app.proto b/chrome/browser/web_applications/proto/web_app.proto
index 36b69ca..97220b35 100644
--- a/chrome/browser/web_applications/proto/web_app.proto
+++ b/chrome/browser/web_applications/proto/web_app.proto
@@ -181,7 +181,8 @@
 // app_id is a hash of launch_url. app_id is the client tag for sync system.
 // app_id is the storage key in ModelTypeStore.
 message WebAppProto {
-  reserved "handle_links", "is_in_sync_install", "is_placeholder";
+  reserved "handle_links", "is_in_sync_install", "is_placeholder",
+      "file_handler_os_integration_state";
   // Synced data. It is replicated across all devices with WEB_APPS.
   //
   // |sync_data.name| and |sync_data.theme_color| are read by a device to
@@ -357,15 +358,10 @@
   // uninstallation, and the uninstallation will be tried again.
   optional bool is_uninstalling = 45;
 
-  // Should be kept in sync with `OsIntegrationState` in web_app_constants.h.
-  enum OsIntegrationState {
-    ENABLED = 0;
-    DISABLED = 1;
-  }
-
   // Whether the file handling abilities of the app should be registered with
   // the OS.
-  optional OsIntegrationState file_handler_os_integration_state = 46;
+  // OsIntegrationState file_handler_os_integration_state = 46;
+  reserved 46;
 
   // Whether the app should show up in file-open intent and picking surfaces.
   optional bool handles_file_open_intents = 47;
diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc
index 655c3b1..6b02bb5 100644
--- a/chrome/browser/web_applications/web_app.cc
+++ b/chrome/browser/web_applications/web_app.cc
@@ -91,15 +91,6 @@
   }
 }
 
-std::string OsIntegrationStateToString(OsIntegrationState state) {
-  switch (state) {
-    case OsIntegrationState::kEnabled:
-      return "kEnabled";
-    case OsIntegrationState::kDisabled:
-      return "kDisabled";
-  }
-}
-
 std::string GetRunOnOsLoginMode(const proto::RunOnOsLoginMode& mode) {
   switch (mode) {
     case proto::RunOnOsLoginMode::RUN_ON_OS_LOGIN_MODE_UNSPECIFIED:
@@ -553,10 +544,6 @@
   file_handler_approval_state_ = approval_state;
 }
 
-void WebApp::SetFileHandlerOsIntegrationState(OsIntegrationState state) {
-  file_handler_os_integration_state_ = state;
-}
-
 void WebApp::SetShareTarget(std::optional<apps::ShareTarget> share_target) {
   share_target_ = std::move(share_target);
 }
@@ -1022,7 +1009,6 @@
         app.client_data_.system_web_app_data,
 #endif
         app.file_handler_approval_state_,
-        app.file_handler_os_integration_state_,
         app.window_controls_overlay_enabled_,
         app.launch_handler_,
         app.parent_app_id_,
@@ -1119,9 +1105,6 @@
   root.Set("file_handler_approval_state",
            ApiApprovalStateToString(file_handler_approval_state_));
 
-  root.Set("file_handler_os_integration_state",
-           OsIntegrationStateToString(file_handler_os_integration_state_));
-
   root.Set("file_handlers", ConvertDebugValueList(file_handlers_));
 
   root.Set("manifest_icons", ConvertDebugValueList(manifest_icons_));
diff --git a/chrome/browser/web_applications/web_app.h b/chrome/browser/web_applications/web_app.h
index 8f047ce..9508afbc 100644
--- a/chrome/browser/web_applications/web_app.h
+++ b/chrome/browser/web_applications/web_app.h
@@ -184,10 +184,6 @@
     return file_handler_approval_state_;
   }
 
-  OsIntegrationState file_handler_os_integration_state() const {
-    return file_handler_os_integration_state_;
-  }
-
   const std::optional<apps::ShareTarget>& share_target() const {
     return share_target_;
   }
@@ -483,8 +479,6 @@
       std::vector<WebAppShortcutsMenuItemInfo> shortcuts_menu_infos);
   void SetFileHandlers(apps::FileHandlers file_handlers);
   void SetFileHandlerApprovalState(ApiApprovalState approval_state);
-  void SetFileHandlerOsIntegrationState(
-      OsIntegrationState os_integration_state);
   void SetShareTarget(std::optional<apps::ShareTarget> share_target);
   void SetAdditionalSearchTerms(
       std::vector<std::string> additional_search_terms);
@@ -636,11 +630,6 @@
   // The state of the user's approval of the app's use of the File Handler API.
   ApiApprovalState file_handler_approval_state_ =
       ApiApprovalState::kRequiresPrompt;
-  // Tracks whether file handling has been or should be enabled at the OS level.
-  // This might go out of sync with actual OS integration status, as Chrome does
-  // not actively monitor OS registries.
-  OsIntegrationState file_handler_os_integration_state_ =
-      OsIntegrationState::kDisabled;
   bool window_controls_overlay_enabled_ = false;
   std::optional<LaunchHandler> launch_handler_;
   std::optional<webapps::AppId> parent_app_id_;
diff --git a/chrome/browser/web_applications/web_app_constants.h b/chrome/browser/web_applications/web_app_constants.h
index b548f97..c539503 100644
--- a/chrome/browser/web_applications/web_app_constants.h
+++ b/chrome/browser/web_applications/web_app_constants.h
@@ -232,14 +232,6 @@
 
 std::ostream& operator<<(std::ostream& os, ApiApprovalState state);
 
-// State concerning whether a particular feature has been enabled at the OS
-// level. For example, with File Handling, this indicates whether an app should
-// be/has been registered with the OS to handle opening certain file types.
-enum class OsIntegrationState {
-  kEnabled = 0,
-  kDisabled = 1,
-};
-
 // TODO(b/274172447): Remove these and the manifest.h include after refactoring
 // away blink::Manifest and moving the inner classes to regular classes
 using LaunchHandler = blink::Manifest::LaunchHandler;
diff --git a/chrome/browser/web_applications/web_app_database.cc b/chrome/browser/web_applications/web_app_database.cc
index 950ab830..7d1a66d 100644
--- a/chrome/browser/web_applications/web_app_database.cc
+++ b/chrome/browser/web_applications/web_app_database.cc
@@ -209,26 +209,6 @@
   }
 }
 
-OsIntegrationState ProtoToOsIntegrationState(
-    WebAppProto::OsIntegrationState state) {
-  switch (state) {
-    case WebAppProto_OsIntegrationState_ENABLED:
-      return OsIntegrationState::kEnabled;
-    case WebAppProto_OsIntegrationState_DISABLED:
-      return OsIntegrationState::kDisabled;
-  }
-}
-
-WebAppProto::OsIntegrationState OsIntegrationStateToProto(
-    OsIntegrationState state) {
-  switch (state) {
-    case OsIntegrationState::kEnabled:
-      return WebAppProto_OsIntegrationState_ENABLED;
-    case OsIntegrationState::kDisabled:
-      return WebAppProto_OsIntegrationState_DISABLED;
-  }
-}
-
 apps::FileHandler::LaunchType ProtoToLaunchType(
     WebAppFileHandlerProto::LaunchType state) {
   switch (state) {
@@ -788,9 +768,6 @@
   local_data->set_file_handler_approval_state(
       ApiApprovalStateToProto(web_app.file_handler_approval_state()));
 
-  local_data->set_file_handler_os_integration_state(
-      OsIntegrationStateToProto(web_app.file_handler_os_integration_state()));
-
   local_data->set_window_controls_overlay_enabled(
       web_app.window_controls_overlay_enabled());
 
@@ -1539,11 +1516,6 @@
         ProtoToApiApprovalState(local_data.file_handler_approval_state()));
   }
 
-  if (local_data.has_file_handler_os_integration_state()) {
-    web_app->SetFileHandlerOsIntegrationState(ProtoToOsIntegrationState(
-        local_data.file_handler_os_integration_state()));
-  }
-
   if (local_data.has_window_controls_overlay_enabled()) {
     web_app->SetWindowControlsOverlayEnabled(
         local_data.window_controls_overlay_enabled());
diff --git a/chrome/browser/web_applications/web_app_run_on_os_login_manager_browsertest.cc b/chrome/browser/web_applications/web_app_run_on_os_login_manager_browsertest.cc
index ddd01de..1829bca 100644
--- a/chrome/browser/web_applications/web_app_run_on_os_login_manager_browsertest.cc
+++ b/chrome/browser/web_applications/web_app_run_on_os_login_manager_browsertest.cc
@@ -9,6 +9,7 @@
 #include "base/auto_reset.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/test/gmock_expected_support.h"
 #include "base/test/run_until.h"
 #include "base/test/test_future.h"
 #include "base/values.h"
@@ -21,14 +22,19 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/startup/first_run_service.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
+#include "chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.h"
 #include "chrome/browser/ui/web_applications/web_app_browsertest_base.h"
 #include "chrome/browser/ui/web_applications/web_app_run_on_os_login_notification.h"
+#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
+#include "chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_policy_constants.h"
+#include "chrome/browser/web_applications/isolated_web_apps/test/isolated_web_app_builder.h"
 #include "chrome/browser/web_applications/policy/web_app_policy_constants.h"
 #include "chrome/browser/web_applications/policy/web_app_policy_manager.h"
 #include "chrome/browser/web_applications/preinstalled_web_app_manager.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
 #include "chrome/browser/web_applications/test/web_app_test_observers.h"
 #include "chrome/browser/web_applications/test/web_app_test_utils.h"
+#include "chrome/browser/web_applications/web_app.h"
 #include "chrome/browser/web_applications/web_app_command_manager.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
@@ -57,9 +63,22 @@
 
 namespace {
 
-constexpr char kTestApp[] = "https://test.test";
-
-constexpr char kTestAppName[] = "WebApp";
+inline constexpr char kTestApp[] = "https://test.test";
+inline constexpr char kTestAppName[] = "WebApp";
+inline constexpr uint8_t kTestPublicKey[] = {
+    0xE4, 0xD5, 0x16, 0xC9, 0x85, 0x9A, 0xF8, 0x63, 0x56, 0xA3, 0x51,
+    0x66, 0x7D, 0xBD, 0x00, 0x43, 0x61, 0x10, 0x1A, 0x92, 0xD4, 0x02,
+    0x72, 0xFE, 0x2B, 0xCE, 0x81, 0xBB, 0x3B, 0x71, 0x3F, 0x2D};
+inline constexpr uint8_t kTestPrivateKey[] = {
+    0x1F, 0x27, 0x3F, 0x93, 0xE9, 0x59, 0x4E, 0xC7, 0x88, 0x82, 0xC7, 0x49,
+    0xF8, 0x79, 0x3D, 0x8C, 0xDB, 0xE4, 0x60, 0x1C, 0x21, 0xF1, 0xD9, 0xF9,
+    0xBC, 0x3A, 0xB5, 0xC7, 0x7F, 0x2D, 0x95, 0xE1,
+    // public key (part of the private key)
+    0xE4, 0xD5, 0x16, 0xC9, 0x85, 0x9A, 0xF8, 0x63, 0x56, 0xA3, 0x51, 0x66,
+    0x7D, 0xBD, 0x00, 0x43, 0x61, 0x10, 0x1A, 0x92, 0xD4, 0x02, 0x72, 0xFE,
+    0x2B, 0xCE, 0x81, 0xBB, 0x3B, 0x71, 0x3F, 0x2D};
+constexpr std::string_view kUpdateManifestFileName = "update_manifest.json";
+constexpr std::string_view kBundleFileName = "bundle.swbn";
 
 class MockNetworkConnectionTracker : public network::NetworkConnectionTracker {
  public:
@@ -81,16 +100,97 @@
   }
 };
 
+class RunOnOsLoginTestHandlerMixin : public InProcessBrowserTestMixin {
+ public:
+  explicit RunOnOsLoginTestHandlerMixin(
+      InProcessBrowserTestMixinHost* mixin_host,
+      InProcessBrowserTest* test_base)
+      : InProcessBrowserTestMixin(mixin_host),
+        test_base_(test_base),
+        // ROOL startup done manually to ensure that SetUpOnMainThread is run
+        // before.
+        skip_run_on_os_login_startup_(std::make_unique<base::AutoReset<bool>>(
+            WebAppRunOnOsLoginManager::SkipStartupForTesting())) {}
+
+  void SetUpOnMainThread() override {
+    profile_ = test_base_->browser()->profile();
+    provider_ = WebAppProvider::GetForTest(profile_);
+  }
+
+  void TearDownOnMainThread() override {
+    test_base_ = nullptr;
+    profile_ = nullptr;
+    provider_ = nullptr;
+  }
+
+  void AddRoolApp(const std::string& manifest_id,
+                  const std::string& run_on_os_login,
+                  bool prevent_close = false) {
+    CHECK(provider_);
+    CHECK(profile_);
+    base::test::TestFuture<void> policy_refresh_sync_future;
+    provider_->policy_manager()
+        .SetRefreshPolicySettingsCompletedCallbackForTesting(
+            policy_refresh_sync_future.GetCallback());
+    PrefService* prefs = profile_->GetPrefs();
+    base::Value::List web_app_settings =
+        prefs->GetList(prefs::kWebAppSettings).Clone();
+    web_app_settings.Append(base::Value::Dict()
+                                .Set(kManifestId, manifest_id)
+                                .Set(kRunOnOsLogin, run_on_os_login)
+                                .Set(kPreventClose, prevent_close));
+    prefs->SetList(prefs::kWebAppSettings, std::move(web_app_settings));
+    EXPECT_TRUE(policy_refresh_sync_future.Wait());
+  }
+
+  void RunOsLogin() {
+    CHECK(provider_);
+    CHECK(!completed_future_);
+    completed_future_ = std::make_unique<base::test::TestFuture<void>>();
+    auto& rool_manager = provider_->run_on_os_login_manager();
+    rool_manager.SetCompletedClosureForTesting(
+        completed_future_->GetCallback());
+    rool_manager.Start();
+  }
+
+  void WaitForRunOnOsLogin() {
+    CHECK(provider_);
+    CHECK(completed_future_);
+    // Wait until the top-level command is added and done.
+    ASSERT_TRUE(completed_future_->Wait());
+    // Wait for the triggered sub-commands to be done.
+    provider_->command_manager().AwaitAllCommandsCompleteForTesting();
+  }
+
+  void ClearRoolSettings() {
+    CHECK(profile_);
+    CHECK(provider_);
+    base::test::TestFuture<void> future;
+    provider_->policy_manager()
+        .SetRefreshPolicySettingsCompletedCallbackForTesting(
+            future.GetCallback());
+    profile_->GetPrefs()->SetList(prefs::kWebAppSettings, base::Value::List());
+    ASSERT_TRUE(future.Wait());
+  }
+
+  void ResetSkipRunOnOsLoginStartup() { skip_run_on_os_login_startup_.reset(); }
+
+ private:
+  raw_ptr<InProcessBrowserTest> test_base_;
+  raw_ptr<Profile> profile_ = nullptr;
+  raw_ptr<WebAppProvider> provider_ = nullptr;
+  std::unique_ptr<base::AutoReset<bool>> skip_run_on_os_login_startup_;
+  std::unique_ptr<base::test::TestFuture<void>> completed_future_;
+  base::test::ScopedFeatureList scoped_feature_list_{
+      features::kDesktopPWAsRunOnOsLogin};
+};
+
 class WebAppRunOnOsLoginManagerBrowserTest
     : public WebAppBrowserTestBase,
       public NotificationDisplayService::Observer {
  public:
   WebAppRunOnOsLoginManagerBrowserTest()
-      :  // ROOL startup done manually to ensure that SetUpOnMainThread is run
-         // before
-        skip_run_on_os_login_startup_(std::make_unique<base::AutoReset<bool>>(
-            WebAppRunOnOsLoginManager::SkipStartupForTesting())),
-        skip_preinstalled_web_app_startup_(
+      : skip_preinstalled_web_app_startup_(
             PreinstalledWebAppManager::SkipStartupForTesting()) {}
 
   void SetUpOnMainThread() override {
@@ -102,10 +202,13 @@
         /*network_connection_tracker=*/nullptr);
     content::SetNetworkConnectionTrackerForTesting(mock_tracker_.get());
     test::WaitUntilWebAppProviderAndSubsystemsReady(&provider());
+    run_on_os_login_handler_.ResetSkipRunOnOsLoginStartup();
   }
 
   void TearDownOnMainThread() override {
     content::SetNetworkConnectionTrackerForTesting(nullptr);
+    run_on_os_login_handler_.TearDown();
+    WebAppBrowserTestBase::TearDownOnMainThread();
   }
 
   // NotificationDisplayService::Observer:
@@ -145,29 +248,6 @@
     observer.Wait();
   }
 
-  void AddRoolApp(const std::string& manifest_id,
-                  const std::string& run_on_os_login,
-                  bool prevent_close = false) {
-    base::test::TestFuture<void> policy_refresh_sync_future;
-    provider()
-        .policy_manager()
-        .SetRefreshPolicySettingsCompletedCallbackForTesting(
-            policy_refresh_sync_future.GetCallback());
-    PrefService* prefs = profile()->GetPrefs();
-    base::Value::List web_app_settings =
-        prefs->GetList(prefs::kWebAppSettings).Clone();
-    web_app_settings.Append(base::Value::Dict()
-                                .Set(kManifestId, manifest_id)
-                                .Set(kRunOnOsLogin, run_on_os_login)
-                                .Set(kPreventClose, prevent_close));
-    prefs->SetList(prefs::kWebAppSettings, std::move(web_app_settings));
-    EXPECT_TRUE(policy_refresh_sync_future.Wait());
-  }
-
-  void ClearWebAppSettings() {
-    profile()->GetPrefs()->SetList(prefs::kWebAppSettings, base::Value::List());
-  }
-
   Browser* FindAppBrowser(GURL app_url) {
     auto web_app = FindAppWithUrlInScope(app_url);
     if (!web_app) {
@@ -178,46 +258,29 @@
     return AppBrowserController::FindForWebApp(*profile(), app_id);
   }
 
-  void RunOsLogin() {
-    auto& rool_manager = provider().run_on_os_login_manager();
-    rool_manager.SetCompletedClosureForTesting(completed_future_.GetCallback());
-    rool_manager.Start();
-  }
-
-  void WaitForAllCommandsFinished() {
-    // Wait until the top-level command is added and done.
-    ASSERT_TRUE(completed_future_.Wait());
-    // Wait for the triggered sub-commands to be done.
-    provider().command_manager().AwaitAllCommandsCompleteForTesting();
-  }
-
   std::unique_ptr<MockNetworkConnectionTracker> mock_tracker_;
-  std::unique_ptr<base::AutoReset<bool>> skip_run_on_os_login_startup_;
   base::AutoReset<bool> skip_preinstalled_web_app_startup_;
   std::unique_ptr<NotificationDisplayServiceTester> notification_tester_;
-  base::test::TestFuture<void> completed_future_;
-  base::test::ScopedFeatureList scoped_feature_list_{
-      features::kDesktopPWAsRunOnOsLogin};
   base::ScopedObservation<NotificationDisplayService,
                           WebAppRunOnOsLoginManagerBrowserTest>
       notification_observation_{this};
+  RunOnOsLoginTestHandlerMixin run_on_os_login_handler_{&mixin_host_, this};
 };
 
 IN_PROC_BROWSER_TEST_F(
     WebAppRunOnOsLoginManagerBrowserTest,
     WebAppRunOnOsLoginWithInitialPolicyValueLaunchesBrowserWindow) {
-  skip_run_on_os_login_startup_ = nullptr;
   EXPECT_CALL(*mock_tracker_, GetConnectionType(_, _))
       .WillRepeatedly(DoAll(
           SetArgPointee<0>(network::mojom::ConnectionType::CONNECTION_ETHERNET),
           Return(true)));
 
   AddForceInstalledApp(kTestApp, kTestAppName);
-  AddRoolApp(kTestApp, kRunWindowed);
+  run_on_os_login_handler_.AddRoolApp(kTestApp, kRunWindowed);
 
   // Wait for ROOL.
-  RunOsLogin();
-  WaitForAllCommandsFinished();
+  run_on_os_login_handler_.RunOsLogin();
+  run_on_os_login_handler_.WaitForRunOnOsLogin();
 
   // Should have 2 browsers: normal and app.
   ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile()));
@@ -229,18 +292,17 @@
 IN_PROC_BROWSER_TEST_F(
     WebAppRunOnOsLoginManagerBrowserTest,
     WebAppRunOnOsLoginWithForceInstallLaunchesBrowserWindow) {
-  skip_run_on_os_login_startup_.reset();
   EXPECT_CALL(*mock_tracker_, GetConnectionType(_, _))
       .WillRepeatedly(DoAll(
           SetArgPointee<0>(network::mojom::ConnectionType::CONNECTION_ETHERNET),
           Return(true)));
 
   AddForceInstalledApp(kTestApp, kTestAppName);
-  AddRoolApp(kTestApp, kRunWindowed);
+  run_on_os_login_handler_.AddRoolApp(kTestApp, kRunWindowed);
 
   // Wait for ROOL.
-  RunOsLogin();
-  WaitForAllCommandsFinished();
+  run_on_os_login_handler_.RunOsLogin();
+  run_on_os_login_handler_.WaitForRunOnOsLogin();
 
   // Should have 2 browsers: normal and app.
   ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile()));
@@ -251,17 +313,16 @@
 
 IN_PROC_BROWSER_TEST_F(WebAppRunOnOsLoginManagerBrowserTest,
                        WebAppRunOnOsLoginNetworkNotConnectedCallSynchronous) {
-  skip_run_on_os_login_startup_.reset();
   EXPECT_CALL(*mock_tracker_, GetConnectionType(_, _))
       .WillRepeatedly(DoAll(
           SetArgPointee<0>(network::mojom::ConnectionType::CONNECTION_NONE),
           Return(true)));
 
   AddForceInstalledApp(kTestApp, kTestAppName);
-  AddRoolApp(kTestApp, kRunWindowed);
+  run_on_os_login_handler_.AddRoolApp(kTestApp, kRunWindowed);
 
   // Wait for ROOL.
-  RunOsLogin();
+  run_on_os_login_handler_.RunOsLogin();
   provider().command_manager().AwaitAllCommandsCompleteForTesting();
 
   // Should have only the normal browser as there is no network.
@@ -270,7 +331,7 @@
   // Simulate the network coming back.
   mock_tracker_->OnNetworkChanged(
       network::mojom::ConnectionType::CONNECTION_WIFI);
-  WaitForAllCommandsFinished();
+  run_on_os_login_handler_.WaitForRunOnOsLogin();
 
   // Should have 2 browsers: normal and app.
   ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile()));
@@ -282,7 +343,6 @@
 IN_PROC_BROWSER_TEST_F(
     WebAppRunOnOsLoginManagerBrowserTest,
     WebAppRunOnOsLoginNetworkNotConnectedCallAsynchronousInitiallyConnected) {
-  skip_run_on_os_login_startup_.reset();
   base::OnceCallback<void(network::mojom::ConnectionType)>
       connection_changed_callback;
   EXPECT_CALL(*mock_tracker_, GetConnectionType(_, _))
@@ -296,10 +356,10 @@
           }));
 
   AddForceInstalledApp(kTestApp, kTestAppName);
-  AddRoolApp(kTestApp, kRunWindowed);
+  run_on_os_login_handler_.AddRoolApp(kTestApp, kRunWindowed);
 
   // Wait for ROOL.
-  RunOsLogin();
+  run_on_os_login_handler_.RunOsLogin();
   provider().command_manager().AwaitAllCommandsCompleteForTesting();
 
   // Should have only the normal browser as there is no network.
@@ -308,7 +368,7 @@
   // Asynchronously notify that there is a network connection
   std::move(connection_changed_callback)
       .Run(network::mojom::ConnectionType::CONNECTION_WIFI);
-  WaitForAllCommandsFinished();
+  run_on_os_login_handler_.WaitForRunOnOsLogin();
 
   // Should have 2 browsers: normal and app.
   ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile()));
@@ -320,7 +380,6 @@
 IN_PROC_BROWSER_TEST_F(
     WebAppRunOnOsLoginManagerBrowserTest,
     WebAppRunOnOsLoginNetworkNotConnectedCallAsynchronousInitiallyDisconnected) {
-  skip_run_on_os_login_startup_.reset();
   base::OnceCallback<void(network::mojom::ConnectionType)>
       connection_changed_callback;
   EXPECT_CALL(*mock_tracker_, GetConnectionType(_, _))
@@ -334,10 +393,10 @@
           }));
 
   AddForceInstalledApp(kTestApp, kTestAppName);
-  AddRoolApp(kTestApp, kRunWindowed);
+  run_on_os_login_handler_.AddRoolApp(kTestApp, kRunWindowed);
 
   // Wait for ROOL.
-  RunOsLogin();
+  run_on_os_login_handler_.RunOsLogin();
   provider().command_manager().AwaitAllCommandsCompleteForTesting();
 
   // Should have only the normal browser as there is no network.
@@ -354,7 +413,7 @@
   // Simulate the network coming back.
   mock_tracker_->OnNetworkChanged(
       network::mojom::ConnectionType::CONNECTION_WIFI);
-  WaitForAllCommandsFinished();
+  run_on_os_login_handler_.WaitForRunOnOsLogin();
 
   // Should have 2 browsers: normal and app.
   ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile()));
@@ -382,7 +441,6 @@
 
 IN_PROC_BROWSER_TEST_P(WebAppRunOnOsLoginNotificationBrowserTest,
                        WebAppRunOnOsLoginNotificationOpensManagementUI) {
-  skip_run_on_os_login_startup_.reset();
   EXPECT_CALL(*mock_tracker_, GetConnectionType(_, _))
       .WillRepeatedly(DoAll(
           SetArgPointee<0>(network::mojom::ConnectionType::CONNECTION_ETHERNET),
@@ -392,14 +450,17 @@
   for (size_t i = 0; i < test_params.number_of_rool_apps; i++) {
     const auto app_id = base::StrCat({kTestApp, base::ToString(i)});
     AddForceInstalledApp(app_id, kTestAppName);
-    AddRoolApp(app_id, kRunWindowed,
-               /*prevent_close=*/i < test_params.number_of_prevent_close_apps);
+    run_on_os_login_handler_.AddRoolApp(
+        app_id, kRunWindowed,
+        /*prevent_close=*/i < test_params.number_of_prevent_close_apps);
   }
-  const absl::Cleanup policy_cleanup = [this]() { ClearWebAppSettings(); };
+  const absl::Cleanup policy_cleanup = [this]() {
+    run_on_os_login_handler_.ClearRoolSettings();
+  };
 
   // Wait for ROOL.
-  RunOsLogin();
-  WaitForAllCommandsFinished();
+  run_on_os_login_handler_.RunOsLogin();
+  run_on_os_login_handler_.WaitForRunOnOsLogin();
 
   // Should have `number_of_rool_apps` + 1 browsers: normal and
   // `number_of_rool_apps` apps.
@@ -438,7 +499,6 @@
 
 IN_PROC_BROWSER_TEST_P(WebAppRunOnOsLoginNotificationBrowserTest,
                        WebAppRunOnOsLoginNotification) {
-  skip_run_on_os_login_startup_.reset();
   EXPECT_CALL(*mock_tracker_, GetConnectionType(_, _))
       .WillRepeatedly(DoAll(
           SetArgPointee<0>(network::mojom::ConnectionType::CONNECTION_ETHERNET),
@@ -448,14 +508,17 @@
   for (size_t i = 0; i < test_params.number_of_rool_apps; i++) {
     const auto app_id = base::StrCat({kTestApp, base::ToString(i)});
     AddForceInstalledApp(app_id, kTestAppName);
-    AddRoolApp(app_id, kRunWindowed,
-               /*prevent_close=*/i < test_params.number_of_prevent_close_apps);
+    run_on_os_login_handler_.AddRoolApp(
+        app_id, kRunWindowed,
+        /*prevent_close=*/i < test_params.number_of_prevent_close_apps);
   }
-  const absl::Cleanup policy_cleanup = [this]() { ClearWebAppSettings(); };
+  const absl::Cleanup policy_cleanup = [this]() {
+    run_on_os_login_handler_.ClearRoolSettings();
+  };
 
   // Wait for ROOL.
-  RunOsLogin();
-  WaitForAllCommandsFinished();
+  run_on_os_login_handler_.RunOsLogin();
+  run_on_os_login_handler_.WaitForRunOnOsLogin();
 
   bool notification_shown = base::test::RunUntil([&]() {
     return notification_tester_->GetNotification(kRunOnOsLoginNotificationId)
@@ -555,6 +618,146 @@
                 u"Your administrator has set up some apps to start "
                 u"automatically. Some of these apps may not be closed."}));
 
+class IsolatedWebAppRunOnOsLoginManagerBrowserTest
+    : public IsolatedWebAppBrowserTestHarness {
+ public:
+  IsolatedWebAppRunOnOsLoginManagerBrowserTest() = default;
+
+ protected:
+  void SetUpOnMainThread() override {
+    IsolatedWebAppBrowserTestHarness::SetUpOnMainThread();
+    test::WaitUntilWebAppProviderAndSubsystemsReady(&provider());
+    SetUpFilesAndServer();
+    AddTrustedWebBundleIdForTesting(url_info_->web_bundle_id());
+    run_on_os_login_handler_.ResetSkipRunOnOsLoginStartup();
+  }
+
+  void TearDownOnMainThread() override {
+    run_on_os_login_handler_.TearDown();
+    IsolatedWebAppBrowserTestHarness::TearDownOnMainThread();
+  }
+
+  void SetUpFilesAndServer() {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    // We cannot use `ScopedTempDir` here because the directory must survive
+    // restarts for the `PRE_` tests to work. Use a directory within the profile
+    // directory instead.
+    temp_dir_ = profile()->GetPath().AppendASCII("iwa-temp-for-testing");
+    EXPECT_TRUE(base::CreateDirectory(temp_dir_));
+    iwa_server_.ServeFilesFromDirectory(temp_dir_);
+    EXPECT_TRUE(iwa_server_.Start());
+
+    auto key_pair = web_package::WebBundleSigner::Ed25519KeyPair(
+        kTestPublicKey, kTestPrivateKey);
+    auto bundle_id = web_package::SignedWebBundleId::CreateForEd25519PublicKey(
+        key_pair_.public_key);
+    url_info_ = IsolatedWebAppUrlInfo::CreateFromSignedWebBundleId(bundle_id);
+
+    auto builder = IsolatedWebAppBuilder(
+        ManifestBuilder().SetName("app-1.0.0").SetVersion("1.0.0"));
+    builder.AddHtml("/", R"(
+        <head>
+          <script type="text/javascript" src="/register-sw.js"></script>
+          <title>1.0.0</title>
+        </head>
+        <body>
+          <h1>Hello from version 1.0.0</h1>
+        </body>)");
+    builder.AddJs("/register-sw.js", R"(
+        window.trustedTypes.createPolicy('default', {
+          createHTML: (html) => html,
+          createScriptURL: (url) => url,
+          createScript: (script) => script,
+        });
+        if (location.search.includes('register-sw=1')) {
+          navigator.serviceWorker.register("/sw.js");
+        }
+      )");
+    builder.AddJs("/sw.js", R"(
+        self.addEventListener('install', (event) => {
+          self.skipWaiting();
+        });
+        self.addEventListener("fetch", (event) => {
+          console.log("SW: used fetch: " + event.request.url);
+          event.respondWith(new Response("", {
+            status: 404,
+            statusText: "Not Found",
+          }));
+        });
+      )");
+    base::FilePath bundle_304_path = temp_dir_.Append(kBundleFileName);
+    bundle_304_ = builder.BuildBundle(bundle_304_path, key_pair_);
+
+    EXPECT_TRUE(base::WriteFile(
+        temp_dir_.Append(kUpdateManifestFileName),
+        base::ReplaceStringPlaceholders(
+            R"(
+              {
+                "versions": [
+                  {"version": "1.0.0", "src": "$1"}
+                ]
+              }
+            )",
+            {iwa_server_.GetURL(base::StrCat({"/", kBundleFileName})).spec()},
+            /*offsets=*/nullptr)));
+  }
+
+  Browser* FindAppBrowser(GURL app_url) {
+    auto web_app = FindAppWithUrlInScope(app_url);
+    if (!web_app) {
+      return nullptr;
+    }
+    webapps::AppId app_id = web_app.value();
+
+    return AppBrowserController::FindForWebApp(*profile(), app_id);
+  }
+
+  std::optional<IsolatedWebAppUrlInfo> url_info_;
+  base::FilePath temp_dir_;
+  net::EmbeddedTestServer iwa_server_;
+  std::unique_ptr<BundledIsolatedWebApp> bundle_304_;
+  web_package::WebBundleSigner::Ed25519KeyPair key_pair_ =
+      web_package::WebBundleSigner::Ed25519KeyPair(kTestPublicKey,
+                                                   kTestPrivateKey);
+  RunOnOsLoginTestHandlerMixin run_on_os_login_handler_{&mixin_host_, this};
+};
+
+IN_PROC_BROWSER_TEST_F(IsolatedWebAppRunOnOsLoginManagerBrowserTest,
+                       IwaRunsOnOsLoginNoPreventCloseSuccess) {
+  const absl::Cleanup policy_cleanup = [this]() {
+    run_on_os_login_handler_.ClearRoolSettings();
+  };
+
+  web_app::WebAppTestInstallObserver observer(profile());
+  observer.BeginListening({url_info_->app_id()});
+
+  profile()->GetPrefs()->SetList(
+      prefs::kIsolatedWebAppInstallForceList,
+      base::Value::List().Append(
+          base::Value::Dict()
+              .Set(kPolicyWebBundleIdKey, url_info_->web_bundle_id().id())
+              .Set(kPolicyUpdateManifestUrlKey,
+                   iwa_server_
+                       .GetURL(base::StrCat({"/", kUpdateManifestFileName}))
+                       .spec())));
+
+  ASSERT_EQ(url_info_->app_id(), observer.Wait());
+
+  std::string manifest_id = url_info_->origin().GetURL().spec();
+  run_on_os_login_handler_.AddRoolApp(manifest_id, kRunWindowed,
+                                      /*prevent_close=*/false);
+
+  // Wait for ROOL.
+  run_on_os_login_handler_.RunOsLogin();
+  run_on_os_login_handler_.WaitForRunOnOsLogin();
+
+  // Should have 2 browsers: normal and app.
+  ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile()));
+  Browser* app_browser = FindAppBrowser(GURL(manifest_id));
+
+  ASSERT_TRUE(app_browser);
+}
+
 }  // namespace
 
 }  // namespace web_app
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt
index 10a6464..92aea22 100644
--- a/chrome/build/android-arm32.pgo.txt
+++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@
-chrome-android32-main-1718603460-820a190069a7598b972154631fbcab1b02eb4ab6-e1200e29f3595324d73f213e24eb7e0190586771.profdata
+chrome-android32-main-1718647181-bb5da665ad8e93e3a654d2b7e9f1f47523ef2bb4-f534d7212a1ad6a3b2fe027d981cef1cf84bb671.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt
index a54bba06..f1bdc39 100644
--- a/chrome/build/android-arm64.pgo.txt
+++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@
-chrome-android64-main-1718596148-108423f915bb4b7234fb8650bfa349a814a21d9b-f3c39da1125689c3b37adf7d4e726037494356b1.profdata
+chrome-android64-main-1718639700-cdf6f33410f077420f76f862fa49d634c9a25b26-59804dab41a756252b58227b66ebb8f0fc7456de.profdata
diff --git a/chrome/build/lacros64.pgo.txt b/chrome/build/lacros64.pgo.txt
index 726ba846..2021a45 100644
--- a/chrome/build/lacros64.pgo.txt
+++ b/chrome/build/lacros64.pgo.txt
@@ -1 +1 @@
-chrome-chromeos-amd64-generic-main-1718420440-f8cd5109d0e5ad1462408c4d2c9b681b74404894-237f9fc44d6960070e22d41931a09e685609ff5e.profdata
+chrome-chromeos-amd64-generic-main-1718626114-589152c9889909e2d54924c487648e4fbef3575b-f8a47a8ef8201f17ea2546700db9763fa1a9a675.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 6e8eaeb..bd76917 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1718603460-05a08d10a2b9bb821a1db3a5a59cee3c6948f18e-e1200e29f3595324d73f213e24eb7e0190586771.profdata
+chrome-linux-main-1718625171-690dda8ef126179c78e43cc1d135b1db2ea4f19f-b7ecd1923696c8ea796fcbfb3e263bdd174d1853.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index ed12b508..d57eb1e 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1718610814-e071686e76401b6298ff422d489dc43b613c3fac-196ee6f4b4595a4148fc63afb2bdf6e7f4620b6a.profdata
+chrome-mac-arm-main-1718647181-4dd686e5122a702601640de0dff694ecae02a4d3-f534d7212a1ad6a3b2fe027d981cef1cf84bb671.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 901921c1..58f1978 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1718603460-624d98142918e1d205bd627a6e34cb5816ec0393-e1200e29f3595324d73f213e24eb7e0190586771.profdata
+chrome-win64-main-1718636384-436bfd7fc57fb0511b69aab604aeb3a1d3dbe579-9caeb0e85926a11e354bb5847a7af10a741d79c4.profdata
diff --git a/chrome/common/accessibility/read_anything.mojom b/chrome/common/accessibility/read_anything.mojom
index ba67c09..3e1dcca 100644
--- a/chrome/common/accessibility/read_anything.mojom
+++ b/chrome/common/accessibility/read_anything.mojom
@@ -12,32 +12,6 @@
 import "ui/accessibility/mojom/ax_tree_update.mojom";
 import "mojo/public/mojom/base/values.mojom";
 
-// Used to represent the current user choices for the Read Anything visual
-// presentation/theme. This includes font name, size, spacing, and colors.
-struct ReadAnythingTheme {
-  // The name of the user's font choice.
-  string font_name;
-
-  // The px value of the user's font size.
-  float font_size;
-
-  // True if links are enabled.
-  bool links_enabled;
-
-  // True if images are enabled.
-  bool images_enabled;
-
-  // The various colors of the user's chosen theme.
-  skia.mojom.SkColor foreground_color;
-  skia.mojom.SkColor background_color;
-
-  // The enum value of the user's line spacing choice
-  read_anything.mojom.LineSpacing line_spacing;
-
-  // The enum value of the user's letter spacing choice.
-  read_anything.mojom.LetterSpacing letter_spacing;
-};
-
 [Extensible]
 enum InstallationState {
   [Default] kUnknown = 0,
@@ -233,9 +207,6 @@
   // previously passed to AccessibilityEventsReceived.
   OnAXTreeDestroyed(ax.mojom.AXTreeID tree_id);
 
-  // Send an updated theme to the WebUI.
-  OnThemeChanged(ReadAnythingTheme new_theme);
-
   // Send an updated language code to the WebUI. Will either be the page
   // language or the browser language depending on what's available.
   SetLanguageCode(string code);
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 5d0fa7a8..e542dc8 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -185,6 +185,10 @@
 const char kDisableComponentUpdate[] = "disable-component-update";
 #endif
 
+// Disables crashpad initialization for testing. The crashpad binary will not
+// run, and thus will not detect and symbolize crashes.
+const char kDisableCrashpadForTesting[] = "disable-crashpad-for-testing";
+
 // Disables installation of default apps on first run. This is used during
 // automated testing.
 const char kDisableDefaultApps[] = "disable-default-apps";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 8309b50..a27cf09 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -76,6 +76,7 @@
 #if BUILDFLAG(ENABLE_COMPONENT_UPDATER)
 extern const char kDisableComponentUpdate[];
 #endif
+extern const char kDisableCrashpadForTesting[];
 extern const char kDisableDefaultApps[];
 extern const char kDisableDomainReliability[];
 extern const char kDisableExtensions[];
diff --git a/chrome/enterprise_companion/BUILD.gn b/chrome/enterprise_companion/BUILD.gn
index 44187c8..bbde265 100644
--- a/chrome/enterprise_companion/BUILD.gn
+++ b/chrome/enterprise_companion/BUILD.gn
@@ -55,6 +55,7 @@
     "//base/test:test_support",
     "//chrome/enterprise_companion/device_management_storage",
     "//chrome/enterprise_companion/device_management_storage:unit_tests",
+    "//chrome/updater:constants_test",
     "//components/named_mojo_ipc_server",
     "//components/policy/core/common",
     "//components/policy/core/common:test_support",
@@ -73,7 +74,10 @@
 if (!is_official_build) {
   executable("enterprise_companion") {
     sources = [ "main.cc" ]
-    deps = [ ":base" ]
+    deps = [
+      ":base",
+      "//chrome/updater:constants_prod",
+    ]
 
     if (is_win) {
       configs += [ "//build/config/win:windowed" ]
diff --git a/chrome/enterprise_companion/device_management_storage/BUILD.gn b/chrome/enterprise_companion/device_management_storage/BUILD.gn
index d2f100b..43cab30 100644
--- a/chrome/enterprise_companion/device_management_storage/BUILD.gn
+++ b/chrome/enterprise_companion/device_management_storage/BUILD.gn
@@ -2,6 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# Note that this library must be linked against //chrome/updater:constants_prod
+# or constants_test to get symbols for constants_header.
 static_library("device_management_storage") {
   sources = [
     "dm_storage.cc",
@@ -10,13 +12,15 @@
   deps = [
     "//base",
     "//chrome/updater:branding_header",
-    "//chrome/updater:browser_sources",
+    "//chrome/updater:constants_header",
+    "//chrome/updater:public_sources",
     "//components/policy/proto",
   ]
   visibility = [
     ":unit_tests",
     "//chrome/enterprise_companion:*",
     "//chrome/updater:*",
+    "//chrome/updater/tools:*",
   ]
 
   if (is_linux) {
@@ -37,7 +41,8 @@
     ":device_management_storage",
     "//base",
     "//base/test:test_support",
-    "//chrome/updater:browser_sources",
+    "//chrome/updater:constants_test",
+    "//chrome/updater:public_sources",
     "//components/policy/proto",
     "//remoting/host/mojom",
     "//testing/gmock",
diff --git a/chrome/enterprise_companion/device_management_storage/dm_storage_unittest.cc b/chrome/enterprise_companion/device_management_storage/dm_storage_unittest.cc
index 51de085..de65a1c 100644
--- a/chrome/enterprise_companion/device_management_storage/dm_storage_unittest.cc
+++ b/chrome/enterprise_companion/device_management_storage/dm_storage_unittest.cc
@@ -12,7 +12,6 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/memory/scoped_refptr.h"
 #include "build/build_config.h"
-#include "chrome/updater/updater_scope.h"
 #include "components/policy/proto/device_management_backend.pb.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/chrome/renderer/accessibility/read_anything_app_controller.cc b/chrome/renderer/accessibility/read_anything_app_controller.cc
index 71a414871..3b47bcf 100644
--- a/chrome/renderer/accessibility/read_anything_app_controller.cc
+++ b/chrome/renderer/accessibility/read_anything_app_controller.cc
@@ -55,9 +55,6 @@
 #include "v8/include/v8-context.h"
 #include "v8/include/v8-microtask-queue.h"
 
-using read_anything::mojom::ReadAnythingTheme;
-using read_anything::mojom::ReadAnythingThemePtr;
-
 namespace {
 
 constexpr char kUndeterminedLocale[] = "und";
@@ -709,26 +706,6 @@
   ExecuteJavaScript("chrome.readingMode.updateSelection();");
 }
 
-void ReadAnythingAppController::OnThemeChanged(ReadAnythingThemePtr new_theme) {
-  bool needs_redraw_for_links =
-      model_.links_enabled() != new_theme->links_enabled;
-  bool needs_redraw_for_images =
-      model_.images_enabled() != new_theme->images_enabled;
-  model_.OnThemeChanged(std::move(new_theme));
-  ExecuteJavaScript("chrome.readingMode.updateTheme();");
-
-  // Only redraw if there is an active tree.
-  if (needs_redraw_for_links &&
-      model_.active_tree_id() != ui::AXTreeIDUnknown()) {
-    ExecuteJavaScript("chrome.readingMode.updateLinks();");
-  }
-
-  if (needs_redraw_for_images &&
-      model_.active_tree_id() != ui::AXTreeIDUnknown()) {
-    ExecuteJavaScript("chrome.readingMode.updateImages();");
-  }
-}
-
 void ReadAnythingAppController::OnSettingsRestoredFromPrefs(
     read_anything::mojom::LineSpacing line_spacing,
     read_anything::mojom::LetterSpacing letter_spacing,
@@ -768,17 +745,12 @@
       .SetProperty("startOffset", &ReadAnythingAppController::StartOffset)
       .SetProperty("endNodeId", &ReadAnythingAppController::EndNodeId)
       .SetProperty("endOffset", &ReadAnythingAppController::EndOffset)
-      .SetProperty("backgroundColor",
-                   &ReadAnythingAppController::BackgroundColor)
       .SetProperty("fontName", &ReadAnythingAppController::FontName)
       .SetProperty("fontSize", &ReadAnythingAppController::FontSize)
       .SetProperty("linksEnabled", &ReadAnythingAppController::LinksEnabled)
       .SetProperty("imagesEnabled", &ReadAnythingAppController::ImagesEnabled)
-
       .SetProperty("imagesFeatureEnabled",
                    &ReadAnythingAppController::ImagesFeatureEnabled)
-      .SetProperty("foregroundColor",
-                   &ReadAnythingAppController::ForegroundColor)
       .SetProperty("letterSpacing", &ReadAnythingAppController::LetterSpacing)
       .SetProperty("lineSpacing", &ReadAnythingAppController::LineSpacing)
       .SetProperty("standardLineSpacing",
@@ -802,8 +774,6 @@
       .SetProperty("yellowTheme", &ReadAnythingAppController::YellowTheme)
       .SetProperty("blueTheme", &ReadAnythingAppController::BlueTheme)
       .SetProperty("speechRate", &ReadAnythingAppController::SpeechRate)
-      .SetProperty("isWebUIToolbarVisible",
-                   &ReadAnythingAppController::IsWebUIToolbarEnabled)
       .SetProperty("isGoogleDocs", &ReadAnythingAppController::IsGoogleDocs)
       .SetProperty("isReadAloudEnabled",
                    &ReadAnythingAppController::IsReadAloudEnabled)
@@ -887,8 +857,6 @@
                    &ReadAnythingAppController::GetSupportedFonts)
       .SetMethod("setContentForTesting",
                  &ReadAnythingAppController::SetContentForTesting)
-      .SetMethod("setThemeForTesting",
-                 &ReadAnythingAppController::SetThemeForTesting)
       .SetMethod("setLanguageForTesting",
                  &ReadAnythingAppController::SetLanguageForTesting)
       .SetMethod("initAxPositionWithNode",
@@ -955,10 +923,6 @@
   return model_.end_offset();
 }
 
-SkColor ReadAnythingAppController::BackgroundColor() const {
-  return model_.background_color();
-}
-
 std::string ReadAnythingAppController::FontName() const {
   return model_.font_name();
 }
@@ -979,10 +943,6 @@
   return features::IsReadAnythingImagesViaAlgorithmEnabled();
 }
 
-SkColor ReadAnythingAppController::ForegroundColor() const {
-  return model_.foreground_color();
-}
-
 float ReadAnythingAppController::LetterSpacing() const {
   return model_.letter_spacing();
 }
@@ -1284,10 +1244,6 @@
   return ax_node->IsLeaf();
 }
 
-bool ReadAnythingAppController::IsWebUIToolbarEnabled() const {
-  return features::IsReadAnythingWebUIToolbarEnabled();
-}
-
 bool ReadAnythingAppController::IsReadAloudEnabled() const {
   return features::IsReadAnythingReadAloudEnabled();
 }
@@ -1635,25 +1591,6 @@
   return model_.GetCurrentTextEndIndex(node_id);
 }
 
-// TODO(crbug.com/40802192): Change line_spacing and letter_spacing types from
-// int to their corresponding enums.
-void ReadAnythingAppController::SetThemeForTesting(const std::string& font_name,
-                                                   float font_size,
-                                                   bool links_enabled,
-                                                   bool images_enabled,
-                                                   SkColor foreground_color,
-                                                   SkColor background_color,
-                                                   int line_spacing,
-                                                   int letter_spacing) {
-  auto line_spacing_enum =
-      static_cast<read_anything::mojom::LineSpacing>(line_spacing);
-  auto letter_spacing_enum =
-      static_cast<read_anything::mojom::LetterSpacing>(letter_spacing);
-  OnThemeChanged(ReadAnythingTheme::New(
-      font_name, font_size, links_enabled, images_enabled, foreground_color,
-      background_color, line_spacing_enum, letter_spacing_enum));
-}
-
 void ReadAnythingAppController::SetLanguageForTesting(
     const std::string& language_code) {
   SetLanguageCode(language_code);
diff --git a/chrome/renderer/accessibility/read_anything_app_controller.h b/chrome/renderer/accessibility/read_anything_app_controller.h
index 60b0914a..2c13298 100644
--- a/chrome/renderer/accessibility/read_anything_app_controller.h
+++ b/chrome/renderer/accessibility/read_anything_app_controller.h
@@ -113,8 +113,6 @@
                                ukm::SourceId ukm_source_id,
                                bool is_pdf) override;
   void OnAXTreeDestroyed(const ui::AXTreeID& tree_id) override;
-  void OnThemeChanged(
-      read_anything::mojom::ReadAnythingThemePtr new_theme) override;
   void OnSettingsRestoredFromPrefs(
       read_anything::mojom::LineSpacing line_spacing,
       read_anything::mojom::LetterSpacing letter_spacing,
@@ -140,7 +138,6 @@
   int StartOffset() const;
   ui::AXNodeID EndNodeId() const;
   int EndOffset() const;
-  SkColor BackgroundColor() const;
   std::string FontName() const;
   float FontSize() const;
   bool LinksEnabled() const;
@@ -151,7 +148,6 @@
   void OnFontSizeReset();
   void OnLinksEnabledToggled();
   void OnImagesEnabledToggled();
-  SkColor ForegroundColor() const;
   float LetterSpacing() const;
   float LineSpacing() const;
   int ColorTheme() const;
@@ -199,7 +195,6 @@
   void OnCollapseSelection() const;
   void OnRestartReadAloud();
   bool IsGoogleDocs() const;
-  bool IsWebUIToolbarEnabled() const;
   bool IsReadAloudEnabled() const;
   bool IsChromeOsAsh() const;
   bool IsAutoVoiceSwitchingEnabled() const;
@@ -321,10 +316,9 @@
 
   int GetNextWordHighlightLength(int index);
 
-  // SetContentForTesting, SetThemeForTesting, and SetLanguageForTesting are
-  // used by ReadAnythingAppTest and thus need to be kept in
-  // ReadAnythingAppController even though ReadAnythingAppControllerBrowserTest
-  // is friended.
+  // SetContentForTesting and SetLanguageForTesting are used by
+  // ReadAnythingAppTest and thus need to be kept in ReadAnythingAppController
+  // even though ReadAnythingAppControllerBrowserTest is friended.
   // Snapshot_lite is a data structure which resembles an
   // AXTreeUpdate. E.g.:
   //   const axTree = {
@@ -344,14 +338,6 @@
   //   };
   void SetContentForTesting(v8::Local<v8::Value> v8_snapshot_lite,
                             std::vector<ui::AXNodeID> content_node_ids);
-  void SetThemeForTesting(const std::string& font_name,
-                          float font_size,
-                          bool links_enabled,
-                          bool images_enabled,
-                          SkColor foreground_color,
-                          SkColor background_color,
-                          int line_spacing,
-                          int letter_spacing);
   void SetLanguageForTesting(const std::string& language_code);
 
   // Helpers for logging UmaHistograms based on times recorded in WebUI.
diff --git a/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc b/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc
index b3c93356..073e659 100644
--- a/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc
+++ b/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc
@@ -184,17 +184,22 @@
     update->tree_data = tree_data;
   }
 
-  void SetThemeForTesting(const std::string& font_name,
-                          float font_size,
-                          bool links_enabled,
-                          bool images_enabled,
-                          SkColor foreground_color,
-                          SkColor background_color,
-                          int line_spacing,
-                          int letter_spacing) {
-    controller_->SetThemeForTesting(
-        font_name, font_size, links_enabled, images_enabled, foreground_color,
-        background_color, line_spacing, letter_spacing);
+  void OnSettingsRestoredFromPrefs(
+      read_anything::mojom::LineSpacing line_spacing,
+      read_anything::mojom::LetterSpacing letter_spacing,
+      const std::string& font,
+      double font_size,
+      bool links_enabled,
+      bool images_enabled,
+      read_anything::mojom::Colors color,
+      double speech_rate,
+      base::Value::Dict voices,
+      base::Value::List languages_enabled_in_pref,
+      read_anything::mojom::HighlightGranularity granularity) {
+    controller_->OnSettingsRestoredFromPrefs(
+        line_spacing, letter_spacing, font, font_size, links_enabled,
+        images_enabled, color, speech_rate, std::move(voices),
+        std::move(languages_enabled_in_pref), granularity);
   }
 
   void AccessibilityEventReceived(
@@ -298,14 +303,12 @@
 
   bool ImagesEnabled() { return controller_->ImagesEnabled(); }
 
-  SkColor ForegroundColor() { return controller_->ForegroundColor(); }
-
-  SkColor BackgroundColor() { return controller_->BackgroundColor(); }
-
   float LineSpacing() { return controller_->LineSpacing(); }
 
   float LetterSpacing() { return controller_->LetterSpacing(); }
 
+  int ColorTheme() { return controller_->ColorTheme(); }
+
   void OnFontSizeReset() { controller_->OnFontSizeReset(); }
 
   void OnLinksEnabledToggled() { controller_->OnLinksEnabledToggled(); }
@@ -379,8 +382,6 @@
 
   bool IsReadAloudEnabled() { return controller_->IsReadAloudEnabled(); }
 
-  bool IsWebUIToolbarEnabled() { return controller_->IsWebUIToolbarEnabled(); }
-
   bool IsLeafNode(ui::AXNodeID ax_node_id) {
     return controller_->IsLeafNode(ax_node_id);
   }
@@ -411,6 +412,10 @@
 
   double SpeechRate() { return controller_->read_aloud_model_.speech_rate(); }
 
+  int HighlightGranularity() {
+    return controller_->read_aloud_model_.highlight_granularity();
+  }
+
   const base::Value::List& EnabledLanguages() {
     return controller_->read_aloud_model_.languages_enabled_in_pref();
   }
@@ -436,6 +441,10 @@
     controller_->SetLanguageForTesting(code);
   }
 
+  std::vector<std::string> GetLanguagesEnabledInPref() {
+    return controller_->GetLanguagesEnabledInPref();
+  }
+
   size_t GetAccessibleBoundary(const std::u16string& text,
                                int max_text_length) {
     return controller_->GetAccessibleBoundary(text, max_text_length);
@@ -593,36 +602,44 @@
   ASSERT_EQ(GetStoredVoice(), "");
 }
 
-TEST_F(ReadAnythingAppControllerTest, IsWebUIToolbarEnabled) {
-  EXPECT_TRUE(IsWebUIToolbarEnabled());
-
-  scoped_feature_list_.InitAndDisableFeature(
-      features::kReadAnythingWebUIToolbar);
-  EXPECT_FALSE(IsWebUIToolbarEnabled());
-}
-
-TEST_F(ReadAnythingAppControllerTest, Theme) {
-  std::string font_name = "Roboto";
-  float font_size = 18.0;
-  bool links_enabled = false;
-  bool images_enabled = false;
-  SkColor foreground = SkColorSetRGB(0x33, 0x36, 0x39);
-  SkColor background = SkColorSetRGB(0xFD, 0xE2, 0x93);
-  int letter_spacing =
-      static_cast<int>(read_anything::mojom::LetterSpacing::kDefaultValue);
-  float letter_spacing_value = 0.0;
-  int line_spacing =
-      static_cast<int>(read_anything::mojom::LineSpacing::kDefaultValue);
+TEST_F(ReadAnythingAppControllerTest, OnSettingsRestoredFromPrefs) {
+  auto line_spacing = read_anything::mojom::LineSpacing::kDefaultValue;
   float line_spacing_value = 1.5;
-  SetThemeForTesting(font_name, font_size, links_enabled, images_enabled,
-                     foreground, background, line_spacing, letter_spacing);
+  auto letter_spacing = read_anything::mojom::LetterSpacing::kDefaultValue;
+  float letter_spacing_value = 0.0;
+  std::string font_name = "Roboto";
+  double font_size = 18.0;
+  bool links_enabled = false;
+  bool images_enabled = true;
+  auto color = read_anything::mojom::Colors::kDefaultValue;
+  int color_value = 0;
+  double speech_rate = 1.5;
+  std::string voice_value = "Italian voice 3";
+  std::string language_value = "it-IT";
+  base::Value::Dict voices = base::Value::Dict();
+  voices.Set(language_value, voice_value);
+  base::Value::List languages_enabled_in_pref = base::Value::List();
+  languages_enabled_in_pref.Append(language_value);
+  auto highlight_granularity =
+      read_anything::mojom::HighlightGranularity::kDefaultValue;
+  int highlight_granularity_value = 0;
+
+  OnSettingsRestoredFromPrefs(
+      line_spacing, letter_spacing, font_name, font_size, links_enabled,
+      images_enabled, color, speech_rate, std::move(voices),
+      std::move(languages_enabled_in_pref), highlight_granularity);
+
+  EXPECT_EQ(line_spacing_value, LineSpacing());
+  EXPECT_EQ(letter_spacing_value, LetterSpacing());
   EXPECT_EQ(font_name, FontName());
   EXPECT_EQ(font_size, FontSize());
   EXPECT_EQ(links_enabled, LinksEnabled());
-  EXPECT_EQ(foreground, ForegroundColor());
-  EXPECT_EQ(background, BackgroundColor());
-  EXPECT_EQ(line_spacing_value, LineSpacing());
-  EXPECT_EQ(letter_spacing_value, LetterSpacing());
+  EXPECT_EQ(color_value, ColorTheme());
+  EXPECT_EQ(speech_rate, SpeechRate());
+  EXPECT_EQ(voice_value, GetStoredVoice());
+  EXPECT_EQ(1u, GetLanguagesEnabledInPref().size());
+  EXPECT_EQ(language_value, GetLanguagesEnabledInPref()[0]);
+  EXPECT_EQ(highlight_granularity_value, HighlightGranularity());
 }
 
 TEST_F(ReadAnythingAppControllerTest, RootIdIsSnapshotRootId) {
@@ -2145,19 +2162,28 @@
   ui::AXNodeID ax_node_id = 2;
   EXPECT_CALL(page_handler_, OnImageDataRequested(tree_id_, ax_node_id))
       .Times(1);
+
+  auto line_spacing = read_anything::mojom::LineSpacing::kDefaultValue;
+  auto letter_spacing = read_anything::mojom::LetterSpacing::kDefaultValue;
   std::string font_name = "Roboto";
-  float font_size = 18.0;
+  double font_size = 18.0;
   bool links_enabled = false;
   bool images_enabled = true;
-  SkColor foreground = SkColorSetRGB(0x33, 0x36, 0x39);
-  SkColor background = SkColorSetRGB(0xFD, 0xE2, 0x93);
-  int letter_spacing =
-      static_cast<int>(read_anything::mojom::LetterSpacing::kDefaultValue);
-  int line_spacing =
-      static_cast<int>(read_anything::mojom::LineSpacing::kDefaultValue);
+  auto color = read_anything::mojom::Colors::kDefaultValue;
+  double speech_rate = 1.5;
+  std::string voice_value = "Italian voice 3";
+  std::string language_value = "it-IT";
+  base::Value::Dict voices = base::Value::Dict();
+  voices.Set(language_value, voice_value);
+  base::Value::List languages_enabled_in_pref = base::Value::List();
+  languages_enabled_in_pref.Append(language_value);
+  auto highlight_granularity =
+      read_anything::mojom::HighlightGranularity::kDefaultValue;
 
-  SetThemeForTesting(font_name, font_size, links_enabled, images_enabled,
-                     foreground, background, line_spacing, letter_spacing);
+  OnSettingsRestoredFromPrefs(
+      line_spacing, letter_spacing, font_name, font_size, links_enabled,
+      images_enabled, color, speech_rate, std::move(voices),
+      std::move(languages_enabled_in_pref), highlight_granularity);
   RequestImageDataUrl(ax_node_id);
   page_handler_.FlushForTesting();
   Mock::VerifyAndClearExpectations(distiller_);
diff --git a/chrome/renderer/accessibility/read_anything_app_model.cc b/chrome/renderer/accessibility/read_anything_app_model.cc
index e0a5d5d..b6158be 100644
--- a/chrome/renderer/accessibility/read_anything_app_model.cc
+++ b/chrome/renderer/accessibility/read_anything_app_model.cc
@@ -72,18 +72,6 @@
 ReadAnythingAppModel::ReadAloudCurrentGranularity::
     ~ReadAloudCurrentGranularity() = default;
 
-void ReadAnythingAppModel::OnThemeChanged(
-    read_anything::mojom::ReadAnythingThemePtr new_theme) {
-  font_name_ = new_theme->font_name;
-  font_size_ = new_theme->font_size;
-  links_enabled_ = new_theme->links_enabled;
-  images_enabled_ = new_theme->images_enabled;
-  letter_spacing_ = GetLetterSpacingValue(new_theme->letter_spacing);
-  line_spacing_ = GetLineSpacingValue(new_theme->line_spacing);
-  background_color_ = new_theme->background_color;
-  foreground_color_ = new_theme->foreground_color;
-}
-
 void ReadAnythingAppModel::OnSettingsRestoredFromPrefs(
     read_anything::mojom::LineSpacing line_spacing,
     read_anything::mojom::LetterSpacing letter_spacing,
diff --git a/chrome/renderer/accessibility/read_anything_app_model.h b/chrome/renderer/accessibility/read_anything_app_model.h
index 24f7b7ae..94968f5 100644
--- a/chrome/renderer/accessibility/read_anything_app_model.h
+++ b/chrome/renderer/accessibility/read_anything_app_model.h
@@ -172,7 +172,6 @@
 
   std::vector<std::string> GetSupportedFonts() const;
 
-  // TODO(b/1266555): Ensure there is proper test coverage for all methods.
   // Theme
   const std::string& font_name() const { return font_name_; }
   void set_font_name(const std::string& font) { font_name_ = font; }
@@ -182,8 +181,6 @@
   float letter_spacing() const { return letter_spacing_; }
   float line_spacing() const { return line_spacing_; }
   int color_theme() const { return color_theme_; }
-  const SkColor& foreground_color() const { return foreground_color_; }
-  const SkColor& background_color() const { return background_color_; }
 
   // Selection.
   bool has_selection() const { return has_selection_; }
@@ -240,7 +237,6 @@
   ui::AXNode* GetAXNode(const ui::AXNodeID& ax_node_id) const;
   bool IsNodeIgnoredForReadAnything(const ui::AXNodeID& ax_node_id) const;
   bool NodeIsContentNode(const ui::AXNodeID& ax_node_id) const;
-  void OnThemeChanged(read_anything::mojom::ReadAnythingThemePtr new_theme);
   void OnSettingsRestoredFromPrefs(
       read_anything::mojom::LineSpacing line_spacing,
       read_anything::mojom::LetterSpacing letter_spacing,
@@ -526,8 +522,6 @@
   float letter_spacing_ =
       (int)read_anything::mojom::LetterSpacing::kDefaultValue;
   float line_spacing_ = (int)read_anything::mojom::LineSpacing::kDefaultValue;
-  SkColor background_color_ = (int)read_anything::mojom::Colors::kDefaultValue;
-  SkColor foreground_color_ = (int)read_anything::mojom::Colors::kDefaultValue;
   int color_theme_ = (int)read_anything::mojom::Colors::kDefaultValue;
 
   // Selection information.
diff --git a/chrome/renderer/accessibility/read_anything_app_model_browsertest.cc b/chrome/renderer/accessibility/read_anything_app_model_browsertest.cc
index 8af0340..cfb86023 100644
--- a/chrome/renderer/accessibility/read_anything_app_model_browsertest.cc
+++ b/chrome/renderer/accessibility/read_anything_app_model_browsertest.cc
@@ -85,29 +85,17 @@
     update->tree_data = tree_data;
   }
 
-  void SetThemeForTesting(const std::string& font_name,
-                          float font_size,
-                          bool links_enabled,
-                          bool images_enabled,
-                          SkColor foreground_color,
-                          SkColor background_color,
-                          int line_spacing,
-                          int letter_spacing) {
-    auto line_spacing_enum =
-        static_cast<read_anything::mojom::LineSpacing>(line_spacing);
-    auto letter_spacing_enum =
-        static_cast<read_anything::mojom::LetterSpacing>(letter_spacing);
-    model_->OnThemeChanged(read_anything::mojom::ReadAnythingTheme::New(
-        font_name, font_size, links_enabled, images_enabled, foreground_color,
-        background_color, line_spacing_enum, letter_spacing_enum));
-  }
-
-  void SetLineAndLetterSpacing(
+  void OnSettingsRestoredFromPrefs(
+      read_anything::mojom::LineSpacing line_spacing,
       read_anything::mojom::LetterSpacing letter_spacing,
-      read_anything::mojom::LineSpacing line_spacing) {
-    model_->OnThemeChanged(read_anything::mojom::ReadAnythingTheme::New(
-        "Arial", 15.0, false, false, SkColorSetRGB(0x33, 0x40, 0x36),
-        SkColorSetRGB(0xDF, 0xD2, 0x63), line_spacing, letter_spacing));
+      const std::string& font,
+      double font_size,
+      bool links_enabled,
+      bool images_enabled,
+      read_anything::mojom::Colors color) {
+    model_->OnSettingsRestoredFromPrefs(line_spacing, letter_spacing, font,
+                                        font_size, links_enabled,
+                                        images_enabled, color);
   }
 
   void AccessibilityEventReceived(const std::vector<ui::AXTreeUpdate>& updates,
@@ -154,14 +142,12 @@
 
   bool ImagesEnabled() { return model_->images_enabled(); }
 
-  SkColor ForegroundColor() { return model_->foreground_color(); }
-
-  SkColor BackgroundColor() { return model_->background_color(); }
-
   float LineSpacing() { return model_->line_spacing(); }
 
   float LetterSpacing() { return model_->letter_spacing(); }
 
+  int ColorTheme() { return model_->color_theme(); }
+
   bool DistillationInProgress() { return model_->distillation_in_progress(); }
 
   bool HasSelection() { return model_->has_selection(); }
@@ -331,29 +317,28 @@
   EXPECT_EQ(font_name, FontName());
 }
 
-TEST_F(ReadAnythingAppModelTest, Theme) {
+TEST_F(ReadAnythingAppModelTest, OnSettingsRestoredFromPrefs) {
+  auto line_spacing = read_anything::mojom::LineSpacing::kDefaultValue;
+  float line_spacing_value = 1.5;
+  auto letter_spacing = read_anything::mojom::LetterSpacing::kDefaultValue;
+  float letter_spacing_value = 0.0;
   std::string font_name = "Roboto";
-  float font_size = 18.0;
+  double font_size = 18.0;
   bool links_enabled = false;
   bool images_enabled = true;
-  SkColor foreground = SkColorSetRGB(0x33, 0x36, 0x39);
-  SkColor background = SkColorSetRGB(0xFD, 0xE2, 0x93);
-  int letter_spacing =
-      static_cast<int>(read_anything::mojom::LetterSpacing::kDefaultValue);
-  float letter_spacing_value = 0.0;
-  int line_spacing =
-      static_cast<int>(read_anything::mojom::LineSpacing::kDefaultValue);
-  float line_spacing_value = 1.5;
-  SetThemeForTesting(font_name, font_size, links_enabled, images_enabled,
-                     foreground, background, line_spacing, letter_spacing);
+  auto color = read_anything::mojom::Colors::kDefaultValue;
+  int color_value = 0;
+
+  OnSettingsRestoredFromPrefs(line_spacing, letter_spacing, font_name,
+                              font_size, links_enabled, images_enabled, color);
+
+  EXPECT_EQ(line_spacing_value, LineSpacing());
+  EXPECT_EQ(letter_spacing_value, LetterSpacing());
   EXPECT_EQ(font_name, FontName());
   EXPECT_EQ(font_size, FontSize());
   EXPECT_EQ(links_enabled, LinksEnabled());
   EXPECT_EQ(images_enabled, ImagesEnabled());
-  EXPECT_EQ(foreground, ForegroundColor());
-  EXPECT_EQ(background, BackgroundColor());
-  EXPECT_EQ(line_spacing_value, LineSpacing());
-  EXPECT_EQ(letter_spacing_value, LetterSpacing());
+  EXPECT_EQ(color_value, ColorTheme());
 }
 
 TEST_F(ReadAnythingAppModelTest, IsNodeIgnoredForReadAnything) {
@@ -1002,19 +987,6 @@
   EXPECT_FALSE(SelectionNodeIdsContains(4));
 }
 
-TEST_F(ReadAnythingAppModelTest, SetTheme_LineAndLetterSpacingCorrect) {
-  SetLineAndLetterSpacing(read_anything::mojom::LetterSpacing::kStandard,
-                          read_anything::mojom::LineSpacing::kLoose);
-  ASSERT_EQ(LineSpacing(), 1.5);
-  ASSERT_EQ(LetterSpacing(), 0);
-
-  // Ensure the line and letter spacing are updated.
-  SetLineAndLetterSpacing(read_anything::mojom::LetterSpacing::kWide,
-                          read_anything::mojom::LineSpacing::kVeryLoose);
-  ASSERT_EQ(LineSpacing(), 2.0);
-  ASSERT_EQ(LetterSpacing(), 0.05f);
-}
-
 TEST_F(ReadAnythingAppModelTest, Reset_ResetsState) {
   // Initial state.
   ui::AXTreeUpdate update;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 0681f5f5..fcefb3d 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -10378,9 +10378,7 @@
       "../browser/ui/views/relaunch_notification/relaunch_required_timer_internal_unittest.cc",
       "../browser/ui/views/send_tab_to_self/send_tab_to_self_device_picker_bubble_view_unittest.cc",
       "../browser/ui/views/send_tab_to_self/send_tab_to_self_toolbar_bubble_view_unittest.cc",
-      "../browser/ui/views/side_panel/read_anything/read_anything_controller_unittest.cc",
       "../browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc",
-      "../browser/ui/views/side_panel/read_anything/read_anything_model_unittest.cc",
       "../browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller_unittest.cc",
       "../browser/ui/views/side_panel/side_panel_coordinator_unittest.cc",
       "../browser/ui/views/site_data/page_specific_site_data_dialog_unittest.cc",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/sync/SyncTestUtil.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/sync/SyncTestUtil.java
index 80b3215..d114b8a 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/sync/SyncTestUtil.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/sync/SyncTestUtil.java
@@ -238,7 +238,7 @@
 
     /**
      * Extracts datatype-specific information from the given JSONObject. The returned JSONObject
-     * contains the same data as a specifics protocol buffer (e.g., TypedUrlSpecifics).
+     * contains the same data as a specifics protocol buffer (e.g., ReadingListSpecifics).
      */
     private static JSONObject extractSpecifics(JSONObject node) throws JSONException {
         JSONObject specifics = node.getJSONObject("SPECIFICS");
@@ -294,17 +294,15 @@
     /**
      * Returns the local Sync data present for a single datatype.
      *
-     * For each data entity, a Pair is returned. The first piece of data is the entity's server ID.
-     * This is useful for activities like deleting an entity on the server. The second piece of data
-     * is a JSONObject representing the datatype-specific information for the entity. This data is
-     * the same as the data stored in a specifics protocol buffer (e.g., TypedUrlSpecifics).
+     * <p>For each data entity, a Pair is returned. The first piece of data is the entity's server
+     * ID. This is useful for activities like deleting an entity on the server. The second piece of
+     * data is a JSONObject representing the datatype-specific information for the entity. This data
+     * is the same as the data stored in a specifics protocol buffer (e.g., ReadingListSpecifics).
      *
      * @param context the Context used to retreive the correct SyncService
      * @param typeString a String representing a specific datatype.
-     *
-     * TODO(pvalenzuela): Replace typeString with the native ModelType enum or something else
-     * that will avoid callers needing to specify the native string version.
-     *
+     *     <p>TODO(pvalenzuela): Replace typeString with the native ModelType enum or something else
+     *     that will avoid callers needing to specify the native string version.
      * @return a List of Pair<String, JSONObject> representing the local Sync data
      */
     public static List<Pair<String, JSONObject>> getLocalData(Context context, String typeString)
diff --git a/chrome/test/chromedriver/net/adb_client_socket_unittest.cc b/chrome/test/chromedriver/net/adb_client_socket_unittest.cc
index 91307d2..42b51e4 100644
--- a/chrome/test/chromedriver/net/adb_client_socket_unittest.cc
+++ b/chrome/test/chromedriver/net/adb_client_socket_unittest.cc
@@ -8,6 +8,7 @@
 
 #include "base/containers/span.h"
 #include "base/functional/bind.h"
+#include "base/memory/raw_span.h"
 #include "base/run_loop.h"
 #include "base/test/gtest_util.h"
 #include "base/test/mock_callback.h"
@@ -75,7 +76,7 @@
   bool GetSSLInfo(net::SSLInfo* ssl_info) override { return false; }
   bool WasEverUsed() const override { return false; }
 
-  base::span<std::string> return_values_array;
+  base::raw_span<std::string> return_values_array;
 };
 
 class AdbClientSocketTest : public testing::Test {
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py
index 0da999da..502b74e 100755
--- a/chrome/test/chromedriver/test/run_py_tests.py
+++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -152,14 +152,6 @@
     'ChromeDriverTest.testFindChildElementsStaleElement2',
     # Flaky: https://crbug.com/1486520
     'ChromeDriverTest.testClickStaleElement',
-        # Failing on macOS 14 due to https://crbug.com/40233722
-    'ChromeDriverSecureContextTest.testAddVirtualAuthenticator',
-    'ChromeDriverSecureContextTest.testAddVirtualAuthDefaultBackupSettings',
-    'ChromeDriverSecureContextTest.testAddVirtualAuthenticatorDefaultParams',
-    'ChromeDriverSecureContextTest.testGetCredentials',
-    'ChromeDriverSecureContextTest.testRemoveAllCredentials',
-    'ChromeDriverSecureContextTest.testRemoveCredential',
-    'ChromeDriverSecureContextTest.testSetUserVerified'
 ]
 
 _BROWSER_SPECIFIC_FILTER = {}
diff --git a/chrome/test/data/password/simple_change_password_form.html b/chrome/test/data/password/simple_change_password_form.html
index a70f4118..e9c8955f 100644
--- a/chrome/test/data/password/simple_change_password_form.html
+++ b/chrome/test/data/password/simple_change_password_form.html
@@ -10,7 +10,6 @@
   <input type="text" id="chg_username_field" name="chg_username_field">
   <input type="password" id="chg_password_field" name="chg_password_field">
   <input type="password" id="chg_new_password_1" name="chg_new_password_1">
-  <input type="password" id="chg_new_password_2" name="chg_new_password_2">
   <input type="submit" id="chg_submit_button" name="chg_submit_button">
 </form>
 </body>
diff --git a/chrome/test/data/test_visual.html b/chrome/test/data/test_visual.html
index 614071460..fbd07c1d 100644
--- a/chrome/test/data/test_visual.html
+++ b/chrome/test/data/test_visual.html
@@ -2,7 +2,7 @@
 <html>
 <body>
 
-<img src="handbag.png" alt="Smiley face" width="400" height="500">
+<img src="handbag.png" id="image" alt="Smiley face" width="400" height="500">
 
 </body>
 </html>
\ No newline at end of file
diff --git a/chrome/test/data/test_visual.html.mock-http-headers b/chrome/test/data/test_visual.html.mock-http-headers
new file mode 100644
index 0000000..263e89c4
--- /dev/null
+++ b/chrome/test/data/test_visual.html.mock-http-headers
@@ -0,0 +1,2 @@
+HTTP/1.1 200 OK
+Supports-Loading-Mode: fenced-frame
\ No newline at end of file
diff --git a/chrome/test/data/web_apps/empty_web_app.json b/chrome/test/data/web_apps/empty_web_app.json
index 34759c4..e7c87e27 100644
--- a/chrome/test/data/web_apps/empty_web_app.json
+++ b/chrome/test/data/web_apps/empty_web_app.json
@@ -23,7 +23,6 @@
       "MONOCHROME": [  ]
    },
    "file_handler_approval_state": "kRequiresPrompt",
-   "file_handler_os_integration_state": "kDisabled",
    "file_handlers": [  ],
    "first_install_time": "1601-01-01 00:00:00.000000 UTC",
    "generated_icon_fix": null,
diff --git a/chrome/test/data/web_apps/sample_web_app.json b/chrome/test/data/web_apps/sample_web_app.json
index 22f7f69b..85d0962 100644
--- a/chrome/test/data/web_apps/sample_web_app.json
+++ b/chrome/test/data/web_apps/sample_web_app.json
@@ -60,7 +60,6 @@
       "MONOCHROME": [ 256 ]
    },
    "file_handler_approval_state": "kRequiresPrompt",
-   "file_handler_os_integration_state": "kDisabled",
    "file_handlers": [ {
       "accept": [ {
          "file_extensions": [ ".32484220700a", ".32484220700b" ],
diff --git a/chrome/test/data/webui/chromeos/sanitize_ui/sanitize_ui_browsertest.cc b/chrome/test/data/webui/chromeos/sanitize_ui/sanitize_ui_browsertest.cc
index f1dd165..f666d7c 100644
--- a/chrome/test/data/webui/chromeos/sanitize_ui/sanitize_ui_browsertest.cc
+++ b/chrome/test/data/webui/chromeos/sanitize_ui/sanitize_ui_browsertest.cc
@@ -4,6 +4,7 @@
 
 #include <string>
 
+#include "ash/constants/ash_features.h"
 #include "ash/webui/sanitize_ui/url_constants.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/test/base/web_ui_mocha_browser_test.h"
@@ -21,6 +22,9 @@
  public:
   SanitizeUIBrowserTest() {
     set_test_loader_host(::ash::kChromeUISanitizeAppHost);
+    scoped_feature_list_.InitWithFeatures(
+        /*enabled_features=*/{ash::features::kSanitize},
+        /*disabled_featuers=*/{});
   }
 
  protected:
@@ -29,6 +33,9 @@
         base::StringPrintf("chromeos/sanitize_ui/%s", testFilePath.c_str());
     WebUIMochaBrowserTest::RunTest(testPath, "mocha.run()");
   }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 IN_PROC_BROWSER_TEST_F(SanitizeUIBrowserTest, SanitizeInitialize) {
diff --git a/chrome/test/data/webui/chromeos/sanitize_ui/sanitize_ui_test.ts b/chrome/test/data/webui/chromeos/sanitize_ui/sanitize_ui_test.ts
index 5fe7dfc..f542c96e 100644
--- a/chrome/test/data/webui/chromeos/sanitize_ui/sanitize_ui_test.ts
+++ b/chrome/test/data/webui/chromeos/sanitize_ui/sanitize_ui_test.ts
@@ -2,10 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+
+
+import {CrExpandButtonElement} from 'chrome://resources/ash/common/cr_elements/cr_expand_button/cr_expand_button.js';
 import {assert} from 'chrome://resources/js/assert.js';
+import {OpenWindowProxyImpl} from 'chrome://resources/js/open_window_proxy.js';
 import {SanitizeDoneElement} from 'chrome://sanitize/sanitize_done.js';
 import {assertEquals} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
+import {TestOpenWindowProxy} from 'chrome://webui-test/test_open_window_proxy.js';
+
 
 function initSanitizeDoneElement(): SanitizeDoneElement {
   const element = new SanitizeDoneElement();
@@ -14,12 +20,134 @@
   return element;
 }
 suite('SanitizeUITest', function() {
+  let openWindowProxy: TestOpenWindowProxy;
+
+  setup(function() {
+    openWindowProxy = new TestOpenWindowProxy();
+    OpenWindowProxyImpl.setInstance(openWindowProxy);
+  });
+
   test('SanitizeDonePopulation', () => {
     const doneElement = initSanitizeDoneElement();
-    const headerDiv = doneElement.shadowRoot!.querySelector('#header');
+    const titleDiv = doneElement.shadowRoot!.querySelector('#title');
     // Verify the header element exists
-    assert(headerDiv);
+    assert(titleDiv);
     // Check the header content
-    assertEquals('Sanitize Done', headerDiv!.textContent);
+    assertEquals('Your device is sanitized', titleDiv!.textContent);
+  });
+
+  test('SanitizeDoneAccordionsAndLinksTest', async () => {
+    const doneElement = initSanitizeDoneElement();
+    // Check accordions exist
+    const extensionsAccordion =
+        doneElement.shadowRoot!.querySelector<CrExpandButtonElement>(
+            '#expandExtensions');
+    assert(!!extensionsAccordion);
+    const chromeOSSettingsAccordion =
+        doneElement.shadowRoot!.querySelector<CrExpandButtonElement>(
+            '#expandChromeOsSettingsInfo');
+    assert(!!chromeOSSettingsAccordion);
+    const chromeSettingsAccordion =
+        doneElement.shadowRoot!.querySelector<CrExpandButtonElement>(
+            '#expandChromeSettingsInfo');
+    assert(!!chromeSettingsAccordion);
+
+    // Check buttons are hidden under accordions and clicking them opens the
+    // relevant link
+
+    // Extensions Section
+    const hiddenExtensionsButton =
+        doneElement.shadowRoot!.querySelector('#extensionsButton');
+    assert(!hiddenExtensionsButton);
+    extensionsAccordion.click();
+    flushTasks();
+    const extensionsButton =
+        doneElement.shadowRoot!.querySelector<HTMLElement>('#extensionsButton');
+    assert(!!extensionsButton);
+    extensionsButton.click();
+    const extensionsUrl = await openWindowProxy.whenCalled('openUrl');
+    assertEquals(extensionsUrl, 'chrome://extensions');
+    openWindowProxy.resetResolver('openUrl');
+
+
+    // ChromeOS Settings Section
+    const hiddenChromeOsInputButton =
+        doneElement.shadowRoot!.querySelector('#chromeOsInputButton');
+    const hiddenChromeOsNetworkButton =
+        doneElement.shadowRoot!.querySelector('#chromeOsNetworkButton');
+    assert(!hiddenChromeOsInputButton);
+    assert(!hiddenChromeOsNetworkButton);
+    chromeOSSettingsAccordion.click();
+    flushTasks();
+    const chromeOsInputButton =
+        doneElement.shadowRoot!.querySelector<HTMLElement>(
+            '#chromeOsInputButton');
+    const chromeOsNetworkButton =
+        doneElement.shadowRoot!.querySelector<HTMLElement>(
+            '#chromeOsNetworkButton');
+
+    assert(!!chromeOsInputButton);
+    chromeOsInputButton.click();
+    const chromeOsInputUrl = await openWindowProxy.whenCalled('openUrl');
+    assertEquals(chromeOsInputUrl, 'chrome://os-settings/osLanguages/input');
+    openWindowProxy.resetResolver('openUrl');
+
+
+    assert(!!chromeOsNetworkButton);
+    chromeOsNetworkButton.click();
+    const chromeOsNetworkUrl = await openWindowProxy.whenCalled('openUrl');
+    assertEquals(chromeOsNetworkUrl, 'chrome://os-settings/internet');
+    openWindowProxy.resetResolver('openUrl');
+
+    // ChromeOS Settings Section
+    const hiddenChromeSiteContentButton =
+        doneElement.shadowRoot!.querySelector('#chromeSiteContentButton');
+    const hiddenChromeStartupButton =
+        doneElement.shadowRoot!.querySelector('#chromeStartupButton');
+    const hiddenChromeHomepageButton =
+        doneElement.shadowRoot!.querySelector('#chromeHomepageButton');
+    const hiddenChromeLanguagesButton =
+        doneElement.shadowRoot!.querySelector('#chromeLanguagesButton');
+    assert(!hiddenChromeSiteContentButton);
+    assert(!hiddenChromeStartupButton);
+    assert(!hiddenChromeHomepageButton);
+    assert(!hiddenChromeLanguagesButton);
+    chromeSettingsAccordion.click();
+    flushTasks();
+    const chromeSiteContentButton =
+        doneElement.shadowRoot!.querySelector<HTMLElement>(
+            '#chromeSiteContentButton');
+    const chromeStartupButton =
+        doneElement.shadowRoot!.querySelector<HTMLElement>(
+            '#chromeStartupButton');
+    const chromeHomepageButton =
+        doneElement.shadowRoot!.querySelector<HTMLElement>(
+            '#chromeHomepageButton');
+    const chromeLanguagesButton =
+        doneElement.shadowRoot!.querySelector<HTMLElement>(
+            '#chromeLanguagesButton');
+
+    assert(!!chromeSiteContentButton);
+    chromeSiteContentButton.click();
+    const chromeSiteContentUrl = await openWindowProxy.whenCalled('openUrl');
+    assertEquals(chromeSiteContentUrl, 'chrome://settings/content');
+    openWindowProxy.resetResolver('openUrl');
+
+    assert(!!chromeStartupButton);
+    chromeStartupButton.click();
+    const chromeStartupUrl = await openWindowProxy.whenCalled('openUrl');
+    assertEquals(chromeStartupUrl, 'chrome://settings/onStartup');
+    openWindowProxy.resetResolver('openUrl');
+
+    assert(!!chromeHomepageButton);
+    chromeHomepageButton.click();
+    const chromeHomepageUrl = await openWindowProxy.whenCalled('openUrl');
+    assertEquals(chromeHomepageUrl, 'chrome://settings/appearance');
+    openWindowProxy.resetResolver('openUrl');
+
+    assert(!!chromeLanguagesButton);
+    chromeLanguagesButton.click();
+    const chromeLanguagesUrl = await openWindowProxy.whenCalled('openUrl');
+    assertEquals(chromeLanguagesUrl, 'chrome://settings/languages');
   });
 });
diff --git a/chrome/test/data/webui/chromeos/settings/device_page/customize_mouse_buttons_subpage_test.ts b/chrome/test/data/webui/chromeos/settings/device_page/customize_mouse_buttons_subpage_test.ts
index 49a8601..ab47603 100644
--- a/chrome/test/data/webui/chromeos/settings/device_page/customize_mouse_buttons_subpage_test.ts
+++ b/chrome/test/data/webui/chromeos/settings/device_page/customize_mouse_buttons_subpage_test.ts
@@ -75,10 +75,9 @@
     assertDeepEquals(buttonActionList, expectedActionList);
   });
 
-  test('hasLauncherButton fetched from provider', async () => {
-    const expectedHasLauncherButton =
-        (await provider.hasLauncherButton())?.hasLauncherButton;
-    assertEquals(page.get('hasLauncherButton_'), expectedHasLauncherButton);
+  test('getMetaKeyToDisplay fetched from provider', async () => {
+    const expectedMetaKey = (await provider.getMetaKeyToDisplay())?.metaKey;
+    assertEquals(page.get('metaKey_'), expectedMetaKey);
   });
 
   test('button name change triggers settings update', async () => {
diff --git a/chrome/test/data/webui/chromeos/settings/device_page/customize_pen_buttons_subpage_test.ts b/chrome/test/data/webui/chromeos/settings/device_page/customize_pen_buttons_subpage_test.ts
index 18c71a2..3ded8def 100644
--- a/chrome/test/data/webui/chromeos/settings/device_page/customize_pen_buttons_subpage_test.ts
+++ b/chrome/test/data/webui/chromeos/settings/device_page/customize_pen_buttons_subpage_test.ts
@@ -76,10 +76,9 @@
     assertDeepEquals(buttonActionList, expectedActionList);
   });
 
-  test('hasLauncherButton fetched from provider', async () => {
-    const expectedHasLauncherButton =
-        (await provider.hasLauncherButton())?.hasLauncherButton;
-    assertEquals(page.get('hasLauncherButton_'), expectedHasLauncherButton);
+  test('getMetaKeyToDisplay fetched from provider', async () => {
+    const expectedMetaKey = (await provider.getMetaKeyToDisplay())?.metaKey;
+    assertEquals(page.get('metaKey_'), expectedMetaKey);
   });
 
   test('button name change triggers settings update', async () => {
diff --git a/chrome/test/data/webui/chromeos/settings/device_page/customize_tablet_buttons_subpage_test.ts b/chrome/test/data/webui/chromeos/settings/device_page/customize_tablet_buttons_subpage_test.ts
index da24e224..17d368d9 100644
--- a/chrome/test/data/webui/chromeos/settings/device_page/customize_tablet_buttons_subpage_test.ts
+++ b/chrome/test/data/webui/chromeos/settings/device_page/customize_tablet_buttons_subpage_test.ts
@@ -72,10 +72,9 @@
     assertDeepEquals(buttonActionList, expectedActionList);
   });
 
-  test('hasLauncherButton fetched from provider', async () => {
-    const expectedHasLauncherButton =
-        (await provider.hasLauncherButton())?.hasLauncherButton;
-    assertEquals(page.get('hasLauncherButton_'), expectedHasLauncherButton);
+  test('getMetaKeyToDisplay fetched from provider', async () => {
+    const expectedMetaKey = (await provider.getMetaKeyToDisplay())?.metaKey;
+    assertEquals(page.get('metaKey_'), expectedMetaKey);
   });
 
   test('button name change triggers settings update', async () => {
diff --git a/chrome/test/data/webui/chromeos/settings/device_page/fake_input_device_settings_provider_test.ts b/chrome/test/data/webui/chromeos/settings/device_page/fake_input_device_settings_provider_test.ts
index fedea680..7adad62 100644
--- a/chrome/test/data/webui/chromeos/settings/device_page/fake_input_device_settings_provider_test.ts
+++ b/chrome/test/data/webui/chromeos/settings/device_page/fake_input_device_settings_provider_test.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {fakeGraphicsTabletButtonActions, fakeGraphicsTablets, FakeInputDeviceSettingsProvider, fakeKeyboards, fakeMice, fakeMouseButtonActions, fakePointingSticks, fakeStyluses, fakeTouchpads, Keyboard, ModifierKey, SixPackKeyInfo, SixPackShortcutModifier} from 'chrome://os-settings/os_settings.js';
+import {fakeGraphicsTabletButtonActions, fakeGraphicsTablets, FakeInputDeviceSettingsProvider, fakeKeyboards, fakeMice, fakeMouseButtonActions, fakePointingSticks, fakeStyluses, fakeTouchpads, Keyboard, MetaKey, ModifierKey, SixPackKeyInfo, SixPackShortcutModifier} from 'chrome://os-settings/os_settings.js';
 import {assertDeepEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
 
 suite('FakeInputDeviceSettings', () => {
@@ -164,14 +164,14 @@
         graphicsTabletActions.options, fakeGraphicsTabletButtonActions);
   });
 
-  test('hasLauncherButton', async () => {
-    provider.setFakeHasLauncherButton(true);
-    let hasLauncherButton = await provider.hasLauncherButton();
-    assertDeepEquals(hasLauncherButton, {hasLauncherButton: true});
+  test('getMetaKeyToDisplay', async () => {
+    provider.setFakeMetaKeyToDisplay(MetaKey.kLauncher);
+    let metaKey = await provider.getMetaKeyToDisplay();
+    assertDeepEquals(metaKey, {metaKey: MetaKey.kLauncher});
 
-    provider.setFakeHasLauncherButton(false);
-    hasLauncherButton = await provider.hasLauncherButton();
-    assertDeepEquals(hasLauncherButton, {hasLauncherButton: false});
+    provider.setFakeMetaKeyToDisplay(MetaKey.kLauncherRefresh);
+    metaKey = await provider.getMetaKeyToDisplay();
+    assertDeepEquals(metaKey, {metaKey: MetaKey.kLauncherRefresh});
   });
 
   test('isRgbKeyboardSupported', async () => {
diff --git a/chrome/test/data/webui/downloads/item_test.ts b/chrome/test/data/webui/downloads/item_test.ts
index 07689f4..8353103 100644
--- a/chrome/test/data/webui/downloads/item_test.ts
+++ b/chrome/test/data/webui/downloads/item_test.ts
@@ -101,9 +101,6 @@
       });
 
   test('referrer url on dangerous downloads isn\'t linkable', () => {
-    const item = document.createElement('downloads-item');
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-    document.body.appendChild(item);
     const referrerUrl = 'https://test.com';
     const displayReferrerUrl = 'https://displaytest.com';
     item.set('data', createDownload({
@@ -203,60 +200,8 @@
     assertTrue(item.getFileIcon().hidden);
   });
 
-  test('icon overridden by danger type', async () => {
-    loadTimeData.overrideValues({improvedDownloadWarningsUX: false});
-    const item = document.createElement('downloads-item');
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-    document.body.appendChild(item);
-    testIconLoader.setShouldIconsLoad(true);
-    item.set('data', createDownload({
-               filePath: 'unique1',
-               hideDate: false,
-               dangerType: DangerType.kSensitiveContentBlock,
-             }));
-    flush();
-
-    assertEquals('cr:error', item.shadowRoot!.querySelector('iron-icon')!.icon);
-    assertTrue(item.$['file-icon'].hidden);
-
-    item.set('data', createDownload({
-               filePath: 'unique1',
-               hideDate: false,
-               dangerType: DangerType.kBlockedTooLarge,
-             }));
-    flush();
-
-    assertEquals('cr:error', item.shadowRoot!.querySelector('iron-icon')!.icon);
-    assertTrue(item.$['file-icon'].hidden);
-
-    item.set('data', createDownload({
-               filePath: 'unique1',
-               hideDate: false,
-               dangerType: DangerType.kBlockedPasswordProtected,
-             }));
-    flush();
-
-    assertEquals('cr:error', item.shadowRoot!.querySelector('iron-icon')!.icon);
-    assertTrue(item.$['file-icon'].hidden);
-
-    item.set('data', createDownload({
-               filePath: 'unique1',
-               hideDate: false,
-               dangerType: DangerType.kDeepScannedFailed,
-             }));
-    flush();
-
-    assertEquals('cr:info', item.shadowRoot!.querySelector('iron-icon')!.icon);
-    assertTrue(item.$['file-icon'].hidden);
-  });
-
   test(
-      'icon overridden by display type for improvedDownloadWarningsUX',
-      async () => {
-        loadTimeData.overrideValues({improvedDownloadWarningsUX: true});
-        const item = document.createElement('downloads-item');
-        document.body.innerHTML = window.trustedTypes!.emptyHTML;
-        document.body.appendChild(item);
+      'icon overridden by display type', async () => {
         testIconLoader.setShouldIconsLoad(true);
         item.set('data', createDownload({
                    filePath: 'unique1',
@@ -364,13 +309,7 @@
       });
 
   test(
-      'description color set by display type for improvedDownloadWarningsUX',
-      async () => {
-        loadTimeData.overrideValues({improvedDownloadWarningsUX: true});
-        const item = document.createElement('downloads-item');
-        document.body.innerHTML = window.trustedTypes!.emptyHTML;
-        document.body.appendChild(item);
-
+      'description color set by display type', async () => {
         item.set('data', createDownload({
                    filePath: 'unique1',
                    hideDate: false,
@@ -455,11 +394,6 @@
       });
 
   test('description text overridden by tailored warning type', () => {
-    loadTimeData.overrideValues({improvedDownloadWarningsUX: true});
-    const item = document.createElement('downloads-item');
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-    document.body.appendChild(item);
-
     function assertDescriptionText(expected: string) {
       assertEquals(
           expected,
@@ -514,12 +448,7 @@
   });
 
   test(
-      'icon aria-hidden determined by display type for improvedDownloadWarningsUX',
-      () => {
-        loadTimeData.overrideValues({improvedDownloadWarningsUX: true});
-        const item = document.createElement('downloads-item');
-        document.body.innerHTML = window.trustedTypes!.emptyHTML;
-        document.body.appendChild(item);
+      'icon aria-hidden determined by display type', () => {
         testIconLoader.setShouldIconsLoad(true);
 
         const iconWrapper = item.shadowRoot!.querySelector('.icon-wrapper');
@@ -552,10 +481,6 @@
       });
 
   test('save dangerous click fires event for dangerous', () => {
-    loadTimeData.overrideValues({improvedDownloadWarningsUX: true});
-    const item = document.createElement('downloads-item');
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-    document.body.appendChild(item);
     item.set('data', createDownload({
                filePath: 'unique1',
                hideDate: false,
@@ -578,10 +503,6 @@
   });
 
   test('save dangerous click does not fire event for suspicious', async () => {
-    loadTimeData.overrideValues({improvedDownloadWarningsUX: true});
-    const item = document.createElement('downloads-item');
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-    document.body.appendChild(item);
     item.set('data', createDownload({
                id: 'itemId',
                filePath: 'unique1',
@@ -615,10 +536,6 @@
   });
 
   test('deep scan dropdown buttons shown on correct state', () => {
-    loadTimeData.overrideValues({improvedDownloadWarningsUX: true});
-    const item = document.createElement('downloads-item');
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-    document.body.appendChild(item);
     item.set('data', createDownload({
                filePath: 'unique1',
                hideDate: false,
@@ -636,10 +553,6 @@
   });
 
   test('local decryption scan icon and text', () => {
-    loadTimeData.overrideValues({'improvedDownloadWarningsUX': true});
-    const item = document.createElement('downloads-item');
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-    document.body.appendChild(item);
     item.set('data', createDownload({
                filePath: 'unique1',
                hideDate: false,
@@ -658,10 +571,6 @@
   });
 
   test('open anyway dropdown button shown on failed deep scan', () => {
-    loadTimeData.overrideValues({improvedDownloadWarningsUX: true});
-    const item = document.createElement('downloads-item');
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-    document.body.appendChild(item);
     item.set('data', createDownload({
                filePath: 'unique1',
                hideDate: false,
@@ -678,14 +587,8 @@
   });
 
   test('undo is shown in toast', () => {
-    loadTimeData.overrideValues({improvedDownloadWarningsUX: true});
-    const item = document.createElement('downloads-item');
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-    document.body.appendChild(item);
     item.set('data', createDownload({hideDate: false}));
     flush();
-    toastManager = document.createElement('cr-toast-manager');
-    document.body.appendChild(toastManager);
     toastManager.show('', /* hideSlotted= */ true);
     assertTrue(toastManager.slottedHidden);
     // There's no menu button when the item is normal (not dangerous) and
@@ -702,18 +605,12 @@
   });
 
   test('undo is not shown in toast when item is dangerous', () => {
-    loadTimeData.overrideValues({improvedDownloadWarningsUX: true});
-    const item = document.createElement('downloads-item');
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-    document.body.appendChild(item);
     item.set('data', createDownload({
                hideDate: false,
                isDangerous: true,
                state: State.kDangerous,
              }));
     flush();
-    toastManager = document.createElement('cr-toast-manager');
-    document.body.appendChild(toastManager);
     toastManager.show('', /* hideSlotted= */ false);
     assertFalse(toastManager.slottedHidden);
     const moreActionsButton = item.getMoreActionsButton();
@@ -729,18 +626,12 @@
   });
 
   test('undo is not shown in toast when item is insecure', () => {
-    loadTimeData.overrideValues({improvedDownloadWarningsUX: true});
-    const item = document.createElement('downloads-item');
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-    document.body.appendChild(item);
     item.set('data', createDownload({
                hideDate: false,
                isInsecure: true,
                state: State.kInsecure,
              }));
     flush();
-    toastManager = document.createElement('cr-toast-manager');
-    document.body.appendChild(toastManager);
     toastManager.show('', /* hideSlotted= */ false);
     assertFalse(toastManager.slottedHidden);
     const moreActionsButton = item.getMoreActionsButton();
@@ -756,12 +647,6 @@
   });
 
   test('quick remove button discards dangerous item', async function() {
-    // TODO(chlily): cleanup/refactor test setup to account for the launch of
-    // improved download warnings.
-    loadTimeData.overrideValues({improvedDownloadWarningsUX: true});
-    const item = document.createElement('downloads-item');
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-    document.body.appendChild(item);
     item.set('data', createDownload({
                id: 'itemId',
                filePath: 'unique1',
@@ -770,8 +655,6 @@
                state: State.kDangerous,
              }));
     flush();
-    toastManager = document.createElement('cr-toast-manager');
-    document.body.appendChild(toastManager);
     const quickRemoveButton =
         item.shadowRoot!.querySelector<HTMLElement>('#quick-remove');
     assertTrue(!!quickRemoveButton);
@@ -783,18 +666,12 @@
   });
 
   test('quick remove button removes normal item', async function() {
-    loadTimeData.overrideValues({improvedDownloadWarningsUX: true});
-    const item = document.createElement('downloads-item');
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-    document.body.appendChild(item);
     item.set('data', createDownload({
                id: 'itemId',
                filePath: 'unique1',
                hideDate: false,
              }));
     flush();
-    toastManager = document.createElement('cr-toast-manager');
-    document.body.appendChild(toastManager);
     const quickRemoveButton =
         item.shadowRoot!.querySelector<HTMLElement>('#quick-remove');
     assertTrue(!!quickRemoveButton);
diff --git a/chrome/test/data/webui/settings/BUILD.gn b/chrome/test/data/webui/settings/BUILD.gn
index 64aaf93..f933d501a 100644
--- a/chrome/test/data/webui/settings/BUILD.gn
+++ b/chrome/test/data/webui/settings/BUILD.gn
@@ -57,6 +57,7 @@
     "people_page_test.ts",
     "performance_page_test.ts",
     "personalization_options_test.ts",
+    "privacy_guide_completion_fragment_test.ts",
     "privacy_guide_fragments_test.ts",
     "privacy_guide_integration_test.ts",
     "privacy_guide_page_test.ts",
diff --git a/chrome/test/data/webui/settings/privacy_guide_completion_fragment_test.ts b/chrome/test/data/webui/settings/privacy_guide_completion_fragment_test.ts
new file mode 100644
index 0000000..c3a8455
--- /dev/null
+++ b/chrome/test/data/webui/settings/privacy_guide_completion_fragment_test.ts
@@ -0,0 +1,275 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {webUIListenerCallback} from 'chrome://resources/js/cr.js';
+import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import type {PrivacyGuideCompletionFragmentElement} from 'chrome://settings/lazy_load.js';
+import {loadTimeData, MetricsBrowserProxyImpl, OpenWindowProxyImpl, PrivacyGuideInteractions, resetRouterForTesting, Router, routes} from 'chrome://settings/settings.js';
+import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
+import {TestOpenWindowProxy} from 'chrome://webui-test/test_open_window_proxy.js';
+import {eventToPromise, isChildVisible} from 'chrome://webui-test/test_util.js';
+
+import {TestMetricsBrowserProxy} from './test_metrics_browser_proxy.js';
+
+/** Fire a sign in status change event and flush the UI. */
+function setSignInState(signedIn: boolean) {
+  const event = {
+    signedIn: signedIn,
+  };
+  webUIListenerCallback('update-sync-state', event);
+  flush();
+}
+
+suite('CompletionFragment', function() {
+  let fragment: PrivacyGuideCompletionFragmentElement;
+  let testMetricsBrowserProxy: TestMetricsBrowserProxy;
+  let openWindowProxy: TestOpenWindowProxy;
+
+  suiteSetup(function() {
+    loadTimeData.overrideValues({
+      isPrivacySandboxRestricted: false,
+      isPrivacySandboxRestrictedNoticeEnabled: false,
+    });
+    resetRouterForTesting();
+  });
+
+  setup(function() {
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+
+    assertTrue(loadTimeData.getBoolean('showPrivacyGuide'));
+    testMetricsBrowserProxy = new TestMetricsBrowserProxy();
+    MetricsBrowserProxyImpl.setInstance(testMetricsBrowserProxy);
+    openWindowProxy = new TestOpenWindowProxy();
+    OpenWindowProxyImpl.setInstance(openWindowProxy);
+
+    fragment = document.createElement('privacy-guide-completion-fragment');
+    document.body.appendChild(fragment);
+
+    return flushTasks();
+  });
+
+  teardown(function() {
+    fragment.remove();
+    // The browser instance is shared among the tests, hence the route needs to
+    // be reset between tests.
+    Router.getInstance().navigateTo(routes.BASIC);
+  });
+
+  test('backNavigation', async function() {
+    const nextEventPromise = eventToPromise('back-button-click', fragment);
+
+    fragment.$.backButton.click();
+
+    // Ensure the event is sent.
+    return nextEventPromise;
+  });
+
+  test('backToSettingsNavigation', async function() {
+    const closeEventPromise = eventToPromise('close', fragment);
+
+    fragment.shadowRoot!.querySelector<HTMLElement>('#leaveButton')!.click();
+
+    const result = await testMetricsBrowserProxy.whenCalled(
+        'recordPrivacyGuideNextNavigationHistogram');
+    assertEquals(PrivacyGuideInteractions.COMPLETION_NEXT_BUTTON, result);
+
+    const actionResult =
+        await testMetricsBrowserProxy.whenCalled('recordAction');
+    assertEquals(actionResult, 'Settings.PrivacyGuide.NextClickCompletion');
+
+    // Ensure the |close| event has been sent.
+    return closeEventPromise;
+  });
+
+  test('SWAALinkClick', async function() {
+    setSignInState(true);
+
+    assertTrue(isChildVisible(fragment, '#waaRow'));
+    fragment.shadowRoot!.querySelector<HTMLElement>('#waaRow')!.click();
+    flush();
+
+    assertEquals(
+        PrivacyGuideInteractions.SWAA_COMPLETION_LINK,
+        await testMetricsBrowserProxy.whenCalled(
+            'recordPrivacyGuideEntryExitHistogram'));
+    assertEquals(
+        'Settings.PrivacyGuide.CompletionSWAAClick',
+        await testMetricsBrowserProxy.whenCalled('recordAction'));
+    assertEquals(
+        loadTimeData.getString('activityControlsUrlInPrivacyGuide'),
+        await openWindowProxy.whenCalled('openUrl'));
+  });
+
+  test('privacySandboxLinkClick', async function() {
+    fragment.shadowRoot!.querySelector<HTMLElement>(
+                            '#privacySandboxRow')!.click();
+    flush();
+
+    assertEquals(
+        PrivacyGuideInteractions.PRIVACY_SANDBOX_COMPLETION_LINK,
+        await testMetricsBrowserProxy.whenCalled(
+            'recordPrivacyGuideEntryExitHistogram'));
+    assertEquals(
+        'Settings.PrivacyGuide.CompletionPSClick',
+        await testMetricsBrowserProxy.whenCalled('recordAction'));
+  });
+
+  test('updateFragmentFromSignIn', function() {
+    setSignInState(true);
+    assertTrue(isChildVisible(fragment, '#privacySandboxRow'));
+    assertTrue(isChildVisible(fragment, '#waaRow'));
+
+    // Sign the user out and expect the waa row to no longer be visible.
+    setSignInState(false);
+    assertTrue(isChildVisible(fragment, '#privacySandboxRow'));
+    assertFalse(isChildVisible(fragment, '#waaRow'));
+  });
+
+  test('TrackingProtectionLinkClick', async function() {
+    assertTrue(isChildVisible(fragment, '#trackingProtectionRow'));
+    fragment.shadowRoot!.querySelector<HTMLElement>(
+                            '#trackingProtectionRow')!.click();
+    flush();
+
+    const result = await testMetricsBrowserProxy.whenCalled(
+        'recordPrivacyGuideEntryExitHistogram');
+    assertEquals(
+        PrivacyGuideInteractions.TRACKING_PROTECTION_COMPLETION_LINK, result);
+    assertEquals(
+        'Settings.PrivacyGuide.CompletionTrackingProtectionClick',
+        await testMetricsBrowserProxy.whenCalled('recordAction'));
+  });
+});
+
+suite('CompletionFragmentPrivacySandboxRestricted', function() {
+  let fragment: PrivacyGuideCompletionFragmentElement;
+
+  suiteSetup(function() {
+    loadTimeData.overrideValues({
+      isPrivacySandboxRestricted: true,
+      isPrivacySandboxRestrictedNoticeEnabled: false,
+    });
+    resetRouterForTesting();
+  });
+
+  setup(function() {
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+
+    assertTrue(loadTimeData.getBoolean('showPrivacyGuide'));
+    fragment = document.createElement('privacy-guide-completion-fragment');
+    document.body.appendChild(fragment);
+
+    return flushTasks();
+  });
+
+  teardown(function() {
+    fragment.remove();
+    // The browser instance is shared among the tests, hence the route needs to
+    // be reset between tests.
+    Router.getInstance().navigateTo(routes.BASIC);
+  });
+
+  test('updateFragmentFromSignIn', function() {
+    setSignInState(true);
+    assertFalse(isChildVisible(fragment, '#privacySandboxRow'));
+    assertTrue(isChildVisible(fragment, '#waaRow'));
+    const subheader =
+        fragment.shadowRoot!.querySelector<HTMLElement>('.cr-secondary-text')!;
+    assertEquals(
+        fragment.i18n('privacyGuideCompletionCardSubHeader'),
+        subheader.innerText);
+
+    setSignInState(false);
+    assertFalse(isChildVisible(fragment, '#privacySandboxRow'));
+    assertTrue(isChildVisible(fragment, '#trackingProtectionRow'));
+    assertFalse(isChildVisible(fragment, '#waaRow'));
+    assertEquals(
+        fragment.i18n('privacyGuideCompletionCardSubHeader'),
+        subheader.innerText);
+  });
+});
+
+suite(
+    'CompletionFragmentPrivacySandboxRestrictedWithNoticeEnabled', function() {
+      let fragment: PrivacyGuideCompletionFragmentElement;
+
+      suiteSetup(function() {
+        loadTimeData.overrideValues({
+          isPrivacySandboxRestricted: true,
+          isPrivacySandboxRestrictedNoticeEnabled: true,
+        });
+        resetRouterForTesting();
+      });
+
+      setup(function() {
+        document.body.innerHTML = window.trustedTypes!.emptyHTML;
+
+        assertTrue(loadTimeData.getBoolean('showPrivacyGuide'));
+        fragment = document.createElement('privacy-guide-completion-fragment');
+        document.body.appendChild(fragment);
+
+        return flushTasks();
+      });
+
+      teardown(function() {
+        fragment.remove();
+        // The browser instance is shared among the tests, hence the route needs
+        // to be reset between tests.
+        Router.getInstance().navigateTo(routes.BASIC);
+      });
+
+      test('privacySandboxRowVisibility', function() {
+        assertTrue(isChildVisible(fragment, '#privacySandboxRow'));
+      });
+    });
+
+// TODO(https://b/333527273): Remove after TP is launched.
+suite('CompletionFragmentWithoutTrackingProtection', function() {
+  let fragment: PrivacyGuideCompletionFragmentElement;
+
+  suiteSetup(function() {
+    loadTimeData.overrideValues({
+      isPrivacySandboxRestricted: true,
+      isPrivacySandboxRestrictedNoticeEnabled: false,
+      enableTrackingProtectionRolloutUx: false,
+    });
+    resetRouterForTesting();
+  });
+
+  setup(function() {
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+
+    assertTrue(loadTimeData.getBoolean('showPrivacyGuide'));
+    fragment = document.createElement('privacy-guide-completion-fragment');
+    document.body.appendChild(fragment);
+
+    return flushTasks();
+  });
+
+  teardown(function() {
+    fragment.remove();
+    // The browser instance is shared among the tests, hence the route needs
+    // to be reset between tests.
+    Router.getInstance().navigateTo(routes.BASIC);
+  });
+
+  test('trackingProtectionLinkHidden', function() {
+    // The link to Tracking Protection should be hidden outside of the
+    // experiment.
+    assertFalse(isChildVisible(fragment, '#trackingProtectionRow'));
+  });
+
+  test('noLinksShown', function() {
+    setSignInState(false);
+    assertFalse(isChildVisible(fragment, '#privacySandboxRow'));
+    assertFalse(isChildVisible(fragment, '#trackingProtectionRow'));
+    assertFalse(isChildVisible(fragment, '#waaRow'));
+    const subheader =
+        fragment.shadowRoot!.querySelector<HTMLElement>('.cr-secondary-text')!;
+    assertEquals(
+        fragment.i18n('privacyGuideCompletionCardSubHeaderNoLinks'),
+        subheader.innerText);
+  });
+});
diff --git a/chrome/test/data/webui/settings/privacy_guide_fragments_test.ts b/chrome/test/data/webui/settings/privacy_guide_fragments_test.ts
index c8afbdae..01b6bbe 100644
--- a/chrome/test/data/webui/settings/privacy_guide_fragments_test.ts
+++ b/chrome/test/data/webui/settings/privacy_guide_fragments_test.ts
@@ -6,12 +6,11 @@
 import {webUIListenerCallback} from 'chrome://resources/js/cr.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import type {PrivacyGuideCompletionFragmentElement, PrivacyGuideCookiesFragmentElement, PrivacyGuideDescriptionItemElement, PrivacyGuideHistorySyncFragmentElement, PrivacyGuideMsbbFragmentElement, PrivacyGuideSafeBrowsingFragmentElement, PrivacyGuideWelcomeFragmentElement, SettingsCollapseRadioButtonElement, SettingsRadioGroupElement} from 'chrome://settings/lazy_load.js';
+import type {PrivacyGuideCookiesFragmentElement, PrivacyGuideDescriptionItemElement, PrivacyGuideHistorySyncFragmentElement, PrivacyGuideMsbbFragmentElement, PrivacyGuideSafeBrowsingFragmentElement, PrivacyGuideWelcomeFragmentElement, SettingsCollapseRadioButtonElement, SettingsRadioGroupElement} from 'chrome://settings/lazy_load.js';
 import {CookiePrimarySetting, SafeBrowsingSetting} from 'chrome://settings/lazy_load.js';
 import type {SettingsPrefsElement, SyncPrefs} from 'chrome://settings/settings.js';
-import {CrSettingsPrefs, MetricsBrowserProxyImpl, OpenWindowProxyImpl, PrivacyGuideInteractions, PrivacyGuideSettingsStates, resetRouterForTesting, Router, routes, SyncBrowserProxyImpl, syncPrefsIndividualDataTypes} from 'chrome://settings/settings.js';
+import {CrSettingsPrefs, MetricsBrowserProxyImpl, PrivacyGuideSettingsStates, resetRouterForTesting, Router, routes, SyncBrowserProxyImpl, syncPrefsIndividualDataTypes} from 'chrome://settings/settings.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
-import {TestOpenWindowProxy} from 'chrome://webui-test/test_open_window_proxy.js';
 import {eventToPromise, isChildVisible} from 'chrome://webui-test/test_util.js';
 import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
 
@@ -20,15 +19,6 @@
 
 // clang-format on
 
-/** Fire a sign in status change event and flush the UI. */
-function setSignInState(signedIn: boolean) {
-  const event = {
-    signedIn: signedIn,
-  };
-  webUIListenerCallback('update-sync-state', event);
-  flush();
-}
-
 suite('WelcomeFragment', function() {
   let fragment: PrivacyGuideWelcomeFragmentElement;
 
@@ -811,255 +801,3 @@
         CookiePrimarySetting.BLOCK_THIRD_PARTY_INCOGNITO);
   });
 });
-
-suite('CompletionFragment', function() {
-  let fragment: PrivacyGuideCompletionFragmentElement;
-  let testMetricsBrowserProxy: TestMetricsBrowserProxy;
-  let openWindowProxy: TestOpenWindowProxy;
-
-  suiteSetup(function() {
-    loadTimeData.overrideValues({
-      isPrivacySandboxRestricted: false,
-      isPrivacySandboxRestrictedNoticeEnabled: false,
-    });
-    resetRouterForTesting();
-  });
-
-  setup(function() {
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-
-    assertTrue(loadTimeData.getBoolean('showPrivacyGuide'));
-    testMetricsBrowserProxy = new TestMetricsBrowserProxy();
-    MetricsBrowserProxyImpl.setInstance(testMetricsBrowserProxy);
-    openWindowProxy = new TestOpenWindowProxy();
-    OpenWindowProxyImpl.setInstance(openWindowProxy);
-
-    fragment = document.createElement('privacy-guide-completion-fragment');
-    document.body.appendChild(fragment);
-
-    return flushTasks();
-  });
-
-  teardown(function() {
-    fragment.remove();
-    // The browser instance is shared among the tests, hence the route needs to
-    // be reset between tests.
-    Router.getInstance().navigateTo(routes.BASIC);
-  });
-
-  test('backNavigation', async function() {
-    const nextEventPromise = eventToPromise('back-button-click', fragment);
-
-    fragment.$.backButton.click();
-
-    // Ensure the event is sent.
-    return nextEventPromise;
-  });
-
-  test('backToSettingsNavigation', async function() {
-    const closeEventPromise = eventToPromise('close', fragment);
-
-    fragment.shadowRoot!.querySelector<HTMLElement>('#leaveButton')!.click();
-
-    const result = await testMetricsBrowserProxy.whenCalled(
-        'recordPrivacyGuideNextNavigationHistogram');
-    assertEquals(PrivacyGuideInteractions.COMPLETION_NEXT_BUTTON, result);
-
-    const actionResult =
-        await testMetricsBrowserProxy.whenCalled('recordAction');
-    assertEquals(actionResult, 'Settings.PrivacyGuide.NextClickCompletion');
-
-    // Ensure the |close| event has been sent.
-    return closeEventPromise;
-  });
-
-  test('SWAALinkClick', async function() {
-    setSignInState(true);
-
-    assertTrue(isChildVisible(fragment, '#waaRow'));
-    fragment.shadowRoot!.querySelector<HTMLElement>('#waaRow')!.click();
-    flush();
-
-    assertEquals(
-        PrivacyGuideInteractions.SWAA_COMPLETION_LINK,
-        await testMetricsBrowserProxy.whenCalled(
-            'recordPrivacyGuideEntryExitHistogram'));
-    assertEquals(
-        'Settings.PrivacyGuide.CompletionSWAAClick',
-        await testMetricsBrowserProxy.whenCalled('recordAction'));
-    assertEquals(
-        loadTimeData.getString('activityControlsUrlInPrivacyGuide'),
-        await openWindowProxy.whenCalled('openUrl'));
-  });
-
-  test('privacySandboxLinkClick', async function() {
-    fragment.shadowRoot!.querySelector<HTMLElement>(
-                            '#privacySandboxRow')!.click();
-    flush();
-
-    assertEquals(
-        PrivacyGuideInteractions.PRIVACY_SANDBOX_COMPLETION_LINK,
-        await testMetricsBrowserProxy.whenCalled(
-            'recordPrivacyGuideEntryExitHistogram'));
-    assertEquals(
-        'Settings.PrivacyGuide.CompletionPSClick',
-        await testMetricsBrowserProxy.whenCalled('recordAction'));
-  });
-
-  test('updateFragmentFromSignIn', function() {
-    setSignInState(true);
-    assertTrue(isChildVisible(fragment, '#privacySandboxRow'));
-    assertTrue(isChildVisible(fragment, '#waaRow'));
-
-    // Sign the user out and expect the waa row to no longer be visible.
-    setSignInState(false);
-    assertTrue(isChildVisible(fragment, '#privacySandboxRow'));
-    assertFalse(isChildVisible(fragment, '#waaRow'));
-  });
-
-  test('TrackingProtectionLinkClick', async function() {
-    assertTrue(isChildVisible(fragment, '#trackingProtectionRow'));
-    fragment.shadowRoot!.querySelector<HTMLElement>(
-                            '#trackingProtectionRow')!.click();
-    flush();
-
-    const result = await testMetricsBrowserProxy.whenCalled(
-        'recordPrivacyGuideEntryExitHistogram');
-    assertEquals(
-        PrivacyGuideInteractions.TRACKING_PROTECTION_COMPLETION_LINK, result);
-    assertEquals(
-        'Settings.PrivacyGuide.CompletionTrackingProtectionClick',
-        await testMetricsBrowserProxy.whenCalled('recordAction'));
-  });
-});
-
-suite('CompletionFragmentPrivacySandboxRestricted', function() {
-  let fragment: PrivacyGuideCompletionFragmentElement;
-
-  suiteSetup(function() {
-    loadTimeData.overrideValues({
-      isPrivacySandboxRestricted: true,
-      isPrivacySandboxRestrictedNoticeEnabled: false,
-    });
-    resetRouterForTesting();
-  });
-
-  setup(function() {
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-
-    assertTrue(loadTimeData.getBoolean('showPrivacyGuide'));
-    fragment = document.createElement('privacy-guide-completion-fragment');
-    document.body.appendChild(fragment);
-
-    return flushTasks();
-  });
-
-  teardown(function() {
-    fragment.remove();
-    // The browser instance is shared among the tests, hence the route needs to
-    // be reset between tests.
-    Router.getInstance().navigateTo(routes.BASIC);
-  });
-
-  test('updateFragmentFromSignIn', function() {
-    setSignInState(true);
-    assertFalse(isChildVisible(fragment, '#privacySandboxRow'));
-    assertTrue(isChildVisible(fragment, '#waaRow'));
-    const subheader =
-        fragment.shadowRoot!.querySelector<HTMLElement>('.cr-secondary-text')!;
-    assertEquals(
-        fragment.i18n('privacyGuideCompletionCardSubHeader'),
-        subheader.innerText);
-
-    setSignInState(false);
-    assertFalse(isChildVisible(fragment, '#privacySandboxRow'));
-    assertTrue(isChildVisible(fragment, '#trackingProtectionRow'));
-    assertFalse(isChildVisible(fragment, '#waaRow'));
-    assertEquals(
-        fragment.i18n('privacyGuideCompletionCardSubHeader'),
-        subheader.innerText);
-  });
-});
-
-suite(
-    'CompletionFragmentPrivacySandboxRestrictedWithNoticeEnabled', function() {
-      let fragment: PrivacyGuideCompletionFragmentElement;
-
-      suiteSetup(function() {
-        loadTimeData.overrideValues({
-          isPrivacySandboxRestricted: true,
-          isPrivacySandboxRestrictedNoticeEnabled: true,
-        });
-        resetRouterForTesting();
-      });
-
-      setup(function() {
-        document.body.innerHTML = window.trustedTypes!.emptyHTML;
-
-        assertTrue(loadTimeData.getBoolean('showPrivacyGuide'));
-        fragment = document.createElement('privacy-guide-completion-fragment');
-        document.body.appendChild(fragment);
-
-        return flushTasks();
-      });
-
-      teardown(function() {
-        fragment.remove();
-        // The browser instance is shared among the tests, hence the route needs
-        // to be reset between tests.
-        Router.getInstance().navigateTo(routes.BASIC);
-      });
-
-      test('privacySandboxRowVisibility', function() {
-        assertTrue(isChildVisible(fragment, '#privacySandboxRow'));
-      });
-    });
-
-// TODO(https://b/333527273): Remove after TP is launched.
-suite('CompletionFragmentWithoutTrackingProtection', function() {
-  let fragment: PrivacyGuideCompletionFragmentElement;
-
-  suiteSetup(function() {
-    loadTimeData.overrideValues({
-      isPrivacySandboxRestricted: true,
-      isPrivacySandboxRestrictedNoticeEnabled: false,
-      enableTrackingProtectionRolloutUx: false,
-    });
-    resetRouterForTesting();
-  });
-
-  setup(function() {
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-
-    assertTrue(loadTimeData.getBoolean('showPrivacyGuide'));
-    fragment = document.createElement('privacy-guide-completion-fragment');
-    document.body.appendChild(fragment);
-
-    return flushTasks();
-  });
-
-  teardown(function() {
-    fragment.remove();
-    // The browser instance is shared among the tests, hence the route needs
-    // to be reset between tests.
-    Router.getInstance().navigateTo(routes.BASIC);
-  });
-
-  test('trackingProtectionLinkHidden', function() {
-    // The link to Tracking Protection should be hidden outside of the
-    // experiment.
-    assertFalse(isChildVisible(fragment, '#trackingProtectionRow'));
-  });
-
-  test('noLinksShown', function() {
-    setSignInState(false);
-    assertFalse(isChildVisible(fragment, '#privacySandboxRow'));
-    assertFalse(isChildVisible(fragment, '#trackingProtectionRow'));
-    assertFalse(isChildVisible(fragment, '#waaRow'));
-    const subheader =
-        fragment.shadowRoot!.querySelector<HTMLElement>('.cr-secondary-text')!;
-    assertEquals(
-        fragment.i18n('privacyGuideCompletionCardSubHeaderNoLinks'),
-        subheader.innerText);
-  });
-});
diff --git a/chrome/test/data/webui/settings/settings_browsertest.cc b/chrome/test/data/webui/settings/settings_browsertest.cc
index 870c3f0..3523853 100644
--- a/chrome/test/data/webui/settings/settings_browsertest.cc
+++ b/chrome/test/data/webui/settings/settings_browsertest.cc
@@ -851,22 +851,30 @@
 }
 
 IN_PROC_BROWSER_TEST_F(SettingsPrivacyGuideTest, CompletionFragment) {
-  RunTest("settings/privacy_guide_fragments_test.js",
+  RunTest("settings/privacy_guide_completion_fragment_test.js",
           "runMochaSuite('CompletionFragment')");
 }
 
 IN_PROC_BROWSER_TEST_F(SettingsPrivacyGuideTest,
                        CompletionFragmentPrivacySandboxRestricted) {
-  RunTest("settings/privacy_guide_fragments_test.js",
+  RunTest("settings/privacy_guide_completion_fragment_test.js",
           "runMochaSuite('CompletionFragmentPrivacySandboxRestricted')");
 }
 
 IN_PROC_BROWSER_TEST_F(SettingsPrivacyGuideTest,
                        CompletionFragmentWithTrackingProtection) {
-  RunTest("settings/privacy_guide_fragments_test.js",
+  RunTest("settings/privacy_guide_completion_fragment_test.js",
           "runMochaSuite('CompletionFragmentWithoutTrackingProtection')");
 }
 
+IN_PROC_BROWSER_TEST_F(
+    SettingsPrivacyGuideTest,
+    CompletionFragmentPrivacySandboxRestrictedWithNoticeEnabled) {
+  RunTest("settings/privacy_guide_completion_fragment_test.js",
+          "runMochaSuite('"
+          "CompletionFragmentPrivacySandboxRestrictedWithNoticeEnabled')");
+}
+
 class SettingsPrivacyPagePrivacySandboxRestrictedTest
     : public SettingsBrowserTest {
  protected:
@@ -1481,6 +1489,14 @@
           "runMochaSuite('SafetyHubDisabled')");
 }
 
+IN_PROC_BROWSER_TEST_F(
+    SettingsSiteSettingsPageTest,
+    AbusiveNotificationsEnabledUnusedSitePermissionsDisabled) {
+  RunTest("settings/site_settings_page_test.js",
+          "runMochaSuite('"
+          "AbusiveNotificationsEnabledUnusedSitePermissionsDisabled')");
+}
+
 using SettingsTranslatePageTest = SettingsBrowserTest;
 
 IN_PROC_BROWSER_TEST_F(SettingsTranslatePageTest, TranslateSettings) {
diff --git a/chrome/test/data/webui/settings/site_settings_page_test.ts b/chrome/test/data/webui/settings/site_settings_page_test.ts
index 36ae224..6fa9cec 100644
--- a/chrome/test/data/webui/settings/site_settings_page_test.ts
+++ b/chrome/test/data/webui/settings/site_settings_page_test.ts
@@ -472,3 +472,48 @@
             '#unusedSitePermissionsRevocationToggle')));
   });
 });
+
+/**
+ * If unused site permissions feature is not enabled, but abusive notification
+ * revocation is enabled, the UI should be shown if there are permissions for
+ * the user to review.
+ *
+ * TODO(crbug.com/328773301): Remove after
+ * SafetyHubAbusiveNotificationRevocation is launched.
+ */
+suite('AbusiveNotificationsEnabledUnusedSitePermissionsDisabled', function() {
+  let page: SettingsSiteSettingsPageElement;
+  let safetyHubBrowserProxy: TestSafetyHubBrowserProxy;
+
+  suiteSetup(function() {
+    loadTimeData.overrideValues({
+      enableSafetyHub: false,
+      safetyCheckUnusedSitePermissionsEnabled: false,
+      safetyHubAbusiveNotificationRevocationEnabled: true,
+    });
+  });
+
+  setup(async function() {
+    safetyHubBrowserProxy = new TestSafetyHubBrowserProxy();
+    SafetyHubBrowserProxyImpl.setInstance(safetyHubBrowserProxy);
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    page = document.createElement('settings-site-settings-page');
+    document.body.appendChild(page);
+    await flushTasks();
+  });
+
+  test(
+      'VisibleWithItemsToReviewUnusedSitePermissionsDisabled',
+      async function() {
+        // The element is not visible when there is nothing to review.
+        assertFalse(isChildVisible(page, 'settings-unused-site-permissions'));
+
+        // The element becomes visible if the list of permissions is no longer
+        // empty.
+        webUIListenerCallback(
+            SafetyHubEvent.UNUSED_PERMISSIONS_MAYBE_CHANGED,
+            unusedSitePermissionMockData);
+        await flushTasks();
+        assertTrue(isChildVisible(page, 'settings-unused-site-permissions'));
+      });
+});
diff --git a/chrome/test/data/webui/side_panel/read_anything/BUILD.gn b/chrome/test/data/webui/side_panel/read_anything/BUILD.gn
index 43eb43e..b0a83221 100644
--- a/chrome/test/data/webui/side_panel/read_anything/BUILD.gn
+++ b/chrome/test/data/webui/side_panel/read_anything/BUILD.gn
@@ -12,7 +12,6 @@
     "checkmark_visible_on_selected.ts",
     "voice_selection_menu_test.ts",
     "read_aloud_flag_test.ts",
-    "toolbar_flag_test.ts",
     "font_size_test.ts",
     "font_menu_test.ts",
     "color_menu_test.ts",
diff --git a/chrome/test/data/webui/side_panel/read_anything/app_receives_toolbar_changes_test.ts b/chrome/test/data/webui/side_panel/read_anything/app_receives_toolbar_changes_test.ts
index 704dedd4..d94b74e 100644
--- a/chrome/test/data/webui/side_panel/read_anything/app_receives_toolbar_changes_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/app_receives_toolbar_changes_test.ts
@@ -44,15 +44,15 @@
     test('container letter spacing updated', () => {
       const letterSpacing1 = 0.5;
       emitLetterSpacing(letterSpacing1);
-      assertEquals(containerLetterSpacing(), letterSpacing1);
+      assertEquals(letterSpacing1, containerLetterSpacing());
 
       const letterSpacing2 = 1.2;
       emitLetterSpacing(letterSpacing2);
-      assertEquals(containerLetterSpacing(), letterSpacing2);
+      assertEquals(letterSpacing2, containerLetterSpacing());
 
       const letterSpacing3 = 2;
       emitLetterSpacing(letterSpacing3);
-      assertEquals(containerLetterSpacing(), letterSpacing3);
+      assertEquals(letterSpacing3, containerLetterSpacing());
     });
   });
 
@@ -69,15 +69,15 @@
     test('container line spacing updated', () => {
       const lineSpacing1 = 0.5;
       emitLineSpacing(lineSpacing1);
-      assertEquals(containerLineSpacing(), lineSpacing1);
+      assertEquals(lineSpacing1, containerLineSpacing());
 
       const lineSpacing2 = 1.2;
       emitLineSpacing(lineSpacing2);
-      assertEquals(containerLineSpacing(), lineSpacing2);
+      assertEquals(lineSpacing2, containerLineSpacing());
 
       const lineSpacing3 = 2;
       emitLineSpacing(lineSpacing3);
-      assertEquals(containerLineSpacing(), lineSpacing3);
+      assertEquals(lineSpacing3, containerLineSpacing());
     });
   });
 
@@ -96,17 +96,17 @@
       const fontSize1 = 12;
       chrome.readingMode.fontSize = fontSize1;
       emitFontSize();
-      assertEquals(containerFontSize(), fontSize1);
+      assertEquals(fontSize1, containerFontSize());
 
       const fontSize2 = 16;
       chrome.readingMode.fontSize = fontSize2;
       emitFontSize();
-      assertEquals(containerFontSize(), fontSize2);
+      assertEquals(fontSize2, containerFontSize());
 
       const fontSize3 = 9;
       chrome.readingMode.fontSize = fontSize3;
       emitFontSize();
-      assertEquals(containerFontSize(), fontSize3);
+      assertEquals(fontSize3, containerFontSize());
     });
   });
 
@@ -177,8 +177,8 @@
 
     function assertFontsEqual(actual: string, expected: string): void {
       assertEquals(
-          actual.trim().toLowerCase().replaceAll('"', ''),
-          expected.trim().toLowerCase().replaceAll('"', ''));
+          expected.trim().toLowerCase().replaceAll('"', ''),
+          actual.trim().toLowerCase().replaceAll('"', ''));
     }
 
     test('valid font updates container font', () => {
@@ -271,7 +271,7 @@
             () => {
               emitLanguageToggle(lang);
 
-              assertEquals(sentInstallRequestFor, lang);
+              assertEquals(lang, sentInstallRequestFor);
               assertEquals(
                   app.getVoicePackLocalStatus(lang),
                   VoiceClientSideStatusCode.SENT_INSTALL_REQUEST_ERROR_RETRY);
@@ -282,7 +282,7 @@
         test('directly sends install request', () => {
           emitLanguageToggle('en-us');
 
-          assertEquals(sentInstallRequestFor, 'en-us');
+          assertEquals('en-us', sentInstallRequestFor);
         });
       });
 
@@ -299,7 +299,7 @@
         test('does not directly install lang', () => {
           emitLanguageToggle(lang);
 
-          assertEquals(sentInstallRequestFor, '');
+          assertEquals('', sentInstallRequestFor);
         });
       });
     });
@@ -423,25 +423,25 @@
 
     test('on hide, uses transparent highlight', () => {
       emitHighlight(false);
-      assertEquals(highlightColor(), 'transparent');
+      assertEquals('transparent', highlightColor());
     });
 
     test('on show, uses colored highlight', () => {
       emitHighlight(true);
-      assertNotEquals(highlightColor(), 'transparent');
+      assertNotEquals('transparent', highlightColor());
     });
 
     suite('after update color theme', () => {
       test('uses colored highlight with highlights on', () => {
         emitHighlight(true);
         emitEvent(app, THEME_EVENT, {detail: {data: '-blue'}});
-        assertNotEquals(highlightColor(), 'transparent');
+        assertNotEquals('transparent', highlightColor());
       });
 
       test('uses transparent highlight with highlights off', () => {
         emitHighlight(false);
         emitEvent(app, THEME_EVENT, {detail: {data: '-yellow'}});
-        assertEquals(highlightColor(), 'transparent');
+        assertEquals('transparent', highlightColor());
       });
     });
   });
diff --git a/chrome/test/data/webui/side_panel/read_anything/checkmark_visible_on_selected.ts b/chrome/test/data/webui/side_panel/read_anything/checkmark_visible_on_selected.ts
index ad145e0..ca65332 100644
--- a/chrome/test/data/webui/side_panel/read_anything/checkmark_visible_on_selected.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/checkmark_visible_on_selected.ts
@@ -29,8 +29,8 @@
       checkMarks: NodeListOf<HTMLElement>, expectedIndex: number): void {
     checkMarks.forEach((element, index) => {
       assertEquals(
-          element.style.visibility,
-          index === expectedIndex ? 'visible' : 'hidden');
+          index === expectedIndex ? 'visible' : 'hidden',
+          element.style.visibility);
     });
   }
 
diff --git a/chrome/test/data/webui/side_panel/read_anything/color_menu_test.ts b/chrome/test/data/webui/side_panel/read_anything/color_menu_test.ts
index 12d2ed2..93551c4 100644
--- a/chrome/test/data/webui/side_panel/read_anything/color_menu_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/color_menu_test.ts
@@ -61,7 +61,7 @@
         option.click();
 
         // the selected option is unique and is emitted down the pipeline
-        assertEquals(emittedColors.indexOf(colorEmitted), -1);
+        assertEquals(-1, emittedColors.indexOf(colorEmitted));
         assertGT(chrome.readingMode.colorTheme, previousPropagatedColor);
 
         emittedColors.push(colorEmitted);
diff --git a/chrome/test/data/webui/side_panel/read_anything/common.ts b/chrome/test/data/webui/side_panel/read_anything/common.ts
index 3d1da7d..f4eec86 100644
--- a/chrome/test/data/webui/side_panel/read_anything/common.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/common.ts
@@ -62,7 +62,7 @@
         default: false,
         name: '',
         lang: 'en-us',
-        localService: true,
+        localService: false,
         voiceURI: '',
       },
       overrides || {});
diff --git a/chrome/test/data/webui/side_panel/read_anything/common_test.ts b/chrome/test/data/webui/side_panel/read_anything/common_test.ts
index 12e3cbf..9191c20 100644
--- a/chrome/test/data/webui/side_panel/read_anything/common_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/common_test.ts
@@ -18,13 +18,13 @@
   suite('getCurrentSpeechRate', () => {
     test('rounds value to 1 decimal', () => {
       chrome.readingMode.speechRate = 1.1234567890;
-      assertEquals(getCurrentSpeechRate(), 1.1);
+      assertEquals(1.1, getCurrentSpeechRate());
 
       chrome.readingMode.speechRate = 0.912345678;
-      assertEquals(getCurrentSpeechRate(), 0.9);
+      assertEquals(0.9, getCurrentSpeechRate());
 
       chrome.readingMode.speechRate = 1.199999999;
-      assertEquals(getCurrentSpeechRate(), 1.2);
+      assertEquals(1.2, getCurrentSpeechRate());
     });
   });
 });
diff --git a/chrome/test/data/webui/side_panel/read_anything/connected_callback_test.ts b/chrome/test/data/webui/side_panel/read_anything/connected_callback_test.ts
index 44dacb79..58f68727 100644
--- a/chrome/test/data/webui/side_panel/read_anything/connected_callback_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/connected_callback_test.ts
@@ -33,8 +33,8 @@
         app.querySelector<HTMLElement>('#empty-state-container')!.hidden,
         false);
     const emptyState = app.querySelector('sp-empty-state')!;
-    assertEquals(emptyState.heading, 'Getting ready');
-    assertEquals(emptyState.body, '');
+    assertEquals('Getting ready', emptyState.heading);
+    assertEquals('', emptyState.body);
     assertStringContains(emptyState.imagePath, 'throbber');
     assertStringContains(emptyState.darkImagePath, 'throbber');
   });
diff --git a/chrome/test/data/webui/side_panel/read_anything/fake_speech_synthesis.ts b/chrome/test/data/webui/side_panel/read_anything/fake_speech_synthesis.ts
index 3f7ce5a..dc6bbf1ee 100644
--- a/chrome/test/data/webui/side_panel/read_anything/fake_speech_synthesis.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/fake_speech_synthesis.ts
@@ -1,6 +1,7 @@
 // Copyright 2024 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
+import {createSpeechSynthesisVoice} from './common.js';
 
 // A fake SpeechSynthesis object for testing
 export class FakeSpeechSynthesis {
@@ -46,13 +47,13 @@
 
   getVoices(): SpeechSynthesisVoice[] {
     return [
-      {lang: 'en', name: 'Lauren', default: true} as SpeechSynthesisVoice,
-      {lang: 'en', name: 'Eitan'} as SpeechSynthesisVoice,
-      {lang: 'en', name: 'Kristi'} as SpeechSynthesisVoice,
-      {lang: 'en', name: 'Shari'} as SpeechSynthesisVoice,
-      {lang: 'en', name: 'Yu'} as SpeechSynthesisVoice,
-      {lang: 'en', name: 'Xiang', localService: this.shouldUseLocalVoices} as
-          SpeechSynthesisVoice,
+      createSpeechSynthesisVoice({lang: 'en', name: 'Lauren', default: true}),
+      createSpeechSynthesisVoice({lang: 'en', name: 'Eitan'}),
+      createSpeechSynthesisVoice({lang: 'en', name: 'Kristi'}),
+      createSpeechSynthesisVoice({lang: 'en', name: 'Shari'}),
+      createSpeechSynthesisVoice({lang: 'en', name: 'Yu'}),
+      createSpeechSynthesisVoice(
+          {lang: 'en', name: 'Xiang', localService: this.shouldUseLocalVoices}),
     ];
   }
 
diff --git a/chrome/test/data/webui/side_panel/read_anything/fake_tree_builder_test.ts b/chrome/test/data/webui/side_panel/read_anything/fake_tree_builder_test.ts
index 6bfa8e129..717c1a8 100644
--- a/chrome/test/data/webui/side_panel/read_anything/fake_tree_builder_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/fake_tree_builder_test.ts
@@ -39,18 +39,18 @@
       const node = tree.nodes.get(expectedId)!;
       assertEquals(node.id, expectedId);
 
-      assertEquals(node.htmlTag, expectedHtmlTag);
-      assertEquals(readingMode.getHtmlTag(expectedId), expectedHtmlTag);
+      assertEquals(expectedHtmlTag, node.htmlTag);
+      assertEquals(expectedHtmlTag, readingMode.getHtmlTag(expectedId));
 
-      assertEquals(node.textContent, expectedTextContent);
-      assertEquals(readingMode.getTextContent(expectedId), expectedTextContent);
+      assertEquals(expectedTextContent, node.textContent);
+      assertEquals(expectedTextContent, readingMode.getTextContent(expectedId));
 
       const readingModeChildren = readingMode.getChildren(expectedId);
-      assertEquals(readingModeChildren.length, expectedChildren.length);
-      assertEquals(node.children.length, expectedChildren.length);
+      assertEquals(expectedChildren.length, readingModeChildren.length);
+      assertEquals(expectedChildren.length, node.children.length);
       for (let i = 0; i < expectedChildren.length; i++) {
-        assertEquals(readingModeChildren[i]!, expectedChildren[i]);
-        assertEquals(node.children[i]!, expectedChildren[i]);
+        assertEquals(expectedChildren[i], readingModeChildren[i]!);
+        assertEquals(expectedChildren[i], node.children[i]!);
       }
     }
 
@@ -75,7 +75,7 @@
       const rootId = 0;
       const tree = builder.root(rootId).build(readingMode);
 
-      assertEquals(readingMode.rootId, rootId);
+      assertEquals(rootId, readingMode.rootId);
       assertNodeHasExpectedValues(tree, rootId, '#document', '', []);
     });
 
@@ -99,7 +99,7 @@
       });
 
       test('root of tree has document tag and html tag children', () => {
-        assertEquals(readingMode.rootId, rootId);
+        assertEquals(rootId, readingMode.rootId);
         assertNodeHasExpectedValues(
             tree, rootId, '#document', '', htmlTagNodes);
       });
@@ -150,19 +150,19 @@
       test('selection within one node succeeds', () => {
         tree.setSelection(14, 3, 14, 10);
 
-        assertEquals(readingMode.startNodeId, 14);
-        assertEquals(readingMode.endNodeId, 14);
-        assertEquals(readingMode.startOffset, 3);
-        assertEquals(readingMode.endOffset, 10);
+        assertEquals(14, readingMode.startNodeId);
+        assertEquals(14, readingMode.endNodeId);
+        assertEquals(3, readingMode.startOffset);
+        assertEquals(10, readingMode.endOffset);
       });
 
       test('selection across nodes succeeds', () => {
         tree.setSelection(14, 0, 16, 5);
 
-        assertEquals(readingMode.startNodeId, 14);
-        assertEquals(readingMode.endNodeId, 16);
-        assertEquals(readingMode.startOffset, 0);
-        assertEquals(readingMode.endOffset, 5);
+        assertEquals(14, readingMode.startNodeId);
+        assertEquals(16, readingMode.endNodeId);
+        assertEquals(0, readingMode.startOffset);
+        assertEquals(5, readingMode.endOffset);
       });
     });
 
@@ -177,18 +177,18 @@
         });
 
         test('indices for highlighted node are correct', () => {
-          assertEquals(readingMode.getCurrentTextStartIndex(textNodes[1]!), 3);
-          assertEquals(readingMode.getCurrentTextEndIndex(textNodes[1]!), 10);
+          assertEquals(3, readingMode.getCurrentTextStartIndex(textNodes[1]!));
+          assertEquals(10, readingMode.getCurrentTextEndIndex(textNodes[1]!));
         });
 
         test('indices for valid but not highlighted node are not found', () => {
-          assertEquals(readingMode.getCurrentTextStartIndex(textNodes[2]!), -1);
-          assertEquals(readingMode.getCurrentTextEndIndex(textNodes[2]!), -1);
+          assertEquals(-1, readingMode.getCurrentTextStartIndex(textNodes[2]!));
+          assertEquals(-1, readingMode.getCurrentTextEndIndex(textNodes[2]!));
         });
 
         test('indices for invalid node are not found', () => {
-          assertEquals(readingMode.getCurrentTextStartIndex(0), -1);
-          assertEquals(readingMode.getCurrentTextEndIndex(0), -1);
+          assertEquals(-1, readingMode.getCurrentTextStartIndex(0));
+          assertEquals(-1, readingMode.getCurrentTextEndIndex(0));
         });
       });
 
@@ -198,20 +198,20 @@
         });
 
         test('indices for first highlighted node are correct', () => {
-          assertEquals(readingMode.getCurrentTextStartIndex(textNodes[1]!), 4);
+          assertEquals(4, readingMode.getCurrentTextStartIndex(textNodes[1]!));
           assertEquals(
               readingMode.getCurrentTextEndIndex(textNodes[1]!),
               text[1]!.length);
         });
 
         test('indices for last highlighted node are correct', () => {
-          assertEquals(readingMode.getCurrentTextStartIndex(textNodes[3]!), 0);
-          assertEquals(readingMode.getCurrentTextEndIndex(textNodes[3]!), 5);
+          assertEquals(0, readingMode.getCurrentTextStartIndex(textNodes[3]!));
+          assertEquals(5, readingMode.getCurrentTextEndIndex(textNodes[3]!));
         });
 
         test('indices for invalid node are not found', () => {
-          assertEquals(readingMode.getCurrentTextStartIndex(0), -1);
-          assertEquals(readingMode.getCurrentTextEndIndex(0), -1);
+          assertEquals(-1, readingMode.getCurrentTextStartIndex(0));
+          assertEquals(-1, readingMode.getCurrentTextEndIndex(0));
         });
       });
     });
@@ -227,20 +227,20 @@
         });
 
         test('full node is highlighted', () => {
-          assertEquals(readingMode.getCurrentTextStartIndex(textNodes[2]!), 0);
+          assertEquals(0, readingMode.getCurrentTextStartIndex(textNodes[2]!));
           assertEquals(
               readingMode.getCurrentTextEndIndex(textNodes[2]!),
               text[2]!.length);
         });
 
         test('valid but not highlighted node has invalid indices', () => {
-          assertEquals(readingMode.getCurrentTextStartIndex(textNodes[3]!), -1);
-          assertEquals(readingMode.getCurrentTextEndIndex(textNodes[3]!), -1);
+          assertEquals(-1, readingMode.getCurrentTextStartIndex(textNodes[3]!));
+          assertEquals(-1, readingMode.getCurrentTextEndIndex(textNodes[3]!));
         });
 
         test('indices for invalid node are not found', () => {
-          assertEquals(readingMode.getCurrentTextStartIndex(0), -1);
-          assertEquals(readingMode.getCurrentTextEndIndex(0), -1);
+          assertEquals(-1, readingMode.getCurrentTextStartIndex(0));
+          assertEquals(-1, readingMode.getCurrentTextEndIndex(0));
         });
       });
     });
diff --git a/chrome/test/data/webui/side_panel/read_anything/font_menu_test.ts b/chrome/test/data/webui/side_panel/read_anything/font_menu_test.ts
index 65e787b..1a6c479 100644
--- a/chrome/test/data/webui/side_panel/read_anything/font_menu_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/font_menu_test.ts
@@ -48,8 +48,8 @@
 
   function assertFontsEqual(actual: string, expected: string): void {
     assertEquals(
-        actual.trim().toLowerCase().replaceAll('"', ''),
-        expected.trim().toLowerCase().replaceAll('"', ''));
+        expected.trim().toLowerCase().replaceAll('"', ''),
+        actual.trim().toLowerCase().replaceAll('"', ''));
   }
 
   suite('with read aloud', () => {
@@ -80,7 +80,7 @@
       assertEquals(fontMenuOptions.length, 4);
 
       updateFonts(['font 1']);
-      assertEquals(fontMenuOptions.length, 1);
+      assertEquals(1, fontMenuOptions.length);
 
       // initial-count in the dom-repeat for the fonts menu limits the
       // size of the font menu, so adding more than 8 fonts is difficult to
@@ -96,7 +96,7 @@
         'font 7',
         'font 8',
       ]);
-      assertEquals(fontMenuOptions.length, 8);
+      assertEquals(8, fontMenuOptions.length);
     });
 
     test('uses the first font if font not available', () => {
@@ -113,10 +113,10 @@
       const hiddenCheckMarks =
           toolbar.$.fontMenu.get().querySelectorAll<HTMLElement>(
               '.check-mark-hidden-true');
-      assertEquals(checkMarks.length, 1);
-      assertEquals(hiddenCheckMarks.length, 2);
-      assertEquals(chrome.readingMode.fontName, fonts[0]);
-      assertEquals(toolbar.style.fontFamily, fonts[0]);
+      assertEquals(1, checkMarks.length);
+      assertEquals(2, hiddenCheckMarks.length);
+      assertEquals(fonts[0], chrome.readingMode.fontName);
+      assertEquals(fonts[0], toolbar.style.fontFamily);
     });
 
     test('each font option is styled with the font that it is', () => {
@@ -200,9 +200,9 @@
       // Update the fonts to exclude the previously chosen font
       updateFonts(fonts);
 
-      assertEquals(fontSelect!.selectedIndex, 0);
-      assertEquals(chrome.readingMode.fontName, fonts[0]);
-      assertEquals(toolbar.style.fontFamily, fonts[0]);
+      assertEquals(0, fontSelect!.selectedIndex);
+      assertEquals(fonts[0], chrome.readingMode.fontName);
+      assertEquals(fonts[0], toolbar.style.fontFamily);
     });
 
     suite('on font option clicked', () => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/highlight_toggle_test.ts b/chrome/test/data/webui/side_panel/read_anything/highlight_toggle_test.ts
index 7c4b6a5..6e08d99 100644
--- a/chrome/test/data/webui/side_panel/read_anything/highlight_toggle_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/highlight_toggle_test.ts
@@ -43,9 +43,9 @@
 
   suite('by default', () => {
     test('highlighting is on', () => {
-      assertEquals(highlightButton.ironIcon, 'read-anything:highlight-on');
+      assertEquals('read-anything:highlight-on', highlightButton.ironIcon);
       assertStringContains(highlightButton.title, 'off');
-      assertEquals(chrome.readingMode.highlightGranularity, 0);
+      assertEquals(0, chrome.readingMode.highlightGranularity);
       assertTrue(chrome.readingMode.isHighlightOn());
       assertFalse(!!highlightOn);
     });
@@ -57,9 +57,9 @@
     });
 
     test('highlighting is turned off', () => {
-      assertEquals(highlightButton.ironIcon, 'read-anything:highlight-off');
+      assertEquals('read-anything:highlight-off', highlightButton.ironIcon);
       assertStringContains(highlightButton.title, 'on');
-      assertEquals(chrome.readingMode.highlightGranularity, 1);
+      assertEquals(1, chrome.readingMode.highlightGranularity);
       assertFalse(chrome.readingMode.isHighlightOn());
       assertFalse(highlightOn!);
     });
@@ -70,9 +70,9 @@
       });
 
       test('highlighting is turned back on', () => {
-        assertEquals(highlightButton.ironIcon, 'read-anything:highlight-on');
+        assertEquals('read-anything:highlight-on', highlightButton.ironIcon);
         assertStringContains(highlightButton.title, 'off');
-        assertEquals(chrome.readingMode.highlightGranularity, 0);
+        assertEquals(0, chrome.readingMode.highlightGranularity);
         assertTrue(chrome.readingMode.isHighlightOn());
         assertTrue(highlightOn!);
       });
diff --git a/chrome/test/data/webui/side_panel/read_anything/language_change_test.ts b/chrome/test/data/webui/side_panel/read_anything/language_change_test.ts
index c0b8722..ac457d49 100644
--- a/chrome/test/data/webui/side_panel/read_anything/language_change_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/language_change_test.ts
@@ -13,7 +13,7 @@
 import {AVAILABLE_GOOGLE_TTS_LOCALES, convertLangOrLocaleForVoicePackManager, PACK_MANAGER_SUPPORTED_LANGS_AND_LOCALES, VoicePackServerStatusSuccessCode} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome-untrusted://webui-test/chai_assert.js';
 
-import {suppressInnocuousErrors} from './common.js';
+import {createSpeechSynthesisVoice, suppressInnocuousErrors} from './common.js';
 import {FakeReadingMode} from './fake_reading_mode.js';
 import {TestColorUpdaterBrowserProxy} from './test_color_updater_browser_proxy.js';
 
@@ -24,23 +24,24 @@
   const lang3 = 'pt-br';
   const langWithNoVoices = 'elvish';
 
-  const defaultVoice = {
+  const defaultVoice = createSpeechSynthesisVoice({
     lang: langForDefaultVoice,
     name: 'Kristi',
     default: true,
-  } as SpeechSynthesisVoice;
-  const firstVoiceWithLang1 = {lang: lang1, name: 'Lauren'} as
-      SpeechSynthesisVoice;
-  const defaultVoiceWithLang1 = {lang: lang1, name: 'Eitan', default: true} as
-      SpeechSynthesisVoice;
-  const firstVoiceWithLang2 = {lang: lang2, name: 'Yu'} as SpeechSynthesisVoice;
-  const secondVoiceWithLang2 = {lang: lang2, name: 'Xiang'} as
-      SpeechSynthesisVoice;
-  const firstVoiceWithLang3 = {lang: lang3, name: 'Kristi'} as
-      SpeechSynthesisVoice;
-  const naturalVoiceWithLang3 = {lang: lang3, name: 'Kristi (Natural)'} as
-      SpeechSynthesisVoice;
-  const otherVoice = {lang: 'it', name: 'Shari'} as SpeechSynthesisVoice;
+  });
+  const firstVoiceWithLang1 =
+      createSpeechSynthesisVoice({lang: lang1, name: 'Lauren'});
+  const defaultVoiceWithLang1 =
+      createSpeechSynthesisVoice({lang: lang1, name: 'Eitan', default: true});
+  const firstVoiceWithLang2 =
+      createSpeechSynthesisVoice({lang: lang2, name: 'Yu'});
+  const secondVoiceWithLang2 =
+      createSpeechSynthesisVoice({lang: lang2, name: 'Xiang'});
+  const firstVoiceWithLang3 =
+      createSpeechSynthesisVoice({lang: lang3, name: 'Kristi'});
+  const naturalVoiceWithLang3 =
+      createSpeechSynthesisVoice({lang: lang3, name: 'Kristi (Natural)'});
+  const otherVoice = createSpeechSynthesisVoice({lang: 'it', name: 'Shari'});
   const voices = [
     defaultVoice,
     firstVoiceWithLang1,
@@ -102,7 +103,7 @@
 
     chrome.readingMode.getStoredVoice = () => otherVoice.name;
     app.languageChanged();
-    assertEquals(app.selectedVoice, startingVoice);
+    assertEquals(startingVoice, app.selectedVoice);
   });
 
   suite('with flag updates selected voice', () => {
@@ -122,7 +123,7 @@
 
       app.languageChanged();
 
-      assertEquals(app.selectedVoice, otherVoice);
+      assertEquals(otherVoice, app.selectedVoice);
     });
 
     suite('when there is no stored voice for this language', () => {
@@ -138,12 +139,12 @@
         test('to the current voice if there is one', () => {
           app.selectedVoice = otherVoice;
           app.languageChanged();
-          assertEquals(app.selectedVoice, otherVoice);
+          assertEquals(otherVoice, app.selectedVoice);
         });
 
         test('to a natural voice if there\'s no current voice', () => {
           app.languageChanged();
-          assertEquals(app.selectedVoice, naturalVoiceWithLang3);
+          assertEquals(naturalVoiceWithLang3, app.selectedVoice);
         });
 
         test('to the device default if there\'s no natural', () => {
@@ -151,7 +152,7 @@
           flush();
 
           app.languageChanged();
-          assertEquals(app.selectedVoice, defaultVoice);
+          assertEquals(defaultVoice, app.selectedVoice);
         });
       });
 
@@ -159,7 +160,7 @@
         test('to a natural voice for this language', () => {
           chrome.readingMode.baseLanguageForSpeech = lang3;
           app.languageChanged();
-          assertEquals(app.selectedVoice, naturalVoiceWithLang3);
+          assertEquals(naturalVoiceWithLang3, app.selectedVoice);
         });
 
         test(
@@ -167,7 +168,7 @@
             () => {
               chrome.readingMode.baseLanguageForSpeech = lang1;
               app.languageChanged();
-              assertEquals(app.selectedVoice, defaultVoiceWithLang1);
+              assertEquals(defaultVoiceWithLang1, app.selectedVoice);
             });
 
         test(
@@ -175,7 +176,7 @@
             () => {
               chrome.readingMode.baseLanguageForSpeech = lang2;
               app.languageChanged();
-              assertEquals(app.selectedVoice, firstVoiceWithLang2);
+              assertEquals(firstVoiceWithLang2, app.selectedVoice);
             });
       });
 
@@ -188,7 +189,7 @@
           app.languageChanged();
 
           assertTrue(app.enabledLangs.includes(lang3));
-          assertEquals(app.selectedVoice, naturalVoiceWithLang3);
+          assertEquals(naturalVoiceWithLang3, app.selectedVoice);
         });
 
         test(
@@ -201,13 +202,13 @@
               app.languageChanged();
 
               assertTrue(app.enabledLangs.includes(lang1));
-              assertEquals(app.selectedVoice, defaultVoiceWithLang1);
+              assertEquals(defaultVoiceWithLang1, app.selectedVoice);
             });
 
 
         test('to voice in different locale and same language', () => {
-          const voice = {lang: 'en-GB', name: 'British', default: true} as
-              SpeechSynthesisVoice;
+          const voice = createSpeechSynthesisVoice(
+              {lang: 'en-GB', name: 'British', default: true});
           app.enabledLangs = ['en-gb'];
           app.availableVoices = [voice];
           setInstalled('en-gb');
@@ -217,7 +218,7 @@
 
           app.languageChanged();
 
-          assertEquals(app.selectedVoice, voice);
+          assertEquals(voice, app.selectedVoice);
         });
 
         test('to natural enabled voice if no same locale', () => {
@@ -228,7 +229,7 @@
 
           app.languageChanged();
 
-          assertEquals(app.selectedVoice, naturalVoiceWithLang3);
+          assertEquals(naturalVoiceWithLang3, app.selectedVoice);
         });
 
         test('to default enabled voice if no natural voice', () => {
@@ -239,7 +240,7 @@
 
           app.languageChanged();
 
-          assertEquals(app.selectedVoice, defaultVoiceWithLang1);
+          assertEquals(defaultVoiceWithLang1, app.selectedVoice);
         });
 
         test('to undefined if no enabled languages', () => {
@@ -249,7 +250,7 @@
 
           app.languageChanged();
 
-          assertEquals(app.selectedVoice, undefined);
+          assertEquals(undefined, app.selectedVoice);
         });
       });
     });
diff --git a/chrome/test/data/webui/side_panel/read_anything/language_menu_test.ts b/chrome/test/data/webui/side_panel/read_anything/language_menu_test.ts
index 3853101..4122575 100644
--- a/chrome/test/data/webui/side_panel/read_anything/language_menu_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/language_menu_test.ts
@@ -11,6 +11,8 @@
 import {AVAILABLE_GOOGLE_TTS_LOCALES, VoiceClientSideStatusCode} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome-untrusted://webui-test/chai_assert.js';
 
+import {createSpeechSynthesisVoice} from './common.js';
+
 suite('LanguageMenu', () => {
   let languageMenu: LanguageMenuElement;
   let availableVoices: SpeechSynthesisVoice[];
@@ -76,7 +78,7 @@
 
     test('with existing available language no duplicates added', () => {
       availableVoices =
-          [{name: 'test voice 1', lang: 'en-US'} as SpeechSynthesisVoice];
+          [createSpeechSynthesisVoice({name: 'test voice 1', lang: 'en-US'})];
       const expectedLanguages =
           chrome.readingMode.isLanguagePackDownloadingEnabled &&
               chrome.readingMode.isChromeOsAsh ?
@@ -85,7 +87,7 @@
       setAvailableVoices();
       languageMenu.showDialog();
       assertTrue(isPositionedOnPage(languageMenu));
-      assertEquals(getLanguageLineItems().length, expectedLanguages);
+      assertEquals(expectedLanguages, getLanguageLineItems().length);
     });
   });
 
@@ -97,11 +99,11 @@
 
     test('with existing available language no duplicates added', () => {
       availableVoices =
-          [{name: 'test voice 1', lang: 'en-US'} as SpeechSynthesisVoice];
+          [createSpeechSynthesisVoice({name: 'test voice 1', lang: 'en-US'})];
       setAvailableVoices();
       languageMenu.showDialog();
       assertTrue(isPositionedOnPage(languageMenu));
-      assertEquals(getLanguageLineItems().length, 1);
+      assertEquals(1, getLanguageLineItems().length);
     });
 
     test('adds language from available voice', () => {
@@ -111,11 +113,11 @@
           1 :
           0;
       availableVoices =
-          [{name: 'test voice 5', lang: 'en-es'} as SpeechSynthesisVoice];
+          [createSpeechSynthesisVoice({name: 'test voice 5', lang: 'en-es'})];
       setAvailableVoices();
       languageMenu.showDialog();
       assertTrue(isPositionedOnPage(languageMenu));
-      assertEquals(getLanguageLineItems().length, expectedLanguages + 1);
+      assertEquals(expectedLanguages + 1, getLanguageLineItems().length);
     });
 
     test('sorts alphabetically', () => {
@@ -125,22 +127,22 @@
           1 :
           0;
       availableVoices = [
-        {name: 'Steve', lang: 'da-dk'} as SpeechSynthesisVoice,
-        {name: 'Dustin', lang: 'bn-bd'} as SpeechSynthesisVoice,
+        createSpeechSynthesisVoice({name: 'Steve', lang: 'da-dk'}),
+        createSpeechSynthesisVoice({name: 'Dustin', lang: 'bn-bd'}),
       ];
       setAvailableVoices();
       languageMenu.showDialog();
       assertTrue(isPositionedOnPage(languageMenu));
-      assertEquals(getLanguageLineItems().length, expectedLanguages + 2);
-      assertLanguageLineWithTextAndSwitch(getLanguageLineItems()[0]!, 'bn-bd');
-      assertLanguageLineWithTextAndSwitch(getLanguageLineItems()[1]!, 'da-dk');
+      assertEquals(expectedLanguages + 2, getLanguageLineItems().length);
+      assertLanguageLineWithTextAndSwitch('bn-bd', getLanguageLineItems()[0]!);
+      assertLanguageLineWithTextAndSwitch('da-dk', getLanguageLineItems()[1]!);
     });
   });
 
   suite('with one language', () => {
     setup(() => {
       availableVoices =
-          [{name: 'test voice 1', lang: 'en-US'} as SpeechSynthesisVoice];
+          [createSpeechSynthesisVoice({name: 'test voice 1', lang: 'en-US'})];
       setAvailableVoices();
       languageMenu.showDialog();
     });
@@ -149,30 +151,30 @@
         'defaults to the locale when there is no display name with a switch',
         () => {
           assertTrue(isPositionedOnPage(languageMenu));
-          assertEquals(getLanguageLineItems().length, 1);
+          assertEquals(1, getLanguageLineItems().length);
           assertLanguageLineWithTextAndSwitch(
-              getLanguageLineItems()[0]!, 'en-US');
-          assertEquals(getLanguageSearchField().value, '');
+              'en-US', getLanguageLineItems()[0]!);
+          assertEquals('', getLanguageSearchField().value);
         });
 
     suite('when availableVoices updates', () => {
       setup(() => {
         availableVoices = [
-          {name: 'test voice 1', lang: 'en-US'} as SpeechSynthesisVoice,
-          {name: 'test voice 2', lang: 'en-UK'} as SpeechSynthesisVoice,
+          createSpeechSynthesisVoice({name: 'test voice 1', lang: 'en-US'}),
+          createSpeechSynthesisVoice({name: 'test voice 2', lang: 'en-UK'}),
         ];
         setAvailableVoices();
       });
 
       test('it updates and displays the new languages', () => {
         assertTrue(isPositionedOnPage(languageMenu));
-        assertEquals(getLanguageLineItems().length, 2);
+        assertEquals(2, getLanguageLineItems().length);
         assertLanguageLineWithTextAndSwitch(
-            getLanguageLineItems()[0]!, 'en-UK');
+            'en-UK', getLanguageLineItems()[0]!);
         assertLanguageLineWithTextAndSwitch(
-            getLanguageLineItems()[1]!, 'en-US');
-        assertEquals(getLanguageSearchField().value, '');
-        assertEquals(getNoResultsFoundMessage()!.hidden, true);
+            'en-US', getLanguageLineItems()[1]!);
+        assertEquals('', getLanguageSearchField().value);
+        assertEquals(true, getNoResultsFoundMessage()!.hidden);
       });
     });
 
@@ -186,9 +188,9 @@
 
       test('it displays the display name', () => {
         assertTrue(isPositionedOnPage(languageMenu));
-        assertEquals(getLanguageLineItems().length, 1);
+        assertEquals(1, getLanguageLineItems().length);
         assertLanguageLineWithTextAndSwitch(
-            getLanguageLineItems()[0]!, 'English (United States)');
+            'English (United States)', getLanguageLineItems()[0]!);
       });
 
       suite('with search input', () => {
@@ -196,17 +198,17 @@
           getLanguageSearchField().value = 'test';
           await getLanguageSearchField().updateComplete;
           assertTrue(isPositionedOnPage(languageMenu));
-          assertEquals(getLanguageLineItems().length, 0);
-          assertEquals(getNoResultsFoundMessage()!.hidden, false);
+          assertEquals(0, getLanguageLineItems().length);
+          assertEquals(false, getNoResultsFoundMessage()!.hidden);
         });
 
         test('it displays matching language with a match', async () => {
           getLanguageSearchField().value = 'english';
           await getLanguageSearchField().updateComplete;
-          assertEquals(getLanguageLineItems().length, 1);
+          assertEquals(1, getLanguageLineItems().length);
           assertLanguageLineWithTextAndSwitch(
-              getLanguageLineItems()[0]!, 'English (United States)');
-          assertEquals(getNoResultsFoundMessage()!.hidden, true);
+              'English (United States)', getLanguageLineItems()[0]!);
+          assertEquals(true, getNoResultsFoundMessage()!.hidden);
         });
       });
     });
@@ -215,9 +217,9 @@
   suite('with multiple languages', () => {
     setup(() => {
       availableVoices = [
-        {name: 'test voice 0', lang: 'en-US'} as SpeechSynthesisVoice,
-        {name: 'test voice 1', lang: 'it-IT'} as SpeechSynthesisVoice,
-        {name: 'test voice 2', lang: 'en-UK'} as SpeechSynthesisVoice,
+        createSpeechSynthesisVoice({name: 'test voice 0', lang: 'en-US'}),
+        createSpeechSynthesisVoice({name: 'test voice 1', lang: 'it-IT'}),
+        createSpeechSynthesisVoice({name: 'test voice 2', lang: 'en-UK'}),
       ];
       setAvailableVoices();
       enabledLangs = ['Italian'];
@@ -229,14 +231,14 @@
         'defaults to the locale when there is no display name with a switch',
         () => {
           assertTrue(isPositionedOnPage(languageMenu));
-          assertEquals(getLanguageLineItems().length, 3);
+          assertEquals(3, getLanguageLineItems().length);
           assertLanguageLineWithTextAndSwitch(
-              getLanguageLineItems()[0]!, 'en-UK');
+              'en-UK', getLanguageLineItems()[0]!);
           assertLanguageLineWithTextAndSwitch(
-              getLanguageLineItems()[1]!, 'en-US');
+              'en-US', getLanguageLineItems()[1]!);
           assertLanguageLineWithTextAndSwitch(
-              getLanguageLineItems()[2]!, 'it-IT');
-          assertEquals(getLanguageSearchField().value, '');
+              'it-IT', getLanguageLineItems()[2]!);
+          assertEquals('', getLanguageSearchField().value);
         });
 
     suite('with display names for locales', () => {
@@ -251,20 +253,20 @@
 
       test('it displays the display name', () => {
         assertTrue(isPositionedOnPage(languageMenu));
-        assertEquals(getLanguageLineItems().length, 3);
+        assertEquals(3, getLanguageLineItems().length);
         assertLanguageLineWithTextAndSwitch(
-            getLanguageLineItems()[0]!, 'English (United Kingdom)');
+            'English (United Kingdom)', getLanguageLineItems()[0]!);
         assertLanguageLineWithTextAndSwitch(
-            getLanguageLineItems()[1]!, 'English (United States)');
+            'English (United States)', getLanguageLineItems()[1]!);
         assertLanguageLineWithTextAndSwitch(
-            getLanguageLineItems()[2]!, 'Italian');
-        assertEquals(getLanguageSearchField().value, '');
+            'Italian', getLanguageLineItems()[2]!);
+        assertEquals('', getLanguageSearchField().value);
       });
 
       test('it does not groups languages with different name', () => {
         availableVoices = [
-          {name: 'test voice 0', lang: 'en-US'} as SpeechSynthesisVoice,
-          {name: 'test voice 3', lang: 'en'} as SpeechSynthesisVoice,
+          createSpeechSynthesisVoice({name: 'test voice 0', lang: 'en-US'}),
+          createSpeechSynthesisVoice({name: 'test voice 3', lang: 'en'}),
         ];
         setAvailableVoices();
         languageMenu.localeToDisplayName = {
@@ -273,38 +275,38 @@
         };
         flush();
         assertTrue(isPositionedOnPage(languageMenu));
-        assertEquals(getLanguageLineItems().length, 2);
+        assertEquals(2, getLanguageLineItems().length);
         assertLanguageLineWithTextAndSwitch(
-            getLanguageLineItems()[0]!, 'English');
+            'English', getLanguageLineItems()[0]!);
         assertLanguageLineWithTextAndSwitch(
-            getLanguageLineItems()[1]!, 'English (United States)');
+            'English (United States)', getLanguageLineItems()[1]!);
       });
 
       test('it toggles switch on for initially enabled line', async () => {
         assertTrue(isPositionedOnPage(languageMenu));
-        assertEquals(getLanguageLineItems().length, 3);
-        assertLanguageLineWithToggleChecked(getLanguageLineItems()[0]!, false);
-        assertLanguageLineWithToggleChecked(getLanguageLineItems()[1]!, true);
-        assertLanguageLineWithToggleChecked(getLanguageLineItems()[2]!, false);
+        assertEquals(3, getLanguageLineItems().length);
+        assertLanguageLineWithToggleChecked(false, getLanguageLineItems()[0]!);
+        assertLanguageLineWithToggleChecked(true, getLanguageLineItems()[1]!);
+        assertLanguageLineWithToggleChecked(false, getLanguageLineItems()[2]!);
       });
 
       test('it toggles switch when language pref changes', async () => {
         enabledLangs = ['Italian', 'English (United States)'];
         setEnabledLanguages();
         assertTrue(isPositionedOnPage(languageMenu));
-        assertEquals(getLanguageLineItems().length, 3);
-        assertLanguageLineWithToggleChecked(getLanguageLineItems()[0]!, true);
-        assertLanguageLineWithToggleChecked(getLanguageLineItems()[1]!, true);
-        assertLanguageLineWithToggleChecked(getLanguageLineItems()[2]!, false);
+        assertEquals(3, getLanguageLineItems().length);
+        assertLanguageLineWithToggleChecked(true, getLanguageLineItems()[0]!);
+        assertLanguageLineWithToggleChecked(true, getLanguageLineItems()[1]!);
+        assertLanguageLineWithToggleChecked(false, getLanguageLineItems()[2]!);
       });
 
       test('it shows no notification initially', async () => {
         enabledLangs = ['Italian', 'English (United States)'];
         setEnabledLanguages();
-        assertEquals(getNotificationItems().length, 3);
-        assertLanguageNotification(getNotificationItems()[0]!, '');
-        assertLanguageNotification(getNotificationItems()[1]!, '');
-        assertLanguageNotification(getNotificationItems()[2]!, '');
+        assertEquals(3, getNotificationItems().length);
+        assertLanguageNotification('', getNotificationItems()[0]!);
+        assertLanguageNotification('', getNotificationItems()[1]!);
+        assertLanguageNotification('', getNotificationItems()[2]!);
       });
 
       test('it shows and hides downloading notification', async () => {
@@ -314,27 +316,27 @@
         languagesToNotificationMap['it'] =
             VoiceClientSideStatusCode.SENT_INSTALL_REQUEST;
         setNotificationForLanguage();
-        assertEquals(getNotificationItems().length, 3);
-        assertLanguageNotification(getNotificationItems()[0]!, '');
-        assertLanguageNotification(getNotificationItems()[1]!, '');
+        assertEquals(3, getNotificationItems().length);
+        assertLanguageNotification('', getNotificationItems()[0]!);
+        assertLanguageNotification('', getNotificationItems()[1]!);
         assertLanguageNotification(
-            getNotificationItems()[2]!, 'Downloading voices…');
+            'Downloading voices…', getNotificationItems()[2]!);
 
         languagesToNotificationMap['it'] =
             VoiceClientSideStatusCode.INSTALLED_AND_UNAVAILABLE;
         setNotificationForLanguage();
-        assertEquals(getNotificationItems().length, 3);
-        assertLanguageNotification(getNotificationItems()[0]!, '');
-        assertLanguageNotification(getNotificationItems()[1]!, '');
+        assertEquals(3, getNotificationItems().length);
+        assertLanguageNotification('', getNotificationItems()[0]!);
+        assertLanguageNotification('', getNotificationItems()[1]!);
         assertLanguageNotification(
-            getNotificationItems()[2]!, 'Downloading voices…');
+            'Downloading voices…', getNotificationItems()[2]!);
 
         languagesToNotificationMap['it'] = VoiceClientSideStatusCode.AVAILABLE;
         setNotificationForLanguage();
-        assertEquals(getNotificationItems().length, 3);
-        assertLanguageNotification(getNotificationItems()[0]!, '');
-        assertLanguageNotification(getNotificationItems()[1]!, '');
-        assertLanguageNotification(getNotificationItems()[2]!, '');
+        assertEquals(3, getNotificationItems().length);
+        assertLanguageNotification('', getNotificationItems()[0]!);
+        assertLanguageNotification('', getNotificationItems()[1]!);
+        assertLanguageNotification('', getNotificationItems()[2]!);
       });
 
       test('hides downloading notification after a reopen', async () => {
@@ -345,18 +347,18 @@
             VoiceClientSideStatusCode.SENT_INSTALL_REQUEST;
         setNotificationForLanguage();
 
-        assertEquals(getNotificationItems().length, 3);
-        assertLanguageNotification(getNotificationItems()[0]!, '');
-        assertLanguageNotification(getNotificationItems()[1]!, '');
+        assertEquals(3, getNotificationItems().length);
+        assertLanguageNotification('', getNotificationItems()[0]!);
+        assertLanguageNotification('', getNotificationItems()[1]!);
         assertLanguageNotification(
-            getNotificationItems()[2]!, 'Downloading voices…');
+            'Downloading voices…', getNotificationItems()[2]!);
 
         reopenLanguageMenu();
-        assertEquals(getNotificationItems().length, 3);
-        assertLanguageNotification(getNotificationItems()[0]!, '');
-        assertLanguageNotification(getNotificationItems()[1]!, '');
+        assertEquals(3, getNotificationItems().length);
+        assertLanguageNotification('', getNotificationItems()[0]!);
+        assertLanguageNotification('', getNotificationItems()[1]!);
         assertLanguageNotification(
-            getNotificationItems()[2]!, 'Downloading voices…');
+            'Downloading voices…', getNotificationItems()[2]!);
       });
 
       test('non-Google language does not show downloading notification', () => {
@@ -365,17 +367,17 @@
         setEnabledLanguages();
 
         availableVoices = [
-          {name: 'test voice 1', lang: 'en-us'} as SpeechSynthesisVoice,
-          {name: 'espeak voice', lang: 'es'} as SpeechSynthesisVoice,
+          createSpeechSynthesisVoice({name: 'test voice 1', lang: 'en-us'}),
+          createSpeechSynthesisVoice({name: 'espeak voice', lang: 'es'}),
         ];
         setAvailableVoices();
         languagesToNotificationMap['es'] =
             VoiceClientSideStatusCode.SENT_INSTALL_REQUEST;
         setNotificationForLanguage();
 
-        assertEquals(getNotificationItems().length, 2);
-        assertLanguageNotification(getNotificationItems()[0]!, '');
-        assertLanguageNotification(getNotificationItems()[1]!, '');
+        assertEquals(2, getNotificationItems().length);
+        assertLanguageNotification('', getNotificationItems()[0]!);
+        assertLanguageNotification('', getNotificationItems()[1]!);
       });
 
       test('shows generic error notification with internet', async () => {
@@ -384,11 +386,11 @@
         languagesToNotificationMap['it'] =
             VoiceClientSideStatusCode.ERROR_INSTALLING;
         setNotificationForLanguage();
-        assertEquals(getNotificationItems().length, 3);
-        assertLanguageNotification(getNotificationItems()[0]!, '');
-        assertLanguageNotification(getNotificationItems()[1]!, '');
+        assertEquals(3, getNotificationItems().length);
+        assertLanguageNotification('', getNotificationItems()[0]!);
+        assertLanguageNotification('', getNotificationItems()[1]!);
         assertLanguageNotification(
-            getNotificationItems()[2]!, 'Download failed');
+            'Download failed', getNotificationItems()[2]!);
       });
 
 
@@ -400,12 +402,12 @@
             languagesToNotificationMap['it'] =
                 VoiceClientSideStatusCode.INSTALL_ERROR_ALLOCATION;
             setNotificationForLanguage();
-            assertEquals(getNotificationItems().length, 3);
-            assertLanguageNotification(getNotificationItems()[0]!, '');
-            assertLanguageNotification(getNotificationItems()[1]!, '');
+            assertEquals(3, getNotificationItems().length);
+            assertLanguageNotification('', getNotificationItems()[0]!);
+            assertLanguageNotification('', getNotificationItems()[1]!);
             assertLanguageNotification(
-                getNotificationItems()[2]!,
-                'For higher quality voices, clear space on your device');
+                'For higher quality voices, clear space on your device',
+                getNotificationItems()[2]!);
           });
 
       test(
@@ -417,18 +419,18 @@
                 VoiceClientSideStatusCode.INSTALL_ERROR_ALLOCATION;
             setNotificationForLanguage();
 
-            assertEquals(getNotificationItems().length, 3);
-            assertLanguageNotification(getNotificationItems()[0]!, '');
-            assertLanguageNotification(getNotificationItems()[1]!, '');
+            assertEquals(3, getNotificationItems().length);
+            assertLanguageNotification('', getNotificationItems()[0]!);
+            assertLanguageNotification('', getNotificationItems()[1]!);
             assertLanguageNotification(
-                getNotificationItems()[2]!,
-                'For higher quality voices, clear space on your device');
+                'For higher quality voices, clear space on your device',
+                getNotificationItems()[2]!);
 
             reopenLanguageMenu();
-            assertEquals(getNotificationItems().length, 3);
-            assertLanguageNotification(getNotificationItems()[0]!, '');
-            assertLanguageNotification(getNotificationItems()[1]!, '');
-            assertLanguageNotification(getNotificationItems()[2]!, '');
+            assertEquals(3, getNotificationItems().length);
+            assertLanguageNotification('', getNotificationItems()[0]!);
+            assertLanguageNotification('', getNotificationItems()[1]!);
+            assertLanguageNotification('', getNotificationItems()[2]!);
           });
 
       test('with no voices it shows allocation notification ', async () => {
@@ -438,7 +440,7 @@
         setEnabledLanguages();
 
         availableVoices =
-            [{name: 'test voice 1', lang: 'en-US'} as SpeechSynthesisVoice];
+            [createSpeechSynthesisVoice({name: 'test voice 1', lang: 'en-US'})];
         setAvailableVoices();
 
         languagesToNotificationMap['it'] =
@@ -455,14 +457,14 @@
             chrome.readingMode.isLanguagePackDownloadingEnabled;
         const notificationItemSize =
             areLanguagesWithUninstalledVoicesAvailable ? 3 : 1;
-        assertEquals(getNotificationItems().length, notificationItemSize);
-        assertLanguageNotification(getNotificationItems()[0]!, '');
+        assertEquals(notificationItemSize, getNotificationItems().length);
+        assertLanguageNotification('', getNotificationItems()[0]!);
 
         if (notificationItemSize > 1) {
-          assertLanguageNotification(getNotificationItems()[1]!, '');
+          assertLanguageNotification('', getNotificationItems()[1]!);
           assertLanguageNotification(
-              getNotificationItems()[2]!,
-              'To install this language, clear space on your device');
+              'To install this language, clear space on your device',
+              getNotificationItems()[2]!);
         }
       });
 
@@ -473,7 +475,7 @@
         setEnabledLanguages();
 
         availableVoices =
-            [{name: 'test voice 1', lang: 'en-US'} as SpeechSynthesisVoice];
+            [createSpeechSynthesisVoice({name: 'test voice 1', lang: 'en-US'})];
         setAvailableVoices();
 
         languagesToNotificationMap['it'] =
@@ -490,22 +492,22 @@
             chrome.readingMode.isLanguagePackDownloadingEnabled;
         const notificationItemSize =
             areLanguagesWithUninstalledVoicesAvailable ? 3 : 1;
-        assertEquals(getNotificationItems().length, notificationItemSize);
-        assertLanguageNotification(getNotificationItems()[0]!, '');
+        assertEquals(notificationItemSize, getNotificationItems().length);
+        assertLanguageNotification('', getNotificationItems()[0]!);
 
         if (notificationItemSize > 1) {
-          assertLanguageNotification(getNotificationItems()[1]!, '');
+          assertLanguageNotification('', getNotificationItems()[1]!);
           assertLanguageNotification(
-              getNotificationItems()[2]!,
-              'To install this language, clear space on your device');
+              'To install this language, clear space on your device',
+              getNotificationItems()[2]!);
         }
 
         reopenLanguageMenu();
 
         // Assert that the notification has cleared.
         if (notificationItemSize > 1) {
-          assertLanguageNotification(getNotificationItems()[1]!, '');
-          assertLanguageNotification(getNotificationItems()[2]!, '');
+          assertLanguageNotification('', getNotificationItems()[1]!);
+          assertLanguageNotification('', getNotificationItems()[2]!);
         }
       });
 
@@ -514,15 +516,15 @@
           getLanguageSearchField().value = 'test';
           await getLanguageSearchField().updateComplete;
           assertTrue(isPositionedOnPage(languageMenu));
-          assertEquals(getLanguageLineItems().length, 0);
+          assertEquals(0, getLanguageLineItems().length);
         });
 
         test('it displays matching language with a match', async () => {
           getLanguageSearchField().value = 'italian';
           await getLanguageSearchField().updateComplete;
-          assertEquals(getLanguageLineItems().length, 1);
+          assertEquals(1, getLanguageLineItems().length);
           assertLanguageLineWithTextAndSwitch(
-              getLanguageLineItems()[0]!, 'Italian');
+              'Italian', getLanguageLineItems()[0]!);
         });
       });
     });
@@ -531,12 +533,12 @@
   suite('with multiple voices for the same language', () => {
     setup(() => {
       availableVoices = [
-        {name: 'test voice 0', lang: 'en-US'} as SpeechSynthesisVoice,
-        {name: 'test voice 1', lang: 'en-US'} as SpeechSynthesisVoice,
-        {name: 'test voice 2', lang: 'en-UK'} as SpeechSynthesisVoice,
-        {name: 'test voice 3', lang: 'en-UK'} as SpeechSynthesisVoice,
-        {name: 'test voice 4', lang: 'it-IT'} as SpeechSynthesisVoice,
-        {name: 'test voice 5', lang: 'zh-CN'} as SpeechSynthesisVoice,
+        createSpeechSynthesisVoice({name: 'test voice 0', lang: 'en-US'}),
+        createSpeechSynthesisVoice({name: 'test voice 1', lang: 'en-US'}),
+        createSpeechSynthesisVoice({name: 'test voice 2', lang: 'en-UK'}),
+        createSpeechSynthesisVoice({name: 'test voice 3', lang: 'en-UK'}),
+        createSpeechSynthesisVoice({name: 'test voice 4', lang: 'it-IT'}),
+        createSpeechSynthesisVoice({name: 'test voice 5', lang: 'zh-CN'}),
       ];
       setAvailableVoices();
       languageMenu.showDialog();
@@ -544,11 +546,11 @@
 
     test('only shows one line per unique language name', () => {
       assertTrue(isPositionedOnPage(languageMenu));
-      assertEquals(getLanguageLineItems().length, 4);
-      assertLanguageLineWithTextAndSwitch(getLanguageLineItems()[0]!, 'en-UK');
-      assertLanguageLineWithTextAndSwitch(getLanguageLineItems()[1]!, 'en-US');
-      assertLanguageLineWithTextAndSwitch(getLanguageLineItems()[2]!, 'it-IT');
-      assertLanguageLineWithTextAndSwitch(getLanguageLineItems()[3]!, 'zh-CN');
+      assertEquals(4, getLanguageLineItems().length);
+      assertLanguageLineWithTextAndSwitch('en-UK', getLanguageLineItems()[0]!);
+      assertLanguageLineWithTextAndSwitch('en-US', getLanguageLineItems()[1]!);
+      assertLanguageLineWithTextAndSwitch('it-IT', getLanguageLineItems()[2]!);
+      assertLanguageLineWithTextAndSwitch('zh-CN', getLanguageLineItems()[3]!);
     });
 
     suite('with display names for locales', () => {
@@ -565,16 +567,16 @@
       test('it displays the display name', () => {
         flush();
         assertTrue(isPositionedOnPage(languageMenu));
-        assertEquals(getLanguageLineItems().length, 4);
+        assertEquals(4, getLanguageLineItems().length);
         assertLanguageLineWithTextAndSwitch(
-            getLanguageLineItems()[0]!, 'Chinese');
+            'Chinese', getLanguageLineItems()[0]!);
         assertLanguageLineWithTextAndSwitch(
-            getLanguageLineItems()[1]!, 'English (United Kingdom)');
+            'English (United Kingdom)', getLanguageLineItems()[1]!);
         assertLanguageLineWithTextAndSwitch(
-            getLanguageLineItems()[2]!, 'English (United States)');
+            'English (United States)', getLanguageLineItems()[2]!);
         assertLanguageLineWithTextAndSwitch(
-            getLanguageLineItems()[3]!, 'Italian');
-        assertEquals(getLanguageSearchField().value, '');
+            'Italian', getLanguageLineItems()[3]!);
+        assertEquals('', getLanguageSearchField().value);
       });
 
       suite('with search input', () => {
@@ -582,15 +584,15 @@
           getLanguageSearchField().value = 'test';
           await getLanguageSearchField().updateComplete;
           assertTrue(isPositionedOnPage(languageMenu));
-          assertEquals(getLanguageLineItems().length, 0);
+          assertEquals(0, getLanguageLineItems().length);
         });
 
         test('it displays matching language with a match', async () => {
           getLanguageSearchField().value = 'chin';
           await getLanguageSearchField().updateComplete;
-          assertEquals(getLanguageLineItems().length, 1);
+          assertEquals(1, getLanguageLineItems().length);
           assertLanguageLineWithTextAndSwitch(
-              getLanguageLineItems()[0]!, 'Chinese');
+              'Chinese', getLanguageLineItems()[0]!);
         });
       });
     });
@@ -604,14 +606,14 @@
 }
 
 function assertLanguageLineWithTextAndSwitch(
-    element: HTMLElement, expectedText: string) {
+    expectedText: string, element: HTMLElement) {
   assertEquals(expectedText, element.textContent!.trim());
   assertEquals(2, element.children.length);
   assertEquals('CR-TOGGLE', element.children[1]!.tagName);
 }
 
 async function assertLanguageLineWithToggleChecked(
-    element: HTMLElement, expectedChecked: boolean) {
+    expectedChecked: boolean, element: HTMLElement) {
   const toggle: CrToggleElement = (element.querySelector('cr-toggle'))!;
   await toggle.updateComplete;
   if (expectedChecked) {
@@ -626,6 +628,6 @@
 }
 
 function assertLanguageNotification(
-    element: HTMLElement, expectedNotification: string) {
-  assertEquals(element.innerText, expectedNotification);
+    expectedNotification: string, element: HTMLElement) {
+  assertEquals(expectedNotification, element.innerText);
 }
diff --git a/chrome/test/data/webui/side_panel/read_anything/letter_spacing_test.ts b/chrome/test/data/webui/side_panel/read_anything/letter_spacing_test.ts
index e9fd25be..e204465 100644
--- a/chrome/test/data/webui/side_panel/read_anything/letter_spacing_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/letter_spacing_test.ts
@@ -55,13 +55,13 @@
     });
 
     test('has 3 options', () => {
-      assertEquals(letterSpacingMenuOptions.length, 3);
+      assertEquals(3, letterSpacingMenuOptions.length);
     });
 
     test('first option propagates standard spacing', () => {
       letterSpacingMenuOptions[0]!.click();
 
-      assertEquals(spacingEmitted, chrome.readingMode.standardLetterSpacing);
+      assertEquals(chrome.readingMode.standardLetterSpacing, spacingEmitted);
       assertEquals(
           chrome.readingMode.letterSpacing,
           chrome.readingMode.standardLetterSpacing);
@@ -70,7 +70,7 @@
     test('second option propagates wide spacing', () => {
       letterSpacingMenuOptions[1]!.click();
 
-      assertEquals(spacingEmitted, chrome.readingMode.wideLetterSpacing);
+      assertEquals(chrome.readingMode.wideLetterSpacing, spacingEmitted);
       assertEquals(
           chrome.readingMode.letterSpacing,
           chrome.readingMode.wideLetterSpacing);
@@ -79,7 +79,7 @@
     test('third option propagates very wide spacing', () => {
       letterSpacingMenuOptions[2]!.click();
 
-      assertEquals(spacingEmitted, chrome.readingMode.veryWideLetterSpacing);
+      assertEquals(chrome.readingMode.veryWideLetterSpacing, spacingEmitted);
       assertEquals(
           chrome.readingMode.letterSpacing,
           chrome.readingMode.veryWideLetterSpacing);
diff --git a/chrome/test/data/webui/side_panel/read_anything/line_spacing_test.ts b/chrome/test/data/webui/side_panel/read_anything/line_spacing_test.ts
index ff6e28a..2bde6ff 100644
--- a/chrome/test/data/webui/side_panel/read_anything/line_spacing_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/line_spacing_test.ts
@@ -55,13 +55,13 @@
     });
 
     test('has 3 options', () => {
-      assertEquals(lineSpacingMenuOptions.length, 3);
+      assertEquals(3, lineSpacingMenuOptions.length);
     });
 
     test('first option propagates standard spacing', () => {
       lineSpacingMenuOptions[0]!.click();
 
-      assertEquals(spacingEmitted, chrome.readingMode.standardLineSpacing);
+      assertEquals(chrome.readingMode.standardLineSpacing, spacingEmitted);
       assertEquals(
           chrome.readingMode.lineSpacing,
           chrome.readingMode.standardLineSpacing);
@@ -70,15 +70,15 @@
     test('second option propagates loose spacing', () => {
       lineSpacingMenuOptions[1]!.click();
 
-      assertEquals(spacingEmitted, chrome.readingMode.looseLineSpacing);
+      assertEquals(chrome.readingMode.looseLineSpacing, spacingEmitted);
       assertEquals(
-          chrome.readingMode.lineSpacing, chrome.readingMode.looseLineSpacing);
+          chrome.readingMode.looseLineSpacing, chrome.readingMode.lineSpacing);
     });
 
     test('third option propagates very loose spacing', () => {
       lineSpacingMenuOptions[2]!.click();
 
-      assertEquals(spacingEmitted, chrome.readingMode.veryLooseLineSpacing);
+      assertEquals(chrome.readingMode.veryLooseLineSpacing, spacingEmitted);
       assertEquals(
           chrome.readingMode.lineSpacing,
           chrome.readingMode.veryLooseLineSpacing);
diff --git a/chrome/test/data/webui/side_panel/read_anything/links_toggle_button_test.ts b/chrome/test/data/webui/side_panel/read_anything/links_toggle_button_test.ts
index 9376d00..98b52878 100644
--- a/chrome/test/data/webui/side_panel/read_anything/links_toggle_button_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/links_toggle_button_test.ts
@@ -57,7 +57,7 @@
 
     test('links are turned off', () => {
       assertEquals(LINKS_DISABLED_ICON, menuButton.ironIcon);
-      assertEquals(chrome.readingMode.linksEnabled, false);
+      assertFalse(chrome.readingMode.linksEnabled);
       assertStringContains('enable links', menuButton.title.toLowerCase());
     });
 
diff --git a/chrome/test/data/webui/side_panel/read_anything/links_toggled_integration.ts b/chrome/test/data/webui/side_panel/read_anything/links_toggled_integration.ts
index fd4605b..b709131 100644
--- a/chrome/test/data/webui/side_panel/read_anything/links_toggled_integration.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/links_toggled_integration.ts
@@ -9,7 +9,7 @@
 import {LINK_TOGGLE_BUTTON_ID, NEXT_GRANULARITY_EVENT} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome-untrusted://webui-test/chai_assert.js';
 
-import {emitEvent, suppressInnocuousErrors} from './common.js';
+import {createSpeechSynthesisVoice, emitEvent, suppressInnocuousErrors} from './common.js';
 
 suite('LinksToggledIntegration', () => {
   let app: ReadAnythingElement;
@@ -59,7 +59,7 @@
 
   function assertContainerHasLinks(hasLinks: boolean) {
     const innerHTML = app.$.container.innerHTML;
-    assertEquals(innerHTML.includes('a href'), hasLinks);
+    assertEquals(hasLinks, innerHTML.includes('a href'));
   }
 
   setup(() => {
@@ -82,7 +82,8 @@
             '#play-pause')!;
     chrome.readingMode.setContentForTesting(axTree, [2, 4]);
     app.enabledLangs = ['en-US'];
-    app.selectedVoice = {lang: 'en', name: 'Kristi'} as SpeechSynthesisVoice;
+    app.selectedVoice =
+        createSpeechSynthesisVoice({lang: 'en', name: 'Kristi'});
     app.getSpeechSynthesisVoice();
 
     // No need to attempt to log a speech session in tests.
diff --git a/chrome/test/data/webui/side_panel/read_anything/prefs_test.ts b/chrome/test/data/webui/side_panel/read_anything/prefs_test.ts
index ef81624..821290f 100644
--- a/chrome/test/data/webui/side_panel/read_anything/prefs_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/prefs_test.ts
@@ -7,7 +7,7 @@
 import type {ReadAnythingElement} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js';
 import {assertArrayEquals, assertEquals, assertTrue} from 'chrome-untrusted://webui-test/chai_assert.js';
 
-import {suppressInnocuousErrors} from './common.js';
+import {createSpeechSynthesisVoice, suppressInnocuousErrors} from './common.js';
 import {FakeReadingMode} from './fake_reading_mode.js';
 import {TestColorUpdaterBrowserProxy} from './test_color_updater_browser_proxy.js';
 
@@ -87,23 +87,24 @@
       const lang2 = 'tr';
       const langWithNoVoices = 'elvish';
 
-      const defaultVoice = {
+      const defaultVoice = createSpeechSynthesisVoice({
         lang: langForDefaultVoice,
         name: 'Kristi',
         default: true,
-      } as SpeechSynthesisVoice;
-      const firstVoiceWithLang1 = {lang: lang1, name: 'Lauren'} as
-          SpeechSynthesisVoice;
-      const defaultVoiceWithLang1 = {
+      });
+      const firstVoiceWithLang1 =
+          createSpeechSynthesisVoice({lang: lang1, name: 'Lauren'});
+      const defaultVoiceWithLang1 = createSpeechSynthesisVoice({
         lang: lang1,
         name: 'Eitan',
         default: true,
-      } as SpeechSynthesisVoice;
-      const firstVoiceWithLang2 = {lang: lang2, name: 'Yu'} as
-          SpeechSynthesisVoice;
-      const secondVoiceWithLang2 = {lang: lang2, name: 'Xiang'} as
-          SpeechSynthesisVoice;
-      const otherVoice = {lang: 'it', name: 'Shari'} as SpeechSynthesisVoice;
+      });
+      const firstVoiceWithLang2 =
+          createSpeechSynthesisVoice({lang: lang2, name: 'Yu'});
+      const secondVoiceWithLang2 =
+          createSpeechSynthesisVoice({lang: lang2, name: 'Xiang'});
+      const otherVoice =
+          createSpeechSynthesisVoice({lang: 'it', name: 'Shari'});
       const voices = [
         defaultVoice,
         firstVoiceWithLang1,
@@ -121,14 +122,14 @@
       test('to the stored voice for this language if there is one', () => {
         chrome.readingMode.getStoredVoice = () => otherVoice.name;
         app.restoreSettingsFromPrefs();
-        assertEquals(app.selectedVoice, otherVoice);
+        assertEquals(otherVoice, app.selectedVoice);
       });
 
       test('to a default voice if the stored voice is invalid', () => {
         chrome.readingMode.getStoredVoice = () => 'Matt';
         app.enabledLangs = [langForDefaultVoice];
         app.restoreSettingsFromPrefs();
-        assertEquals(app.selectedVoice, defaultVoice);
+        assertEquals(defaultVoice, app.selectedVoice);
       });
 
       suite('when there is no stored voice for this language', () => {
@@ -145,13 +146,13 @@
             app.selectedVoice = otherVoice;
             app.enabledLangs = [otherVoice.lang];
             app.restoreSettingsFromPrefs();
-            assertEquals(app.selectedVoice, otherVoice);
+            assertEquals(otherVoice, app.selectedVoice);
           });
 
           test('to the device default if there\'s no current voice', () => {
             app.enabledLangs = [langForDefaultVoice, otherVoice.lang];
             app.restoreSettingsFromPrefs();
-            assertEquals(app.selectedVoice, defaultVoice);
+            assertEquals(defaultVoice, app.selectedVoice);
           });
         });
 
@@ -159,7 +160,7 @@
           app.enabledLangs = [lang1];
           app.speechSynthesisLanguage = lang1;
           app.restoreSettingsFromPrefs();
-          assertEquals(app.selectedVoice, defaultVoiceWithLang1);
+          assertEquals(defaultVoiceWithLang1, app.selectedVoice);
         });
 
         test(
@@ -170,8 +171,8 @@
               app.restoreSettingsFromPrefs();
               const currentSelectedVoice = app.selectedVoice;
               assertTrue(!!currentSelectedVoice);
-              assertEquals(currentSelectedVoice.name, firstVoiceWithLang2.name);
-              assertEquals(currentSelectedVoice.lang, firstVoiceWithLang2.lang);
+              assertEquals(firstVoiceWithLang2.name, currentSelectedVoice.name);
+              assertEquals(firstVoiceWithLang2.lang, currentSelectedVoice.lang);
             });
       });
     });
diff --git a/chrome/test/data/webui/side_panel/read_anything/rate_selection_test.ts b/chrome/test/data/webui/side_panel/read_anything/rate_selection_test.ts
index 7694aae..301d0e92 100644
--- a/chrome/test/data/webui/side_panel/read_anything/rate_selection_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/rate_selection_test.ts
@@ -42,8 +42,8 @@
 
   suite('by default', () => {
     test('uses 1x', () => {
-      assertEquals(rateButton.ironIcon, 'voice-rate:1');
-      assertEquals(chrome.readingMode.speechRate, 1);
+      assertEquals('voice-rate:1', rateButton.ironIcon);
+      assertEquals(1, chrome.readingMode.speechRate);
     });
 
     test('menu is not open', () => {
@@ -90,11 +90,11 @@
       menuOption.click();
 
       // updates rate
-      assertEquals(chrome.readingMode.speechRate, rateValue);
+      assertEquals(rateValue, chrome.readingMode.speechRate);
       assertTrue(rateEmitted);
 
       // updates icon on toolbar'
-      assertEquals(rateButton.ironIcon, 'voice-rate:' + rateValue);
+      assertEquals('voice-rate:' + rateValue, rateButton.ironIcon);
 
       // closes menu
       assertFalse(toolbar.$.rateMenu.get().open);
diff --git a/chrome/test/data/webui/side_panel/read_anything/read_aloud_highlighting_test.ts b/chrome/test/data/webui/side_panel/read_anything/read_aloud_highlighting_test.ts
index c71e8a7e..f98f4b9 100644
--- a/chrome/test/data/webui/side_panel/read_anything/read_aloud_highlighting_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/read_aloud_highlighting_test.ts
@@ -85,7 +85,7 @@
     });
 
     test('sentence is highlighted', () => {
-      assertEquals(currentHighlight!.textContent, sentence1);
+      assertEquals(sentence1, currentHighlight!.textContent);
     });
 
     test('no previous highlight', () => {
@@ -109,12 +109,12 @@
       previousHighlights =
           app.$.container.querySelectorAll('.previous-read-highlight');
 
-      assertEquals(previousHighlights.length, 2);
-      assertEquals(previousHighlights[0]!.textContent, sentence1);
-      assertEquals(previousHighlights[1]!.textContent, sentence2);
-      assertEquals(currentHighlights.length, 2);
-      assertEquals(currentHighlights[0]!.textContent, sentenceSegment1);
-      assertEquals(currentHighlights[1]!.textContent, sentenceSegment2);
+      assertEquals(2, previousHighlights.length);
+      assertEquals(sentence1, previousHighlights[0]!.textContent);
+      assertEquals(sentence2, previousHighlights[1]!.textContent);
+      assertEquals(2, currentHighlights.length);
+      assertEquals(sentenceSegment1, currentHighlights[0]!.textContent);
+      assertEquals(sentenceSegment2, currentHighlights[1]!.textContent);
     });
 
     test('going back after multiple segments resets all segments', () => {
@@ -125,10 +125,10 @@
       previousHighlights =
           app.$.container.querySelectorAll('.previous-read-highlight');
 
-      assertEquals(previousHighlights.length, 1);
-      assertEquals(previousHighlights[0]!.textContent, sentence1);
-      assertEquals(currentHighlights.length, 1);
-      assertEquals(currentHighlights[0]!.textContent, sentence2);
+      assertEquals(1, previousHighlights.length);
+      assertEquals(sentence1, previousHighlights[0]!.textContent);
+      assertEquals(1, currentHighlights.length);
+      assertEquals(sentence2, currentHighlights[0]!.textContent);
     });
   });
 
@@ -146,11 +146,11 @@
     });
 
     test('sentence is highlighted', () => {
-      assertEquals(currentHighlight!.textContent, sentence2);
+      assertEquals(sentence2, currentHighlight!.textContent);
     });
 
     test('previous sentence has highlight', () => {
-      assertEquals(previousHighlight!.textContent, sentence1);
+      assertEquals(sentence1, previousHighlight!.textContent);
     });
   });
 
@@ -172,13 +172,13 @@
 
     test('no highlights', () => {
       assertFalse(!!currentHighlight);
-      assertEquals(previousHighlights.length, 0);
+      assertEquals(0, previousHighlights.length);
     });
 
     test('text content is still there', () => {
       const expectedText =
           sentence1 + sentence2 + sentenceSegment1 + sentenceSegment2;
-      assertEquals(app.$.container.textContent, expectedText);
+      assertEquals(expectedText, app.$.container.textContent);
     });
 
     test('playing next granularity does not crash', () => {
@@ -203,11 +203,11 @@
     });
 
     test('previous sentence is now current', () => {
-      assertEquals(currentHighlight!.textContent, sentence1);
+      assertEquals(sentence1, currentHighlight!.textContent);
     });
 
     test('nothing marked previous', () => {
-      assertEquals(previousHighlights.length, 0);
+      assertEquals(0, previousHighlights.length);
     });
 
     test('going back before first sentence does not crash', () => {
@@ -221,7 +221,7 @@
       previousHighlights =
           app.$.container.querySelectorAll('.previous-read-highlight');
 
-      assertEquals(currentHighlight!.textContent, sentence1);
+      assertEquals(sentence1, currentHighlight!.textContent);
     });
 
     test('going forward after going back shows correct highlights', () => {
@@ -231,9 +231,9 @@
       previousHighlights =
           app.$.container.querySelectorAll('.previous-read-highlight');
 
-      assertEquals(currentHighlight!.textContent, sentence2);
-      assertEquals(previousHighlights.length, 1);
-      assertEquals(previousHighlights[0]!.textContent, sentence1);
+      assertEquals(sentence2, currentHighlight!.textContent);
+      assertEquals(1, previousHighlights.length);
+      assertEquals(sentence1, previousHighlights[0]!.textContent);
 
       emitNextGranularity();
       const currentHighlights =
@@ -241,12 +241,12 @@
       previousHighlights =
           app.$.container.querySelectorAll('.previous-read-highlight');
 
-      assertEquals(currentHighlights.length, 2);
-      assertEquals(currentHighlights[0]!.textContent, sentenceSegment1);
-      assertEquals(currentHighlights[1]!.textContent, sentenceSegment2);
-      assertEquals(previousHighlights.length, 2);
-      assertEquals(previousHighlights[0]!.textContent, sentence1);
-      assertEquals(previousHighlights[1]!.textContent, sentence2);
+      assertEquals(2, currentHighlights.length);
+      assertEquals(sentenceSegment1, currentHighlights[0]!.textContent);
+      assertEquals(sentenceSegment2, currentHighlights[1]!.textContent);
+      assertEquals(2, previousHighlights.length);
+      assertEquals(sentence1, previousHighlights[0]!.textContent);
+      assertEquals(sentence2, previousHighlights[1]!.textContent);
     });
   });
 
@@ -284,9 +284,9 @@
       previousHighlights =
           app.$.container.querySelectorAll('.previous-read-highlight');
 
-      assertEquals(currentHighlight!.textContent, sentence2);
-      assertEquals(previousHighlights!.length, 1);
-      assertEquals(previousHighlights![0]!.textContent, sentence1);
+      assertEquals(sentence2, currentHighlight!.textContent);
+      assertEquals(1, previousHighlights!.length);
+      assertEquals(sentence1, previousHighlights![0]!.textContent);
     });
 
     test('next granularity shows correct highlights', () => {
@@ -296,10 +296,10 @@
           app.$.container.querySelector('.current-read-highlight');
       previousHighlights =
           app.$.container.querySelectorAll('.previous-read-highlight');
-      assertEquals(currentHighlight!.textContent, sentenceSegment1);
-      assertEquals(previousHighlights!.length, 2);
-      assertEquals(previousHighlights![0]!.textContent, sentence1);
-      assertEquals(previousHighlights![1]!.textContent, sentence2);
+      assertEquals(sentenceSegment1, currentHighlight!.textContent);
+      assertEquals(2, previousHighlights!.length);
+      assertEquals(sentence1, previousHighlights![0]!.textContent);
+      assertEquals(sentence2, previousHighlights![1]!.textContent);
     });
 
     test('previous granularity shows correct highlights', () => {
@@ -309,8 +309,8 @@
           app.$.container.querySelector('.current-read-highlight');
       previousHighlights =
           app.$.container.querySelectorAll('.previous-read-highlight');
-      assertEquals(currentHighlight!.textContent, sentence1);
-      assertEquals(previousHighlights!.length, 0);
+      assertEquals(sentence1, currentHighlight!.textContent);
+      assertEquals(0, previousHighlights!.length);
     });
   });
 });
diff --git a/chrome/test/data/webui/side_panel/read_anything/read_aloud_update_content_selection.ts b/chrome/test/data/webui/side_panel/read_anything/read_aloud_update_content_selection.ts
index 177a235..36cd123 100644
--- a/chrome/test/data/webui/side_panel/read_anything/read_aloud_update_content_selection.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/read_aloud_update_content_selection.ts
@@ -103,7 +103,7 @@
       // The expected HTML before any highlights are added.
       const expected = '<div><p>World</p><p>Friend!</p></div>';
       const innerHTML = app.$.container.innerHTML;
-      assertEquals(innerHTML, expected);
+      assertEquals(expected, innerHTML);
     });
 
     test('selection in reading mode panel correct', () => {
@@ -111,17 +111,17 @@
       // so use a helper to get the selection from the app instead.
       const selection = document.getSelection()!;
       assertTrue(selection != null);
-      assertEquals(selection.anchorNode!.textContent, 'World');
-      assertEquals(selection.focusNode!.textContent, 'Friend');
-      assertEquals(selection.anchorOffset, 1);
-      assertEquals(selection.focusOffset, 2);
+      assertEquals('World', selection.anchorNode!.textContent);
+      assertEquals('Friend', selection.focusNode!.textContent);
+      assertEquals(1, selection.anchorOffset);
+      assertEquals(2, selection.focusOffset);
     });
 
     test('conbtainer class correct', () => {
       assertEquals(
           app.$.container.className,
           'user-select-disabled-when-speech-playing-false');
-      assertEquals(window.getComputedStyle(app.$.container).userSelect, 'auto');
+      assertEquals('auto', window.getComputedStyle(app.$.container).userSelect);
     });
   });
 
@@ -143,19 +143,19 @@
           '<span class="current-read-highlight">!</span>' +
           '</span></p></div>';
       const innerHTML = app.$.container.innerHTML;
-      assertEquals(innerHTML, expected);
+      assertEquals(expected, innerHTML);
     });
 
     test('selection in reading mode panel cleared', () => {
       const selection = document.getSelection()!;
-      assertEquals(selection.toString(), '');
+      assertEquals('', selection.toString());
     });
 
     test('container class correct', () => {
       assertEquals(
           app.$.container.className,
           'user-select-disabled-when-speech-playing-true');
-      assertEquals(window.getComputedStyle(app.$.container).userSelect, 'none');
+      assertEquals('none', window.getComputedStyle(app.$.container).userSelect);
     });
   });
 
@@ -176,19 +176,19 @@
           '<span class="current-read-highlight">!</span>' +
           '</span></p></div>';
       const innerHTML = app.$.container.innerHTML;
-      assertEquals(innerHTML, expected);
+      assertEquals(expected, innerHTML);
     });
 
     test('selection in reading mode panel cleared', () => {
       const selection = document.getSelection()!;
-      assertEquals(selection.toString(), '');
+      assertEquals('', selection.toString());
     });
 
     test('container class correct', () => {
       assertEquals(
           app.$.container.className,
           'user-select-disabled-when-speech-playing-false');
-      assertEquals(window.getComputedStyle(app.$.container).userSelect, 'auto');
+      assertEquals('auto', window.getComputedStyle(app.$.container).userSelect);
     });
   });
 });
diff --git a/chrome/test/data/webui/side_panel/read_anything/read_aloud_update_content_selection_pdf.ts b/chrome/test/data/webui/side_panel/read_anything/read_aloud_update_content_selection_pdf.ts
index d14147ee..a9209f1 100644
--- a/chrome/test/data/webui/side_panel/read_anything/read_aloud_update_content_selection_pdf.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/read_aloud_update_content_selection_pdf.ts
@@ -106,7 +106,7 @@
       // The expected HTML before any highlights are added.
       const expected = '<div><p>World</p><p>Friend!</p></div>';
       const innerHTML = app.$.container.innerHTML;
-      assertEquals(innerHTML, expected);
+      assertEquals(expected, innerHTML);
     });
 
     test('selection in reading mode panel correct', () => {
@@ -114,17 +114,17 @@
       // so use a helper to get the selection from the app instead.
       const selection = document.getSelection()!;
       assertTrue(selection != null);
-      assertEquals(selection.anchorNode!.textContent, 'World');
-      assertEquals(selection.focusNode!.textContent, 'Friend');
-      assertEquals(selection.anchorOffset, 1);
-      assertEquals(selection.focusOffset, 2);
+      assertEquals('World', selection.anchorNode!.textContent);
+      assertEquals('Friend', selection.focusNode!.textContent);
+      assertEquals(1, selection.anchorOffset);
+      assertEquals(2, selection.focusOffset);
     });
 
     test('container class correct', () => {
       assertEquals(
           app.$.container.className,
           'user-select-disabled-when-speech-playing-false');
-      assertEquals(window.getComputedStyle(app.$.container).userSelect, 'auto');
+      assertEquals('auto', window.getComputedStyle(app.$.container).userSelect);
     });
   });
 
@@ -146,19 +146,19 @@
           '<span class="current-read-highlight">!</span>' +
           '</span></p></div>';
       const innerHTML = app.$.container.innerHTML;
-      assertEquals(innerHTML, expected);
+      assertEquals(expected, innerHTML);
     });
 
     test('selection in reading mode panel cleared', () => {
       const selection = document.getSelection()!;
-      assertEquals(selection.toString(), '');
+      assertEquals('', selection.toString());
     });
 
     test('container class correct', () => {
       assertEquals(
           app.$.container.className,
           'user-select-disabled-when-speech-playing-true');
-      assertEquals(window.getComputedStyle(app.$.container).userSelect, 'none');
+      assertEquals('none', window.getComputedStyle(app.$.container).userSelect);
     });
   });
 
@@ -179,19 +179,19 @@
           '<span class="current-read-highlight">!</span>' +
           '</span></p></div>';
       const innerHTML = app.$.container.innerHTML;
-      assertEquals(innerHTML, expected);
+      assertEquals(expected, innerHTML);
     });
 
     test('selection in reading mode panel cleared', () => {
       const selection = document.getSelection()!;
-      assertEquals(selection.toString(), '');
+      assertEquals('', selection.toString());
     });
 
     test('container class correct', () => {
       assertEquals(
           app.$.container.className,
           'user-select-disabled-when-speech-playing-false');
-      assertEquals(window.getComputedStyle(app.$.container).userSelect, 'auto');
+      assertEquals('auto', window.getComputedStyle(app.$.container).userSelect);
     });
   });
 });
diff --git a/chrome/test/data/webui/side_panel/read_anything/read_anything_browsertest.cc b/chrome/test/data/webui/side_panel/read_anything/read_anything_browsertest.cc
index ea541bc..e5b2738 100644
--- a/chrome/test/data/webui/side_panel/read_anything/read_anything_browsertest.cc
+++ b/chrome/test/data/webui/side_panel/read_anything/read_anything_browsertest.cc
@@ -67,11 +67,6 @@
                    "mocha.run()");
 }
 
-IN_PROC_BROWSER_TEST_F(ReadAnythingMochaTest, WebUiToolbarFlag) {
-  RunSidePanelTest("side_panel/read_anything/toolbar_flag_test.js",
-                   "mocha.run()");
-}
-
 IN_PROC_BROWSER_TEST_F(ReadAnythingMochaTest, FontSize) {
   RunSidePanelTest("side_panel/read_anything/font_size_test.js", "mocha.run()");
 }
diff --git a/chrome/test/data/webui/side_panel/read_anything/speech_test.ts b/chrome/test/data/webui/side_panel/read_anything/speech_test.ts
index 3a47030..e428fcc58e 100644
--- a/chrome/test/data/webui/side_panel/read_anything/speech_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/speech_test.ts
@@ -7,7 +7,7 @@
 import {NEXT_GRANULARITY_EVENT, PauseActionSource, PREVIOUS_GRANULARITY_EVENT, RATE_EVENT, WordBoundaryMode} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js';
 import {assertEquals, assertFalse, assertGT, assertTrue} from 'chrome-untrusted://webui-test/chai_assert.js';
 
-import {emitEvent, suppressInnocuousErrors, waitForPlayFromSelection} from './common.js';
+import {createSpeechSynthesisVoice, emitEvent, suppressInnocuousErrors, waitForPlayFromSelection} from './common.js';
 import {FakeSpeechSynthesis} from './fake_speech_synthesis.js';
 
 // TODO: b/323960128 - Add tests for word boundaries here or in a
@@ -99,7 +99,7 @@
     });
 
     test('speaks all text by sentences', () => {
-      assertEquals(speechSynthesis.spokenUtterances.length, totalSentences);
+      assertEquals(totalSentences, speechSynthesis.spokenUtterances.length);
       const utteranceTexts = getSpokenTexts();
       assertTrue(
           paragraph1.every(sentence => utteranceTexts.includes(sentence)));
@@ -164,14 +164,14 @@
       await selectAndPlay(axTree, 5, 0, 5, 7);
 
       const utteranceTexts = getSpokenTexts();
-      assertEquals(utteranceTexts.length, totalSentences - paragraph1.length);
+      assertEquals(totalSentences - paragraph1.length, utteranceTexts.length);
       assertTrue(
           paragraph2.every(sentence => utteranceTexts.includes(sentence)));
     });
 
     test('selection is cleared after play', async () => {
       await selectAndPlay(axTree, 5, 0, 5, 10);
-      assertEquals(app.getSelection().type, 'None');
+      assertEquals('None', app.getSelection().type);
     });
 
     test(
@@ -181,7 +181,7 @@
 
           const utteranceTexts = getSpokenTexts();
           assertEquals(
-              utteranceTexts.length, totalSentences - paragraph1.length);
+              totalSentences - paragraph1.length, utteranceTexts.length);
           assertTrue(
               paragraph2.every(sentence => utteranceTexts.includes(sentence)));
         });
@@ -190,7 +190,7 @@
       await selectAndPlay(axTree, 3, 10, 5, 10);
 
       const utteranceTexts = getSpokenTexts();
-      assertEquals(utteranceTexts.length, totalSentences);
+      assertEquals(totalSentences, utteranceTexts.length);
       assertTrue(
           paragraph1.every(sentence => utteranceTexts.includes(sentence)));
       assertTrue(
@@ -201,7 +201,7 @@
       await selectAndPlay(axTree, 5, 10, 3, 10, /*isBackward=*/ true);
 
       const utteranceTexts = getSpokenTexts();
-      assertEquals(utteranceTexts.length, totalSentences);
+      assertEquals(totalSentences, utteranceTexts.length);
       assertTrue(
           paragraph1.every(sentence => utteranceTexts.includes(sentence)));
       assertTrue(
@@ -218,7 +218,7 @@
           assertTrue(speechSynthesis.canceled);
           const utteranceTexts = getSpokenTexts();
           assertEquals(
-              utteranceTexts.length, totalSentences - paragraph1.length);
+              totalSentences - paragraph1.length, utteranceTexts.length);
           assertTrue(
               paragraph2.every(sentence => utteranceTexts.includes(sentence)));
         });
@@ -269,7 +269,7 @@
       const utteranceTexts = getSpokenTexts();
       // We shouldn't speak fragment2 even though it's in the same node
       // because the selection only covers fragment 3.
-      assertEquals(utteranceTexts.length, 1);
+      assertEquals(1, utteranceTexts.length);
       assertTrue(utteranceTexts.includes(fragment3));
     });
   });
@@ -317,7 +317,7 @@
 
     emitEvent(app, NEXT_GRANULARITY_EVENT);
 
-    assertEquals(speechSynthesis.spokenUtterances.length, expectedNumSentences);
+    assertEquals(expectedNumSentences, speechSynthesis.spokenUtterances.length);
     const utteranceTexts = getSpokenTexts();
     assertFalse(utteranceTexts.includes(paragraph1[0]!));
     assertTrue(paragraph2.every(sentence => utteranceTexts.includes(sentence)));
@@ -330,8 +330,8 @@
 
     emitEvent(app, PREVIOUS_GRANULARITY_EVENT);
 
-    assertEquals(speechSynthesis.spokenUtterances.length, 1);
-    assertEquals(speechSynthesis.spokenUtterances[0]!.text, paragraph2.at(-1)!);
+    assertEquals(1, speechSynthesis.spokenUtterances.length);
+    assertEquals(paragraph2.at(-1)!, speechSynthesis.spokenUtterances[0]!.text);
   });
 
 
@@ -382,11 +382,11 @@
       app.playSpeech();
 
       assertEquals(
-          speechSynthesis.spokenUtterances.length, expectedNumSegments);
+          expectedNumSegments, speechSynthesis.spokenUtterances.length);
       const spoken =
           speechSynthesis.spokenUtterances.map(utterance => utterance.text)
               .join('');
-      assertEquals(spoken, longSentences);
+      assertEquals(longSentences, spoken);
     });
 
     test('on text-too-long error smaller text segment plays', () => {
@@ -404,7 +404,7 @@
       assertFalse(speechSynthesis.speaking);
       assertTrue(speechSynthesis.canceled);
       assertFalse(speechSynthesis.paused);
-      assertEquals(speechSynthesis.spokenUtterances.length, 3);
+      assertEquals(3, speechSynthesis.spokenUtterances.length);
 
       // The first utterance should contain the entire text, but it should
       // be canceled. The second utterance should be the smaller text
@@ -412,17 +412,17 @@
       // should be the remaining text, as there is no longer a text-too-long
       // error triggered.
       const accessibleTextLength = app.getAccessibleTextLength(longSentences);
-      assertEquals(speechSynthesis.spokenUtterances[0]!.text, longSentences);
+      assertEquals(longSentences, speechSynthesis.spokenUtterances[0]!.text);
       assertEquals(
-          speechSynthesis.spokenUtterances[1]!.text,
-          longSentences.substring(0, accessibleTextLength));
+          longSentences.substring(0, accessibleTextLength),
+          speechSynthesis.spokenUtterances[1]!.text);
       assertEquals(
-          speechSynthesis.spokenUtterances[2]!.text,
-          longSentences.substring(accessibleTextLength));
-      assertEquals(speechSynthesis.canceledUtterances.length, 1);
+          longSentences.substring(accessibleTextLength),
+          speechSynthesis.spokenUtterances[2]!.text);
+      assertEquals(1, speechSynthesis.canceledUtterances.length);
       assertEquals(
-          speechSynthesis.canceledUtterances[0]!,
-          speechSynthesis.spokenUtterances[0]!);
+          speechSynthesis.spokenUtterances[0]!,
+          speechSynthesis.canceledUtterances[0]!);
     });
   });
 
@@ -508,7 +508,8 @@
       test('cancels and selects default voice', () => {
         emitEvent(app, 'select-voice', {
           detail: {
-            selectedVoice: {lang: 'en', name: 'Lisie'} as SpeechSynthesisVoice,
+            selectedVoice:
+                createSpeechSynthesisVoice({lang: 'en', name: 'Lisie'}),
           },
         });
 
@@ -529,8 +530,8 @@
             chrome.readingMode.setLanguageForTesting('en');
             emitEvent(app, 'select-voice', {
               detail: {
-                selectedVoice: {lang: 'en', name: 'Lauren', default:true} as
-                    SpeechSynthesisVoice,
+                selectedVoice: createSpeechSynthesisVoice(
+                    {lang: 'en', name: 'Lauren', default: true}),
               },
             });
 
@@ -552,8 +553,8 @@
 
             emitEvent(app, 'select-voice', {
               detail: {
-                selectedVoice: {lang: 'en', name: 'Lauren'} as
-                    SpeechSynthesisVoice,
+                selectedVoice:
+                    createSpeechSynthesisVoice({lang: 'en', name: 'Lauren'}),
               },
             });
 
@@ -578,14 +579,15 @@
         };
         emitEvent(app, 'select-voice', {
           detail: {
-            selectedVoice: {lang: 'en', name: 'Lisie'} as SpeechSynthesisVoice,
+            selectedVoice:
+                createSpeechSynthesisVoice({lang: 'en', name: 'Lisie'}),
           },
         });
 
         assertFalse(speechSynthesis.speaking);
         assertTrue(speechSynthesis.canceled);
         assertFalse(speechSynthesis.paused);
-        assertEquals(speechRate, 1);
+        assertEquals(1, speechRate);
       });
     });
 
@@ -598,7 +600,7 @@
         assertTrue(speechSynthesis.canceled, 'canceled');
         assertTrue(speechSynthesis.speaking, 'speaking');
         assertFalse(speechSynthesis.paused, 'paused');
-        assertEquals(speechSynthesis.spokenUtterances.length, 1);
+        assertEquals(1, speechSynthesis.spokenUtterances.length);
       });
 
       test('then resumes speech after voice menu is closed', () => {
@@ -610,7 +612,7 @@
 
         assertTrue(speechSynthesis.canceled);
         assertFalse(speechSynthesis.paused);
-        assertEquals(speechSynthesis.spokenUtterances.length, totalSentences);
+        assertEquals(totalSentences, speechSynthesis.spokenUtterances.length);
       });
     });
   });
diff --git a/chrome/test/data/webui/side_panel/read_anything/speech_uses_max_text_length.ts b/chrome/test/data/webui/side_panel/read_anything/speech_uses_max_text_length.ts
index 07e2145..1f7f69f 100644
--- a/chrome/test/data/webui/side_panel/read_anything/speech_uses_max_text_length.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/speech_uses_max_text_length.ts
@@ -124,7 +124,7 @@
 
     test('first accessible text boundary is at last comma', () => {
       assertLT(firstBoundary, longSentenceWithFewCommas.length);
-      assertEquals(longSentenceWithFewCommas.lastIndexOf(','), firstBoundary);
+      assertEquals(firstBoundary, longSentenceWithFewCommas.lastIndexOf(','));
     });
 
     test('next accessible text boundary is before end of string', () => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/toolbar_flag_test.ts b/chrome/test/data/webui/side_panel/read_anything/toolbar_flag_test.ts
deleted file mode 100644
index 1523cea8..0000000
--- a/chrome/test/data/webui/side_panel/read_anything/toolbar_flag_test.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2024 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js';
-
-import {BrowserProxy} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js';
-import type {ReadAnythingElement} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js';
-import {assertFalse, assertTrue} from 'chrome-untrusted://webui-test/chai_assert.js';
-
-import {suppressInnocuousErrors} from './common.js';
-import {FakeReadingMode} from './fake_reading_mode.js';
-import {TestColorUpdaterBrowserProxy} from './test_color_updater_browser_proxy.js';
-
-// TODO: crbug.com/1474951 - Remove this test once WebUI flag is removed.
-suite('WebUiToolbarFlag', () => {
-  let app: ReadAnythingElement;
-  let testBrowserProxy: TestColorUpdaterBrowserProxy;
-
-  setup(() => {
-    suppressInnocuousErrors();
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
-    testBrowserProxy = new TestColorUpdaterBrowserProxy();
-    BrowserProxy.setInstance(testBrowserProxy);
-    const readingMode = new FakeReadingMode();
-    chrome.readingMode = readingMode as unknown as typeof chrome.readingMode;
-  });
-
-  function createApp(): void {
-    app = document.createElement('read-anything-app');
-    document.body.appendChild(app);
-  }
-
-  test('webUI toolbar is visible if enabled', () => {
-    chrome.readingMode.isWebUIToolbarVisible = true;
-    createApp();
-
-    const container = app.querySelector<HTMLElement>('#toolbar-container');
-
-    assertTrue(!!container);
-    assertFalse(container.hidden);
-  });
-
-  test('webUI toolbar is invisible if disabled', () => {
-    chrome.readingMode.isWebUIToolbarVisible = false;
-    createApp();
-
-    const container = app.querySelector<HTMLElement>('#toolbar-container');
-
-    assertTrue(!!container);
-    assertTrue(container.hidden);
-  });
-});
diff --git a/chrome/test/data/webui/side_panel/read_anything/toolbar_overflow_test.ts b/chrome/test/data/webui/side_panel/read_anything/toolbar_overflow_test.ts
index 75243911..bcb8c0d1 100644
--- a/chrome/test/data/webui/side_panel/read_anything/toolbar_overflow_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/toolbar_overflow_test.ts
@@ -51,7 +51,7 @@
       const moreOptionsButtons =
           toolbar.$.moreOptionsMenu.get().querySelectorAll<HTMLElement>(
               moreOptionsClass);
-      assertEquals(moreOptionsButtons.length, 0);
+      assertEquals(0, moreOptionsButtons.length);
     });
   });
 
@@ -71,18 +71,18 @@
       let numOverflow = 3;
       overflow(numOverflow);
       assertEquals(
+          numOverflow,
           toolbar.$.moreOptionsMenu.get()
               .querySelectorAll<HTMLElement>(moreOptionsClass)
-              .length,
-          numOverflow);
+              .length);
 
       numOverflow = 5;
       overflow(numOverflow);
       assertEquals(
+          numOverflow,
           toolbar.$.moreOptionsMenu.get()
               .querySelectorAll<HTMLElement>(moreOptionsClass)
-              .length,
-          numOverflow);
+              .length);
     });
   });
 });
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_selection.ts b/chrome/test/data/webui/side_panel/read_anything/update_content_selection.ts
index f92ebcd..00ad368e 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_selection.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_selection.ts
@@ -98,15 +98,15 @@
     test('InnerHtmlCorrect', () => {
       const expected = '<div><p>World</p><p>Friend!</p></div>';
       const innerHTML = app.$.container.innerHTML;
-      assertEquals(innerHTML, expected);
+      assertEquals(expected, innerHTML);
     });
 
     test('CorrectContentSelected', () => {
       const selection = app.getSelection();
-      assertEquals(selection.anchorNode.textContent, 'World');
-      assertEquals(selection.focusNode.textContent, 'Friend');
-      assertEquals(selection.anchorOffset, 1);
-      assertEquals(selection.focusOffset, 2);
+      assertEquals('World', selection.anchorNode.textContent);
+      assertEquals('Friend', selection.focusNode.textContent);
+      assertEquals(1, selection.anchorOffset);
+      assertEquals(2, selection.focusOffset);
     });
   });
 });
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_with_highlights.ts b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_with_highlights.ts
index 11e27d2..172c9f16 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_with_highlights.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_with_highlights.ts
@@ -50,8 +50,8 @@
     app = document.createElement('read-anything-app');
     document.body.appendChild(app);
 
-    assertEquals(textNodeIds.length, 4);
-    assertEquals(texts.length, 4);
+    assertEquals(4, textNodeIds.length);
+    assertEquals(4, texts.length);
     fakeTree = new FakeTreeBuilder()
                    .root(1)
                    .addTag(2, /* parentId= */ 1, 'p')
@@ -163,10 +163,10 @@
           previousSelector, expectedAnchorOffset, texts[0]!,
           expectedFocusOffset);
 
-      assertEquals(actualAnchorId, expectedNodeId);
-      assertEquals(actualFocusId, expectedNodeId);
-      assertEquals(actualAnchorOffset, expectedAnchorOffset);
-      assertEquals(actualFocusOffset, expectedFocusOffset);
+      assertEquals(expectedNodeId, actualAnchorId);
+      assertEquals(expectedNodeId, actualFocusId);
+      assertEquals(expectedAnchorOffset, actualAnchorOffset);
+      assertEquals(expectedFocusOffset, actualFocusOffset);
     });
 
     test('multiple nodes selected before single node highlight', async () => {
@@ -178,10 +178,10 @@
           previousSelector, expectedAnchorOffset, texts[0]!,
           expectedFocusOffset, texts[1]!);
 
-      assertEquals(actualAnchorId, textNodeIds[0]!);
-      assertEquals(actualFocusId, textNodeIds[1]!);
-      assertEquals(actualAnchorOffset, expectedAnchorOffset);
-      assertEquals(actualFocusOffset, expectedFocusOffset);
+      assertEquals(textNodeIds[0]!, actualAnchorId);
+      assertEquals(textNodeIds[1]!, actualFocusId);
+      assertEquals(expectedAnchorOffset, actualAnchorOffset);
+      assertEquals(expectedFocusOffset, actualFocusOffset);
     });
 
     test('one node selected before multiple node highlight', async () => {
@@ -197,10 +197,10 @@
           previousSelector, expectedAnchorOffset, texts[1]!,
           expectedFocusOffset);
 
-      assertEquals(actualAnchorId, expectedNodeId);
-      assertEquals(actualFocusId, expectedNodeId);
-      assertEquals(actualAnchorOffset, expectedAnchorOffset);
-      assertEquals(actualFocusOffset, expectedFocusOffset);
+      assertEquals(expectedNodeId, actualAnchorId);
+      assertEquals(expectedNodeId, actualFocusId);
+      assertEquals(expectedAnchorOffset, actualAnchorOffset);
+      assertEquals(expectedFocusOffset, actualFocusOffset);
     });
 
     test('multiple nodes selected before multiple node highlight', async () => {
@@ -215,10 +215,10 @@
           previousSelector, expectedAnchorOffset, texts[0]!,
           expectedFocusOffset, texts[1]!);
 
-      assertEquals(actualAnchorId, textNodeIds[0]!);
-      assertEquals(actualFocusId, textNodeIds[1]!);
-      assertEquals(actualAnchorOffset, expectedAnchorOffset);
-      assertEquals(actualFocusOffset, expectedFocusOffset);
+      assertEquals(textNodeIds[0]!, actualAnchorId);
+      assertEquals(textNodeIds[1]!, actualFocusId);
+      assertEquals(expectedAnchorOffset, actualAnchorOffset);
+      assertEquals(expectedFocusOffset, actualFocusOffset);
     });
 
     test('one node selected inside single node highlight', async () => {
@@ -232,10 +232,10 @@
           currentSelector, expectedAnchorOffset, texts[1]!,
           expectedFocusOffset);
 
-      assertEquals(actualAnchorId, highlightId);
-      assertEquals(actualFocusId, highlightId);
-      assertEquals(actualAnchorOffset, expectedAnchorOffset);
-      assertEquals(actualFocusOffset, expectedFocusOffset);
+      assertEquals(highlightId, actualAnchorId);
+      assertEquals(highlightId, actualFocusId);
+      assertEquals(expectedAnchorOffset, actualAnchorOffset);
+      assertEquals(expectedFocusOffset, actualFocusOffset);
     });
 
     test('one node selected inside multiple node highlight', async () => {
@@ -250,10 +250,10 @@
           currentSelector, expectedAnchorOffset, texts[1]!,
           expectedFocusOffset);
 
-      assertEquals(actualAnchorId, textNodeIds[1]!);
-      assertEquals(actualFocusId, textNodeIds[1]!);
-      assertEquals(actualAnchorOffset, expectedAnchorOffset);
-      assertEquals(actualFocusOffset, expectedFocusOffset);
+      assertEquals(textNodeIds[1]!, actualAnchorId);
+      assertEquals(textNodeIds[1]!, actualFocusId);
+      assertEquals(expectedAnchorOffset, actualAnchorOffset);
+      assertEquals(expectedFocusOffset, actualFocusOffset);
     });
 
     test('prefix selected in long reading highlight', async () => {
@@ -268,10 +268,10 @@
           previousSelector, expectedAnchorOffset,
           texts[2]!.slice(0, highlightStart), highlightStart);
 
-      assertEquals(actualAnchorId, highlightId);
-      assertEquals(actualFocusId, highlightId);
-      assertEquals(actualAnchorOffset, expectedAnchorOffset);
-      assertEquals(actualFocusOffset, highlightStart);
+      assertEquals(highlightId, actualAnchorId);
+      assertEquals(highlightId, actualFocusId);
+      assertEquals(expectedAnchorOffset, actualAnchorOffset);
+      assertEquals(highlightStart, actualFocusOffset);
     });
 
     test('suffix selected in long reading highlight', async () => {
@@ -288,10 +288,10 @@
       selection.setBaseAndExtent(textNode, 0, textNode, selectedText.length);
       await flushTasks();
 
-      assertEquals(actualAnchorId, highlightId);
-      assertEquals(actualFocusId, highlightId);
-      assertEquals(actualAnchorOffset, highlightEnd);
-      assertEquals(actualFocusOffset, texts[2]!.length);
+      assertEquals(highlightId, actualAnchorId);
+      assertEquals(highlightId, actualFocusId);
+      assertEquals(highlightEnd, actualAnchorOffset);
+      assertEquals(texts[2]!.length, actualFocusOffset);
     });
 
     test('one node selected after reading highlight', async () => {
@@ -303,10 +303,10 @@
       await selectNodes(
           afterSelector, expectedAnchorOffset, texts[2]!, expectedFocusOffset);
 
-      assertEquals(actualAnchorId, textNodeIds[2]!);
-      assertEquals(actualFocusId, textNodeIds[2]!);
-      assertEquals(actualAnchorOffset, expectedAnchorOffset);
-      assertEquals(actualFocusOffset, expectedFocusOffset);
+      assertEquals(textNodeIds[2]!, actualAnchorId);
+      assertEquals(textNodeIds[2]!, actualFocusId);
+      assertEquals(expectedAnchorOffset, actualAnchorOffset);
+      assertEquals(expectedFocusOffset, actualFocusOffset);
     });
 
     test('multiple nodes selected after reading highlight', async () => {
@@ -319,10 +319,10 @@
           afterSelector, expectedAnchorOffset, texts[1]!, expectedFocusOffset,
           texts[2]!);
 
-      assertEquals(actualAnchorId, textNodeIds[1]!);
-      assertEquals(actualFocusId, textNodeIds[2]!);
-      assertEquals(actualAnchorOffset, expectedAnchorOffset);
-      assertEquals(actualFocusOffset, expectedFocusOffset);
+      assertEquals(textNodeIds[1]!, actualAnchorId);
+      assertEquals(textNodeIds[2]!, actualFocusId);
+      assertEquals(expectedAnchorOffset, actualAnchorOffset);
+      assertEquals(expectedFocusOffset, actualFocusOffset);
     });
 
     test(
@@ -342,10 +342,10 @@
               anchorNode, 0, focusNode, focusText.length);
           await flushTasks();
 
-          assertEquals(actualAnchorId, textNodeIds[0]!);
-          assertEquals(actualFocusId, textNodeIds[3]!);
-          assertEquals(actualAnchorOffset, expectedAnchorOffset);
-          assertEquals(actualFocusOffset, expectedFocusOffset);
+          assertEquals(textNodeIds[0]!, actualAnchorId);
+          assertEquals(textNodeIds[3]!, actualFocusId);
+          assertEquals(expectedAnchorOffset, actualAnchorOffset);
+          assertEquals(expectedFocusOffset, actualFocusOffset);
         });
   });
 
@@ -364,10 +364,10 @@
       app.updateSelection();
 
       const selection = app.getSelection();
-      assertEquals(selection.anchorNode.textContent, texts[0]!);
-      assertEquals(selection.focusNode.textContent, texts[0]!);
-      assertEquals(selection.anchorOffset, expectedAnchorOffset);
-      assertEquals(selection.focusOffset, expectedFocusOffset);
+      assertEquals(texts[0]!, selection.anchorNode.textContent);
+      assertEquals(texts[0]!, selection.focusNode.textContent);
+      assertEquals(expectedAnchorOffset, selection.anchorOffset);
+      assertEquals(expectedFocusOffset, selection.focusOffset);
     });
 
     test('multiple nodes selected before single node highlight', () => {
@@ -380,10 +380,10 @@
       app.updateSelection();
 
       const selection = app.getSelection();
-      assertEquals(selection.anchorNode.textContent, texts[0]!);
-      assertEquals(selection.focusNode.textContent, texts[1]!);
-      assertEquals(selection.anchorOffset, expectedAnchorOffset);
-      assertEquals(selection.focusOffset, expectedFocusOffset);
+      assertEquals(texts[0]!, selection.anchorNode.textContent);
+      assertEquals(texts[1]!, selection.focusNode.textContent);
+      assertEquals(expectedAnchorOffset, selection.anchorOffset);
+      assertEquals(expectedFocusOffset, selection.focusOffset);
     });
 
     test('one node selected before multiple node highlight', () => {
@@ -396,10 +396,10 @@
       app.updateSelection();
 
       const selection = app.getSelection();
-      assertEquals(selection.anchorNode.textContent, texts[1]!);
-      assertEquals(selection.focusNode.textContent, texts[1]!);
-      assertEquals(selection.anchorOffset, expectedAnchorOffset);
-      assertEquals(selection.focusOffset, expectedFocusOffset);
+      assertEquals(texts[1]!, selection.anchorNode.textContent);
+      assertEquals(texts[1]!, selection.focusNode.textContent);
+      assertEquals(expectedAnchorOffset, selection.anchorOffset);
+      assertEquals(expectedFocusOffset, selection.focusOffset);
     });
 
     test('multiple nodes selected before multiple node highlight', () => {
@@ -412,10 +412,10 @@
       app.updateSelection();
 
       const selection = app.getSelection();
-      assertEquals(selection.anchorNode.textContent, texts[0]!);
-      assertEquals(selection.focusNode.textContent, texts[1]!);
-      assertEquals(selection.anchorOffset, expectedAnchorOffset);
-      assertEquals(selection.focusOffset, expectedFocusOffset);
+      assertEquals(texts[0]!, selection.anchorNode.textContent);
+      assertEquals(texts[1]!, selection.focusNode.textContent);
+      assertEquals(expectedAnchorOffset, selection.anchorOffset);
+      assertEquals(expectedFocusOffset, selection.focusOffset);
     });
 
     test('one node selected inside single node highlight', () => {
@@ -430,10 +430,10 @@
       app.updateSelection();
 
       const selection = app.getSelection();
-      assertEquals(selection.anchorNode.textContent, texts[1]!);
-      assertEquals(selection.focusNode.textContent, texts[1]!);
-      assertEquals(selection.anchorOffset, expectedAnchorOffset);
-      assertEquals(selection.focusOffset, expectedFocusOffset);
+      assertEquals(texts[1]!, selection.anchorNode.textContent);
+      assertEquals(texts[1]!, selection.focusNode.textContent);
+      assertEquals(expectedAnchorOffset, selection.anchorOffset);
+      assertEquals(expectedFocusOffset, selection.focusOffset);
     });
 
     test('one node selected inside multiple node highlight', () => {
@@ -446,10 +446,10 @@
       app.updateSelection();
 
       const selection = app.getSelection();
-      assertEquals(selection.anchorNode.textContent, texts[1]!);
-      assertEquals(selection.focusNode.textContent, texts[1]!);
-      assertEquals(selection.anchorOffset, expectedAnchorOffset);
-      assertEquals(selection.focusOffset, expectedFocusOffset);
+      assertEquals(texts[1]!, selection.anchorNode.textContent);
+      assertEquals(texts[1]!, selection.focusNode.textContent);
+      assertEquals(expectedAnchorOffset, selection.anchorOffset);
+      assertEquals(expectedFocusOffset, selection.focusOffset);
     });
 
     test(
@@ -465,10 +465,10 @@
           app.updateSelection();
 
           const selection = app.getSelection();
-          assertEquals(selection.anchorNode.textContent, texts[0]!);
-          assertEquals(selection.focusNode.textContent, texts[1]!);
-          assertEquals(selection.anchorOffset, expectedAnchorOffset);
-          assertEquals(selection.focusOffset, expectedFocusOffset);
+          assertEquals(texts[0]!, selection.anchorNode.textContent);
+          assertEquals(texts[1]!, selection.focusNode.textContent);
+          assertEquals(expectedAnchorOffset, selection.anchorOffset);
+          assertEquals(expectedFocusOffset, selection.focusOffset);
         });
 
     test('prefix selected in long reading highlight', () => {
@@ -485,10 +485,10 @@
 
       const selection = app.getSelection();
       const expectedSelectedText = texts[2]!.slice(0, highlightStart);
-      assertEquals(selection.anchorNode.textContent, expectedSelectedText);
-      assertEquals(selection.focusNode.textContent, expectedSelectedText);
-      assertEquals(selection.anchorOffset, expectedAnchorOffset);
-      assertEquals(selection.focusOffset, highlightStart);
+      assertEquals(expectedSelectedText, selection.anchorNode.textContent);
+      assertEquals(expectedSelectedText, selection.focusNode.textContent);
+      assertEquals(expectedAnchorOffset, selection.anchorOffset);
+      assertEquals(highlightStart, selection.focusOffset);
     });
 
     test('suffix selected in long reading highlight', () => {
@@ -507,10 +507,10 @@
       // entirety of the new second node.
       const selection = app.getSelection();
       const expectedSelectedText = texts[2]!.slice(highlightEnd);
-      assertEquals(selection.anchorNode.textContent, expectedSelectedText);
-      assertEquals(selection.focusNode.textContent, expectedSelectedText);
-      assertEquals(selection.anchorOffset, 0);
-      assertEquals(selection.focusOffset, expectedSelectedText.length);
+      assertEquals(expectedSelectedText, selection.anchorNode.textContent);
+      assertEquals(expectedSelectedText, selection.focusNode.textContent);
+      assertEquals(0, selection.anchorOffset);
+      assertEquals(expectedSelectedText.length, selection.focusOffset);
     });
 
     test('one node selected after reading highlight', () => {
@@ -523,10 +523,10 @@
       app.updateSelection();
 
       const selection = app.getSelection();
-      assertEquals(selection.anchorNode.textContent, texts[2]!);
-      assertEquals(selection.focusNode.textContent, texts[2]!);
-      assertEquals(selection.anchorOffset, expectedAnchorOffset);
-      assertEquals(selection.focusOffset, expectedFocusOffset);
+      assertEquals(texts[2]!, selection.anchorNode.textContent);
+      assertEquals(texts[2]!, selection.focusNode.textContent);
+      assertEquals(expectedAnchorOffset, selection.anchorOffset);
+      assertEquals(expectedFocusOffset, selection.focusOffset);
     });
 
     test('multiple nodes selected after reading highlight', () => {
@@ -539,10 +539,10 @@
       app.updateSelection();
 
       const selection = app.getSelection();
-      assertEquals(selection.anchorNode.textContent, texts[1]!);
-      assertEquals(selection.focusNode.textContent, texts[2]!);
-      assertEquals(selection.anchorOffset, expectedAnchorOffset);
-      assertEquals(selection.focusOffset, expectedFocusOffset);
+      assertEquals(texts[1]!, selection.anchorNode.textContent);
+      assertEquals(texts[2]!, selection.focusNode.textContent);
+      assertEquals(expectedAnchorOffset, selection.anchorOffset);
+      assertEquals(expectedFocusOffset, selection.focusOffset);
     });
 
     test('selection across previous, current, and after highlight', () => {
@@ -556,10 +556,10 @@
       app.updateSelection();
 
       const selection = app.getSelection();
-      assertEquals(selection.anchorOffset, 0);
-      assertEquals(selection.focusOffset, texts[3]!.length);
-      assertEquals(selection.anchorNode.textContent, texts[0]!);
-      assertEquals(selection.focusNode.textContent, texts[3]!);
+      assertEquals(0, selection.anchorOffset);
+      assertEquals(texts[3]!.length, selection.focusOffset);
+      assertEquals(texts[0]!, selection.anchorNode.textContent);
+      assertEquals(texts[3]!, selection.focusNode.textContent);
     });
   });
 });
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_background_color.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_background_color.js
deleted file mode 100644
index 08bde77..0000000
--- a/chrome/test/data/webui/side_panel/read_anything/update_theme_background_color.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// out/Debug/browser_tests \
-//    --gtest_filter=ReadAnythingAppTest.UpdateTheme_BackgroundColor
-
-// Do not call the real `onConnected()`. As defined in
-// ReadAnythingAppController, onConnected creates mojo pipes to connect to the
-// rest of the Read Anything feature, which we are not testing here.
-(() => {
-  chrome.readingMode.onConnected = () => {};
-
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
-
-  chrome.readingMode.setThemeForTesting(
-      'f', 1, true, false, 0,
-      /* SkColorSetRGB(0xFD, 0xE2, 0x93) = */ 4294828691, 1, 0);
-  const expected = 'rgb(253, 226, 147)';  // #FDE293
-  const actual = getComputedStyle(container).backgroundColor;
-  const isEqual = actual === expected;
-  if (!isEqual) {
-    console.error(
-        'Expected: ' + JSON.stringify(expected) + ', ' +
-        'Actual: ' + JSON.stringify(actual));
-  }
-  return isEqual;
-})();
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_font_name.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_font_name.js
deleted file mode 100644
index cfc0873b..0000000
--- a/chrome/test/data/webui/side_panel/read_anything/update_theme_font_name.js
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// out/Debug/browser_tests \
-//    --gtest_filter=ReadAnythingAppTest.UpdateTheme_FontName
-
-// Do not call the real `onConnected()`. As defined in
-// ReadAnythingAppController, onConnected creates mojo pipes to connect to the
-// rest of the Read Anything feature, which we are not testing here.
-(() => {
-  chrome.readingMode.onConnected = () => {};
-
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
-  let result = true;
-
-  const assertEquals = (actual, expected) => {
-    const isEqual = actual === expected;
-    if (!isEqual) {
-      console.error(
-          'Expected: ' + JSON.stringify(expected) + ', ' +
-          'Actual: ' + JSON.stringify(actual));
-    }
-    result = result && isEqual;
-    return isEqual;
-  };
-
-  const assertFontName = (expected) => {
-    assertEquals(expected, getComputedStyle(container).fontFamily);
-  };
-
-  chrome.readingMode.setThemeForTesting(
-      'Poppins', 18.0, true, false, 0, 0, 1, 0);
-  assertFontName('Poppins');
-
-  chrome.readingMode.setThemeForTesting(
-      'Sans-serif', 18.0, true, false, 0, 0, 1, 0);
-  assertFontName('sans-serif');
-
-  chrome.readingMode.setThemeForTesting('Serif', 18.0, true, false, 0, 0, 1, 0);
-  assertFontName('serif');
-
-  chrome.readingMode.setThemeForTesting(
-      'Comic Neue', 18.0, true, false, 0, 0, 1, 0);
-  assertFontName('"Comic Neue"');
-
-  chrome.readingMode.setThemeForTesting(
-      'Lexend Deca', 18.0, true, false, 0, 0, 1, 0);
-  assertFontName('"Lexend Deca"');
-
-  chrome.readingMode.setThemeForTesting(
-      'EB Garamond', 18.0, true, false, 0, 0, 1, 0);
-  assertFontName('"EB Garamond"');
-
-  chrome.readingMode.setThemeForTesting(
-      'STIX Two Text', 18.0, true, false, 0, 0, 1, 0);
-  assertFontName('"STIX Two Text"');
-
-  chrome.readingMode.setThemeForTesting(
-      'Andika', 18.0, true, false, 0, 0, 1, 0);
-  assertFontName('Andika');
-
-  return result;
-})();
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_font_size.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_font_size.js
deleted file mode 100644
index aa183dba..0000000
--- a/chrome/test/data/webui/side_panel/read_anything/update_theme_font_size.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// out/Debug/browser_tests \
-//    --gtest_filter=ReadAnythingAppTest.UpdateTheme_FontSize
-
-// Do not call the real `onConnected()`. As defined in
-// ReadAnythingAppController, onConnected creates mojo pipes to connect to the
-// rest of the Read Anything feature, which we are not testing here.
-(() => {
-  chrome.readingMode.onConnected = () => {};
-
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
-
-  chrome.readingMode.setThemeForTesting(
-      'Poppins', 1.0, true, false, 0, 0, 1, 0);
-  const expected = '16px';  // 1em = 16px
-  const actual = getComputedStyle(container).fontSize;
-  const isEqual = actual === expected;
-  if (!isEqual) {
-    console.error(
-        'Expected: ' + JSON.stringify(expected) + ', ' +
-        'Actual: ' + JSON.stringify(actual));
-  }
-  return isEqual;
-})();
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_foreground_color.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_foreground_color.js
deleted file mode 100644
index 6e3e925..0000000
--- a/chrome/test/data/webui/side_panel/read_anything/update_theme_foreground_color.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// out/Debug/browser_tests \
-//    --gtest_filter=ReadAnythingAppTest.UpdateTheme_ForegroundColor
-
-// Do not call the real `onConnected()`. As defined in
-// ReadAnythingAppController, onConnected creates mojo pipes to connect to the
-// rest of the Read Anything feature, which we are not testing here.
-(() => {
-  chrome.readingMode.onConnected = () => {};
-
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
-
-  chrome.readingMode.setThemeForTesting(
-      'f', 1, true, false, /* SkColorSetRGB(0x33, 0x36, 0x39) = */ 4281546297,
-      0, 1, 0);
-  const expected = 'rgb(51, 54, 57)';  // #333639
-  const actual = getComputedStyle(container).color;
-  const isEqual = actual === expected;
-  if (!isEqual) {
-    console.error(
-        'Expected: ' + JSON.stringify(expected) + ', ' +
-        'Actual: ' + JSON.stringify(actual));
-  }
-  return isEqual;
-})();
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_letter_spacing.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_letter_spacing.js
deleted file mode 100644
index 65944fef..0000000
--- a/chrome/test/data/webui/side_panel/read_anything/update_theme_letter_spacing.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// out/Debug/browser_tests \
-//    --gtest_filter=ReadAnythingAppTest.UpdateTheme_LetterSpacing
-
-// Do not call the real `onConnected()`. As defined in
-// ReadAnythingAppController, onConnected creates mojo pipes to connect to the
-// rest of the Read Anything feature, which we are not testing here.
-(() => {
-  chrome.readingMode.onConnected = () => {};
-
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
-
-  chrome.readingMode.setThemeForTesting('f', 1, true, false, 0, 0, 1, 3);
-  // Very loose letter letter spacing = 0.1em, font size = 1em = 16px
-  const expected = '1.6px';
-  const actual = getComputedStyle(container).letterSpacing;
-  const isEqual = actual === expected;
-  if (!isEqual) {
-    console.error(
-        'Expected: ' + JSON.stringify(expected) + ', ' +
-        'Actual: ' + JSON.stringify(actual));
-  }
-  return isEqual;
-})();
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_line_spacing.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_line_spacing.js
deleted file mode 100644
index 378651d..0000000
--- a/chrome/test/data/webui/side_panel/read_anything/update_theme_line_spacing.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// out/Debug/browser_tests \
-//    --gtest_filter=ReadAnythingAppTest.UpdateTheme_LineSpacing
-
-// Do not call the real `onConnected()`. As defined in
-// ReadAnythingAppController, onConnected creates mojo pipes to connect to the
-// rest of the Read Anything feature, which we are not testing here.
-(() => {
-  chrome.readingMode.onConnected = () => {};
-
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
-
-  chrome.readingMode.setThemeForTesting(
-      'Poppins', 1.0, true, false, 0, 0, 2, 0);
-  const expected = '24px';  // 1.5 times the 1em (16px) font size
-  const actual = getComputedStyle(container).lineHeight;
-  const isEqual = actual === expected;
-  if (!isEqual) {
-    console.error(
-        'Expected: ' + JSON.stringify(expected) + ', ' +
-        'Actual: ' + JSON.stringify(actual));
-  }
-  return isEqual;
-})();
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_voice_pack_test.ts b/chrome/test/data/webui/side_panel/read_anything/update_voice_pack_test.ts
index f054cdaa..38599a58 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_voice_pack_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/update_voice_pack_test.ts
@@ -10,6 +10,7 @@
 import type {VoicePackStatus} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome-untrusted://webui-test/chai_assert.js';
 
+import {createSpeechSynthesisVoice} from './common.js';
 import {FakeReadingMode} from './fake_reading_mode.js';
 import {FakeSpeechSynthesis} from './fake_speech_synthesis.js';
 import {TestColorUpdaterBrowserProxy} from './test_color_updater_browser_proxy.js';
@@ -30,8 +31,8 @@
     const voices = app.synth.getVoices();
     app.synth.getVoices = () => {
       return voices.concat(
-          {lang: lang, name: 'Wall-e (Natural)'} as SpeechSynthesisVoice,
-          {lang: lang, name: 'Andy (Natural)'} as SpeechSynthesisVoice,
+          createSpeechSynthesisVoice({lang: lang, name: 'Wall-e (Natural)'}),
+          createSpeechSynthesisVoice({lang: lang, name: 'Andy (Natural)'}),
       );
     };
     app.getVoices(true);
@@ -73,8 +74,8 @@
             getVoicePackServerInstallStatus(voicePackLang).code,
             VoicePackServerStatusSuccessCode.NOT_INSTALLED);
         assertEquals(
-            getVoicePackServerInstallStatus(lang).id, 'Successful response');
-        assertEquals(sentInstallRequestFor, voicePackLang);
+            'Successful response', getVoicePackServerInstallStatus(lang).id);
+        assertEquals(voicePackLang, sentInstallRequestFor);
       });
     });
   });
@@ -164,7 +165,7 @@
             getVoicePackServerInstallStatus(lang).code,
             VoicePackServerStatusSuccessCode.INSTALLED);
         assertEquals(
-            getVoicePackServerInstallStatus(lang).id, 'Successful response');
+            'Successful response', getVoicePackServerInstallStatus(lang).id);
         assertEquals(
             app.getVoicePackLocalStatus(lang),
             VoiceClientSideStatusCode.INSTALLED_AND_UNAVAILABLE);
@@ -196,7 +197,7 @@
         getVoicePackServerInstallStatus(lang).code,
         VoicePackServerStatusSuccessCode.INSTALLED);
     assertEquals(
-        getVoicePackServerInstallStatus(lang).id, 'Successful response');
+        'Successful response', getVoicePackServerInstallStatus(lang).id);
     assertEquals(
         app.getVoicePackLocalStatus(lang),
         VoiceClientSideStatusCode.INSTALLED_AND_UNAVAILABLE);
@@ -207,7 +208,7 @@
       () => {
         const lang = 'yue';
         app.availableVoices = [
-          {lang: 'yue-hk', name: 'Cantonese'} as SpeechSynthesisVoice,
+          createSpeechSynthesisVoice({lang: 'yue-hk', name: 'Cantonese'}),
         ];
 
         app.updateVoicePackStatus(lang, 'kInstalled');
@@ -216,7 +217,7 @@
             getVoicePackServerInstallStatus(lang).code,
             VoicePackServerStatusSuccessCode.INSTALLED);
         assertEquals(
-            getVoicePackServerInstallStatus(lang).id, 'Successful response');
+            'Successful response', getVoicePackServerInstallStatus(lang).id);
         assertEquals(
             app.getVoicePackLocalStatus(lang),
             VoiceClientSideStatusCode.AVAILABLE);
@@ -233,7 +234,7 @@
             getVoicePackServerInstallStatus(lang).code,
             VoicePackServerStatusSuccessCode.INSTALLED);
         assertEquals(
-            getVoicePackServerInstallStatus(lang).id, 'Successful response');
+            'Successful response', getVoicePackServerInstallStatus(lang).id);
         assertEquals(
             app.getVoicePackLocalStatus(lang),
             VoiceClientSideStatusCode.INSTALLED_AND_UNAVAILABLE);
@@ -258,12 +259,12 @@
             getVoicePackServerInstallStatus(lang).code,
             VoicePackServerStatusSuccessCode.INSTALLED);
         assertEquals(
-            getVoicePackServerInstallStatus(lang).id, 'Successful response');
+            'Successful response', getVoicePackServerInstallStatus(lang).id);
         assertEquals(
             app.getVoicePackLocalStatus(lang),
             VoiceClientSideStatusCode.AVAILABLE);
         assertTrue(app.getVoices().some(v => v.lang.toLowerCase() === lang));
-        assertEquals(app.selectedVoice, undefined);
+        assertEquals(undefined, app.selectedVoice);
       });
 
   test(
@@ -286,7 +287,7 @@
         app.updateVoicePackStatus(lang, 'kInstalled');
 
         assertTrue(!!app.selectedVoice);
-        assertEquals(app.selectedVoice.lang, lang);
+        assertEquals(lang, app.selectedVoice.lang);
         assertTrue(app.selectedVoice.name.includes('Natural'));
       });
 
@@ -296,10 +297,10 @@
         const lang = 'en-us';
         chrome.readingMode.isLanguagePackDownloadingEnabled = true;
         chrome.readingMode.baseLanguageForSpeech = 'pt-br';
-        const currentVoice = {
+        const currentVoice = createSpeechSynthesisVoice({
           name: 'Portuguese voice 1',
           lang: chrome.readingMode.baseLanguageForSpeech,
-        } as SpeechSynthesisVoice;
+        });
         app.selectedVoice = currentVoice;
         app.$.toolbar.updateFonts = () => {};
         chrome.readingMode.isAutoVoiceSwitchingEnabled = true;
@@ -313,7 +314,7 @@
         app.updateVoicePackStatus(lang, 'kInstalled');
 
         // The selected voice should stay the same as it was.
-        assertEquals(app.selectedVoice, currentVoice);
+        assertEquals(currentVoice, app.selectedVoice);
       });
 
   test('with error code marks the status', () => {
@@ -323,7 +324,7 @@
         getVoicePackServerInstallStatus(lang).code,
         VoicePackServerStatusErrorCode.OTHER);
     assertEquals(
-        getVoicePackServerInstallStatus(lang).id, 'Unsuccessful response');
+        'Unsuccessful response', getVoicePackServerInstallStatus(lang).id);
 
     assertEquals(
         app.getVoicePackLocalStatus(lang),
@@ -347,7 +348,7 @@
 
       test('and only eSpeak voices for language, disables language', () => {
         app.availableVoices = [
-          {lang: lang, name: 'eSpeak Portuguese'} as SpeechSynthesisVoice,
+          createSpeechSynthesisVoice({lang: lang, name: 'eSpeak Portuguese'}),
         ];
 
         app.updateVoicePackStatusFromInstallResponse(lang, 'kOther');
@@ -373,7 +374,7 @@
           () => {
             app.enabledLangs.push('it-it');
             app.availableVoices = [
-              {lang: 'it', name: 'eSpeak Italian '} as SpeechSynthesisVoice,
+              createSpeechSynthesisVoice({lang: 'it', name: 'eSpeak Italian '}),
             ];
 
             app.updateVoicePackStatusFromInstallResponse('it', 'kOther');
@@ -385,10 +386,10 @@
           'and has other Google voices for language, keeps language enabled',
           () => {
             app.availableVoices = [
-              {lang: lang, name: 'ChromeOS Portuguese 1'} as
-                  SpeechSynthesisVoice,
-              {lang: lang, name: 'ChromeOS Portuguese 2'} as
-                  SpeechSynthesisVoice,
+              createSpeechSynthesisVoice(
+                  {lang: lang, name: 'ChromeOS Portuguese 1'}),
+              createSpeechSynthesisVoice(
+                  {lang: lang, name: 'ChromeOS Portuguese 2'}),
             ];
             app.updateVoicePackStatusFromInstallResponse(lang, 'kOther');
 
diff --git a/chrome/test/data/webui/side_panel/read_anything/voice_language_util_test.ts b/chrome/test/data/webui/side_panel/read_anything/voice_language_util_test.ts
index 0aa2772..95650be 100644
--- a/chrome/test/data/webui/side_panel/read_anything/voice_language_util_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/voice_language_util_test.ts
@@ -11,182 +11,182 @@
   test('mojoVoicePackStatusToVoicePackStatusEnum', () => {
     // Success codes
     assertEquals(
-        mojoVoicePackStatusToVoicePackStatusEnum('kNotInstalled').code,
-        VoicePackServerStatusSuccessCode.NOT_INSTALLED);
+        VoicePackServerStatusSuccessCode.NOT_INSTALLED,
+        mojoVoicePackStatusToVoicePackStatusEnum('kNotInstalled').code);
     assertEquals(
-        mojoVoicePackStatusToVoicePackStatusEnum('kInstalled').code,
-        VoicePackServerStatusSuccessCode.INSTALLED);
+        VoicePackServerStatusSuccessCode.INSTALLED,
+        mojoVoicePackStatusToVoicePackStatusEnum('kInstalled').code);
     assertEquals(
-        mojoVoicePackStatusToVoicePackStatusEnum('kInstalling').code,
-        VoicePackServerStatusSuccessCode.INSTALLING);
+        VoicePackServerStatusSuccessCode.INSTALLING,
+        mojoVoicePackStatusToVoicePackStatusEnum('kInstalling').code);
 
     // Error codes
     assertEquals(
-        mojoVoicePackStatusToVoicePackStatusEnum('kUnknown').code,
-        VoicePackServerStatusErrorCode.OTHER);
+        VoicePackServerStatusErrorCode.OTHER,
+        mojoVoicePackStatusToVoicePackStatusEnum('kUnknown').code);
     assertEquals(
-        mojoVoicePackStatusToVoicePackStatusEnum('kOther').code,
-        VoicePackServerStatusErrorCode.OTHER);
+        VoicePackServerStatusErrorCode.OTHER,
+        mojoVoicePackStatusToVoicePackStatusEnum('kOther').code);
     assertEquals(
-        mojoVoicePackStatusToVoicePackStatusEnum('kWrongId').code,
-        VoicePackServerStatusErrorCode.WRONG_ID);
+        VoicePackServerStatusErrorCode.WRONG_ID,
+        mojoVoicePackStatusToVoicePackStatusEnum('kWrongId').code);
     assertEquals(
-        mojoVoicePackStatusToVoicePackStatusEnum('kNeedReboot').code,
-        VoicePackServerStatusErrorCode.NEED_REBOOT);
+        VoicePackServerStatusErrorCode.NEED_REBOOT,
+        mojoVoicePackStatusToVoicePackStatusEnum('kNeedReboot').code);
     assertEquals(
-        mojoVoicePackStatusToVoicePackStatusEnum('kAllocation').code,
-        VoicePackServerStatusErrorCode.ALLOCATION);
+        VoicePackServerStatusErrorCode.ALLOCATION,
+        mojoVoicePackStatusToVoicePackStatusEnum('kAllocation').code);
     assertEquals(
-        mojoVoicePackStatusToVoicePackStatusEnum('kUnsupportedPlatform').code,
-        VoicePackServerStatusErrorCode.UNSUPPORTED_PLATFORM);
+        VoicePackServerStatusErrorCode.UNSUPPORTED_PLATFORM,
+        mojoVoicePackStatusToVoicePackStatusEnum('kUnsupportedPlatform').code);
   });
 
   test('convertLangOrLocaleForVoicePackManager', () => {
     // Converts to locale when necessary
-    assertEquals(convertLangOrLocaleForVoicePackManager('en'), 'en-us');
-    assertEquals(convertLangOrLocaleForVoicePackManager('es'), 'es-es');
-    assertEquals(convertLangOrLocaleForVoicePackManager('pt'), 'pt-br');
+    assertEquals('en-us', convertLangOrLocaleForVoicePackManager('en'));
+    assertEquals('es-es', convertLangOrLocaleForVoicePackManager('es'));
+    assertEquals('pt-br', convertLangOrLocaleForVoicePackManager('pt'));
 
     // Converts to base language when necessary
-    assertEquals(convertLangOrLocaleForVoicePackManager('fr-FR'), 'fr');
-    assertEquals(convertLangOrLocaleForVoicePackManager('fr-Bf'), 'fr');
+    assertEquals('fr', convertLangOrLocaleForVoicePackManager('fr-FR'));
+    assertEquals('fr', convertLangOrLocaleForVoicePackManager('fr-Bf'));
 
 
     // Converts from unsupported locale to supported locale when necessary
-    assertEquals(convertLangOrLocaleForVoicePackManager('en-UK'), 'en-us');
-    assertEquals(convertLangOrLocaleForVoicePackManager('es-MX'), 'es-es');
+    assertEquals('en-us', convertLangOrLocaleForVoicePackManager('en-UK'));
+    assertEquals('es-es', convertLangOrLocaleForVoicePackManager('es-MX'));
 
     // Keeps base language when necessary
-    assertEquals(convertLangOrLocaleForVoicePackManager('nl'), 'nl');
-    assertEquals(convertLangOrLocaleForVoicePackManager('yue'), 'yue');
+    assertEquals('nl', convertLangOrLocaleForVoicePackManager('nl'));
+    assertEquals('yue', convertLangOrLocaleForVoicePackManager('yue'));
 
     // Keeps locale when necesseary
-    assertEquals(convertLangOrLocaleForVoicePackManager('en-GB'), 'en-gb');
-    assertEquals(convertLangOrLocaleForVoicePackManager('es-es'), 'es-es');
-    assertEquals(convertLangOrLocaleForVoicePackManager('pt-Br'), 'pt-br');
+    assertEquals('en-gb', convertLangOrLocaleForVoicePackManager('en-GB'));
+    assertEquals('es-es', convertLangOrLocaleForVoicePackManager('es-es'));
+    assertEquals('pt-br', convertLangOrLocaleForVoicePackManager('pt-Br'));
 
     // Unsupported languages are undefined
-    assertEquals(convertLangOrLocaleForVoicePackManager('cn'), undefined);
+    assertEquals(undefined, convertLangOrLocaleForVoicePackManager('cn'));
   });
 
   test('convertLangOrLocaleToExactVoicePackLocale', () => {
     // Converts to voice pack locale when multiple supported
-    assertEquals(convertLangOrLocaleToExactVoicePackLocale('en'), 'en-us');
-    assertEquals(convertLangOrLocaleToExactVoicePackLocale('es'), 'es-es');
-    assertEquals(convertLangOrLocaleToExactVoicePackLocale('pt'), 'pt-br');
+    assertEquals('en-us', convertLangOrLocaleToExactVoicePackLocale('en'));
+    assertEquals('es-es', convertLangOrLocaleToExactVoicePackLocale('es'));
+    assertEquals('pt-br', convertLangOrLocaleToExactVoicePackLocale('pt'));
 
     // Converts to voice pack locale when only one locale supported
-    assertEquals(convertLangOrLocaleToExactVoicePackLocale('fr'), 'fr-fr');
-    assertEquals(convertLangOrLocaleToExactVoicePackLocale('it'), 'it-it');
-    assertEquals(convertLangOrLocaleToExactVoicePackLocale('bn'), 'bn-bd');
+    assertEquals('fr-fr', convertLangOrLocaleToExactVoicePackLocale('fr'));
+    assertEquals('it-it', convertLangOrLocaleToExactVoicePackLocale('it'));
+    assertEquals('bn-bd', convertLangOrLocaleToExactVoicePackLocale('bn'));
 
     // Converts from unsupported locale to supported locale when necessary
-    assertEquals(convertLangOrLocaleToExactVoicePackLocale('en-UK'), 'en-us');
-    assertEquals(convertLangOrLocaleToExactVoicePackLocale('es-MX'), 'es-es');
+    assertEquals('en-us', convertLangOrLocaleToExactVoicePackLocale('en-UK'));
+    assertEquals('es-es', convertLangOrLocaleToExactVoicePackLocale('es-MX'));
 
     // Keeps locale when necesseary
-    assertEquals(convertLangOrLocaleToExactVoicePackLocale('en-GB'), 'en-gb');
-    assertEquals(convertLangOrLocaleToExactVoicePackLocale('es-es'), 'es-es');
-    assertEquals(convertLangOrLocaleToExactVoicePackLocale('pt-Br'), 'pt-br');
+    assertEquals('en-gb', convertLangOrLocaleToExactVoicePackLocale('en-GB'));
+    assertEquals('es-es', convertLangOrLocaleToExactVoicePackLocale('es-es'));
+    assertEquals('pt-br', convertLangOrLocaleToExactVoicePackLocale('pt-Br'));
 
     // Unsupported languages are undefined
-    assertEquals(convertLangOrLocaleToExactVoicePackLocale('cn'), undefined);
-    assertEquals(convertLangOrLocaleToExactVoicePackLocale('ar'), undefined);
+    assertEquals(undefined, convertLangOrLocaleToExactVoicePackLocale('cn'));
+    assertEquals(undefined, convertLangOrLocaleToExactVoicePackLocale('ar'));
   });
 
   test('convertLangToAnAvailableLangIfPresent', () => {
     // Returns direct matches
     assertEquals(
-        convertLangToAnAvailableLangIfPresent('en-us', ['en', 'fr', 'en-us']),
-        'en-us');
+        'en-us',
+        convertLangToAnAvailableLangIfPresent('en-us', ['en', 'fr', 'en-us']));
     assertEquals(
-        convertLangToAnAvailableLangIfPresent('en', ['en', 'fr', 'en-us']),
-        'en');
+        'en',
+        convertLangToAnAvailableLangIfPresent('en', ['en', 'fr', 'en-us']));
 
     // Finds matching locale for base lang input
     assertEquals(
-        convertLangToAnAvailableLangIfPresent('en', ['en-US', 'fr']), 'en-us');
+        'en-us', convertLangToAnAvailableLangIfPresent('en', ['en-US', 'fr']));
 
     // Finds locale with same base language as input locale, without a direct
     // locale match
     assertEquals(
-        convertLangToAnAvailableLangIfPresent('en-nz', ['en-US', 'fr']),
-        'en-us');
+        'en-us',
+        convertLangToAnAvailableLangIfPresent('en-nz', ['en-US', 'fr']));
 
     // If there's no direct locale match, but our base lang matches both a
     // base lang and a locale with the same base, default to the base lang
     assertEquals(
-        convertLangToAnAvailableLangIfPresent('en-nz', ['en-US', 'en', 'fr']),
-        'en');
+        'en',
+        convertLangToAnAvailableLangIfPresent('en-nz', ['en-US', 'en', 'fr']));
 
     // Uses browser language fallback.
     assertEquals(
-        convertLangToAnAvailableLangIfPresent('es', ['en-US', 'en', 'fr']),
-        chrome.readingMode.defaultLanguageForSpeech);
+        chrome.readingMode.defaultLanguageForSpeech,
+        convertLangToAnAvailableLangIfPresent('es', ['en-US', 'en', 'fr']));
 
     // No match
     assertEquals(
-        convertLangToAnAvailableLangIfPresent('es', ['zh', 'jp', 'fr']),
-        undefined);
+        undefined,
+        convertLangToAnAvailableLangIfPresent('es', ['zh', 'jp', 'fr']));
   });
 
   test('createInitialListOfEnabledLanguages', () => {
     assertDeepEquals(
+        ['en'],
         createInitialListOfEnabledLanguages(
             /* browserOrPageBaseLang= */ 'fr',
             /* storedLanguagesPref= */[], /* availableLangs= */['en'],
-            /* langOfDefaultVoice= */ 'en'),
-        ['en']);
+            /* langOfDefaultVoice= */ 'en'));
 
     assertDeepEquals(
+        ['fr-fr'],
         createInitialListOfEnabledLanguages(
             /* browserOrPageBaseLang= */ 'fr',
             /* storedLanguagesPref= */[], /* availableLangs= */['en', 'fr-FR'],
-            /* langOfDefaultVoice= */ 'en'),
-        ['fr-fr']);
+            /* langOfDefaultVoice= */ 'en'));
 
     assertDeepEquals(
+        ['en-us', 'fr-fr'],
         createInitialListOfEnabledLanguages(
             /* browserOrPageBaseLang= */ 'fr',
             /* storedLanguagesPref= */['en'],
             /* availableLangs= */['en-us', 'fr-FR'],
             /* langOfDefaultVoice= */ 'en')
-            .sort(),
-        ['en-us', 'fr-fr']);
+            .sort());
 
     assertDeepEquals(
+        ['en-uk', 'fr-fr'],
         createInitialListOfEnabledLanguages(
             /* browserOrPageBaseLang= */ 'fr',
             /* storedLanguagesPref= */['en-us'],
             /* availableLangs= */['en-uk', 'fr-FR'],
             /* langOfDefaultVoice= */ undefined)
-            .sort(),
-        ['en-uk', 'fr-fr']);
+            .sort());
 
     assertDeepEquals(
+        ['en-uk'],
         createInitialListOfEnabledLanguages(
             /* browserOrPageBaseLang= */ 'en',
             /* storedLanguagesPref= */['en-uk'],
             /* availableLangs= */['en-uk', 'en-us'],
             /* langOfDefaultVoice= */ undefined)
-            .sort(),
-        ['en-uk']);
+            .sort());
 
     assertDeepEquals(
+        ['en-us'],
         createInitialListOfEnabledLanguages(
             /* browserOrPageBaseLang= */ 'en',
             /* storedLanguagesPref= */['en-us'],
             /* availableLangs= */['en-uk', 'en-us'],
             /* langOfDefaultVoice= */ undefined)
-            .sort(),
-        ['en-us']);
+            .sort());
 
     assertDeepEquals(
+        [],
         createInitialListOfEnabledLanguages(
             /* browserOrPageBaseLang= */ 'fr',
             /* storedLanguagesPref= */[],
             /* availableLangs= */[],
-            /* langOfDefaultVoice= */ undefined),
-        []);
+            /* langOfDefaultVoice= */ undefined));
   });
 });
diff --git a/chrome/test/data/webui/side_panel/read_anything/voice_selection_menu_test.ts b/chrome/test/data/webui/side_panel/read_anything/voice_selection_menu_test.ts
index f569f884..84e9350d 100644
--- a/chrome/test/data/webui/side_panel/read_anything/voice_selection_menu_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/voice_selection_menu_test.ts
@@ -11,7 +11,7 @@
 import type {VoiceSelectionMenuElement} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js';
 import {assertEquals, assertFalse, assertStringContains, assertTrue} from 'chrome-untrusted://webui-test/chai_assert.js';
 
-import {stubAnimationFrame} from './common.js';
+import {createSpeechSynthesisVoice, stubAnimationFrame} from './common.js';
 
 function stringToHtmlTestId(s: string): string {
   return s.replace(/\s/g, '-').replace(/[()]/g, '');
@@ -27,7 +27,7 @@
 
   // If no param for enabledLangs is provided, it auto populates it with the
   // langs of the voices
-  const setAvailableVoices = (enabledLangs?: string[]) => {
+  function setAvailableVoices(enabledLangs?: string[]) {
     voiceSelectionMenu.availableVoices = availableVoices;
     if (enabledLangs === undefined) {
       voiceSelectionMenu.enabledLangs =
@@ -36,14 +36,14 @@
       voiceSelectionMenu.enabledLangs = enabledLangs;
     }
     flush();
-  };
+  }
 
-  const getDropdownItemForVoice = (voice: SpeechSynthesisVoice) => {
+  function getDropdownItemForVoice(voice: SpeechSynthesisVoice) {
     return voiceSelectionMenu.$.voiceSelectionMenu.get()
         .querySelector<HTMLButtonElement>(`[data-test-id="${
             stringToHtmlTestId(voice.name)}"].dropdown-voice-selection-button`)!
         ;
-  };
+  }
 
   setup(() => {
     document.body.innerHTML = window.trustedTypes!.emptyHTML;
@@ -65,7 +65,7 @@
   suite('with one voice', () => {
     setup(() => {
       availableVoices =
-          [{name: 'test voice 1', lang: 'lang'} as SpeechSynthesisVoice];
+          [createSpeechSynthesisVoice({name: 'test voice 1', lang: 'lang'})];
       setAvailableVoices();
     });
 
@@ -102,8 +102,8 @@
     suite('when availableVoices updates', () => {
       setup(() => {
         availableVoices = [
-          {name: 'test voice 1', lang: 'lang'} as SpeechSynthesisVoice,
-          {name: 'test voice 2', lang: 'lang'} as SpeechSynthesisVoice,
+          createSpeechSynthesisVoice({name: 'test voice 1', lang: 'lang'}),
+          createSpeechSynthesisVoice({name: 'test voice 2', lang: 'lang'}),
         ];
         setAvailableVoices();
       });
@@ -119,12 +119,12 @@
                     voiceSelectionButtonSelector);
 
         assertEquals(
-            getDropdownItemForVoice(availableVoices[0]!).textContent!.trim(),
-            availableVoices[0]!.name);
+            availableVoices[0]!.name,
+            getDropdownItemForVoice(availableVoices[0]!).textContent!.trim());
         assertEquals(
-            getDropdownItemForVoice(availableVoices[1]!).textContent!.trim(),
-            availableVoices[1]!.name);
-        assertEquals(dropdownItems.length, 2);
+            availableVoices[1]!.name,
+            getDropdownItemForVoice(availableVoices[1]!).textContent!.trim());
+        assertEquals(2, dropdownItems.length);
         assertTrue(
             isPositionedOnPage(getDropdownItemForVoice(availableVoices[0]!)));
         assertTrue(
@@ -141,15 +141,15 @@
       // We need an additional call to voiceSelectionMenu.get() in these
       // tests to ensure the menu has been rendered.
       voiceSelectionMenu!.$.voiceSelectionMenu.get();
-      selectedVoice = {name: 'test voice 3', lang: 'en-US'} as
-          SpeechSynthesisVoice;
-      previewVoice = {name: 'test voice 1', lang: 'en-US'} as
-          SpeechSynthesisVoice;
+      selectedVoice =
+          createSpeechSynthesisVoice({name: 'test voice 3', lang: 'en-US'});
+      previewVoice =
+          createSpeechSynthesisVoice({name: 'test voice 1', lang: 'en-US'});
 
       availableVoices = [
-        {name: 'test voice 0', lang: 'en-US'} as SpeechSynthesisVoice,
+        createSpeechSynthesisVoice({name: 'test voice 0', lang: 'en-US'}),
         previewVoice,
-        {name: 'test voice 2', lang: 'it-IT'} as SpeechSynthesisVoice,
+        createSpeechSynthesisVoice({name: 'test voice 2', lang: 'it-IT'}),
         selectedVoice,
       ];
       setAvailableVoices();
@@ -173,16 +173,16 @@
       const menu = voiceSelectionMenu!.$.voiceSelectionMenu.get();
       const groupTitles =
           menu.querySelectorAll<HTMLElement>('.lang-group-title');
-      assertEquals(groupTitles.length, 2);
+      assertEquals(2, groupTitles.length);
 
       const firstVoice = groupTitles.item(0)!.nextElementSibling!;
       const secondVoice = firstVoice.nextElementSibling!;
       const thirdVoice = secondVoice.nextElementSibling!;
       const italianVoice = groupTitles.item(1)!.nextElementSibling!;
-      assertEquals(firstVoice.textContent!.trim(), 'test voice 0');
-      assertEquals(secondVoice.textContent!.trim(), 'test voice 1');
-      assertEquals(thirdVoice.textContent!.trim(), 'test voice 3');
-      assertEquals(italianVoice.textContent!.trim(), 'test voice 2');
+      assertEquals('test voice 0', firstVoice.textContent!.trim());
+      assertEquals('test voice 1', secondVoice.textContent!.trim());
+      assertEquals('test voice 3', thirdVoice.textContent!.trim());
+      assertEquals('test voice 2', italianVoice.textContent!.trim());
     });
 
     suite('with some disabled languages', () => {
@@ -192,10 +192,10 @@
         const menu = voiceSelectionMenu!.$.voiceSelectionMenu.get();
         const groupTitles =
             menu.querySelectorAll<HTMLElement>('.lang-group-title');
-        assertEquals(groupTitles.length, 1);
+        assertEquals(1, groupTitles.length);
 
         const italianVoice = groupTitles.item(0)!.nextElementSibling!;
-        assertEquals(italianVoice.textContent!.trim(), 'test voice 2');
+        assertEquals('test voice 2', italianVoice.textContent!.trim());
       });
     });
 
@@ -203,10 +203,10 @@
       setup(() => {
         availableVoices = [
           previewVoice,
-          {name: 'Google US English 1 (Natural)', lang: 'en-US'} as
-              SpeechSynthesisVoice,
-          {name: 'Google US English 2 (Natural)', lang: 'en-US'} as
-              SpeechSynthesisVoice,
+          createSpeechSynthesisVoice(
+              {name: 'Google US English 1 (Natural)', lang: 'en-US'}),
+          createSpeechSynthesisVoice(
+              {name: 'Google US English 2 (Natural)', lang: 'en-US'}),
           selectedVoice,
         ];
         setAvailableVoices();
@@ -217,17 +217,17 @@
             voiceSelectionMenu!.$.voiceSelectionMenu.get().querySelectorAll(
                 '.voice-name');
 
-        assertEquals(usEnglishDropdownItems.length, 4);
+        assertEquals(4, usEnglishDropdownItems.length);
         assertEquals(
-            usEnglishDropdownItems.item(0).textContent!.trim(),
-            'Google US English 1 (Natural)');
+            'Google US English 1 (Natural)',
+            usEnglishDropdownItems.item(0).textContent!.trim());
         assertEquals(
-            usEnglishDropdownItems.item(1).textContent!.trim(),
-            'Google US English 2 (Natural)');
+            'Google US English 2 (Natural)',
+            usEnglishDropdownItems.item(1).textContent!.trim());
         assertEquals(
-            usEnglishDropdownItems.item(2).textContent!.trim(), 'test voice 1');
+            'test voice 1', usEnglishDropdownItems.item(2).textContent!.trim());
         assertEquals(
-            usEnglishDropdownItems.item(3).textContent!.trim(), 'test voice 3');
+            'test voice 3', usEnglishDropdownItems.item(3).textContent!.trim());
       });
     });
 
@@ -250,16 +250,16 @@
       });
 
       test('it defaults to the locale when there is no display name', () => {
-        assertEquals(groupTitles.item(1)!.textContent!.trim(), 'it-IT');
+        assertEquals('it-IT', groupTitles.item(1)!.textContent!.trim());
       });
     });
 
     suite('when voices have duplicate names', () => {
       setup(() => {
         availableVoices = [
-          {name: 'English', lang: 'en-US'} as SpeechSynthesisVoice,
-          {name: 'English', lang: 'en-US'} as SpeechSynthesisVoice,
-          {name: 'English', lang: 'en-UK'} as SpeechSynthesisVoice,
+          createSpeechSynthesisVoice({name: 'English', lang: 'en-US'}),
+          createSpeechSynthesisVoice({name: 'English', lang: 'en-US'}),
+          createSpeechSynthesisVoice({name: 'English', lang: 'en-UK'}),
         ];
         setAvailableVoices();
       });
@@ -270,13 +270,13 @@
             menu.querySelectorAll<HTMLElement>('.lang-group-title');
         const voiceNames = menu.querySelectorAll<HTMLElement>('.voice-name');
 
-        assertEquals(groupTitles.length, 2);
-        assertEquals(groupTitles.item(0)!.textContent!.trim(), 'en-US');
-        assertEquals(groupTitles.item(1)!.textContent!.trim(), 'en-UK');
-        assertEquals(voiceNames.length, 3);
-        assertEquals(voiceNames.item(0)!.textContent!.trim(), 'English');
-        assertEquals(voiceNames.item(1)!.textContent!.trim(), 'English');
-        assertEquals(voiceNames.item(2)!.textContent!.trim(), 'English');
+        assertEquals(2, groupTitles.length);
+        assertEquals('en-US', groupTitles.item(0)!.textContent!.trim());
+        assertEquals('en-UK', groupTitles.item(1)!.textContent!.trim());
+        assertEquals(3, voiceNames.length);
+        assertEquals('English', voiceNames.item(0)!.textContent!.trim());
+        assertEquals('English', voiceNames.item(1)!.textContent!.trim());
+        assertEquals('English', voiceNames.item(2)!.textContent!.trim());
       });
     });
 
@@ -325,14 +325,14 @@
         // The play icon should flip to stop for the voice being previewed
         assertTrue(isPositionedOnPage(playIconOfPreviewVoice));
         assertEquals(
-            playIconOfPreviewVoice.ironIcon, 'read-anything-20:stop-circle');
+            'read-anything-20:stop-circle', playIconOfPreviewVoice.ironIcon);
         assertStringContains(
             playIconOfPreviewVoice.title.toLowerCase(), 'stop');
         assertStringContains(
             playIconOfPreviewVoice.ariaLabel!.toLowerCase(), 'stop');
         // The play icon should remain unchanged for the other buttons
         assertTrue(isPositionedOnPage(playIconVoice0));
-        assertEquals(playIconVoice0.ironIcon, 'read-anything-20:play-circle');
+        assertEquals('read-anything-20:play-circle', playIconVoice0.ironIcon);
         assertStringContains(playIconVoice0.title.toLowerCase(), 'play');
         assertStringContains(
             playIconVoice0.ariaLabel!.toLowerCase(), 'preview voice for');
@@ -358,8 +358,8 @@
           assertTrue(isPositionedOnPage(playIconOfPreviewVoice));
           assertTrue(isPositionedOnPage(playIconVoice0));
           assertEquals(
-              playIconOfPreviewVoice.ironIcon, 'read-anything-20:play-circle');
-          assertEquals(playIconVoice0.ironIcon, 'read-anything-20:play-circle');
+              'read-anything-20:play-circle', playIconOfPreviewVoice.ironIcon);
+          assertEquals('read-anything-20:play-circle', playIconVoice0.ironIcon);
           assertStringContains(
               playIconOfPreviewVoice.title.toLowerCase(), 'play');
           assertStringContains(playIconVoice0.title.toLowerCase(), 'play');
@@ -402,12 +402,12 @@
     });
 
     test('no downloading messages by default', () => {
-      assertEquals(getDownloadMessages().length, 0);
+      assertEquals(0, getDownloadMessages().length);
     });
 
     test('no downloading messages with invalid language', () => {
       startDownload('simlish');
-      assertEquals(getDownloadMessages().length, 0);
+      assertEquals(0, getDownloadMessages().length);
     });
 
     suite('with one language', () => {
@@ -420,14 +420,14 @@
       test('shows downloading message while installing', () => {
         const msgs = getDownloadMessages();
 
-        assertEquals(msgs.length, 1);
+        assertEquals(1, msgs.length);
         assertStringContains(
             msgs[0]!.textContent!.trim(), 'Downloading Français voices');
       });
 
       test('hides downloading message when done', () => {
         finishDownload(lang);
-        assertEquals(getDownloadMessages().length, 0);
+        assertEquals(0, getDownloadMessages().length);
       });
     });
 
@@ -447,7 +447,7 @@
       test('shows downloading messages while installing', () => {
         const msgs = getDownloadMessages();
 
-        assertEquals(msgs.length, 4);
+        assertEquals(4, msgs.length);
         assertStringContains(
             msgs[0]!.textContent!.trim(),
             'Downloading English (United States) voices');
@@ -463,16 +463,16 @@
 
       test('hides downloading messages when done', () => {
         finishDownload(lang1);
-        assertEquals(getDownloadMessages().length, 3);
+        assertEquals(3, getDownloadMessages().length);
 
         finishDownload(lang2);
-        assertEquals(getDownloadMessages().length, 2);
+        assertEquals(2, getDownloadMessages().length);
 
         finishDownload(lang3);
-        assertEquals(getDownloadMessages().length, 1);
+        assertEquals(1, getDownloadMessages().length);
 
         finishDownload(lang4);
-        assertEquals(getDownloadMessages().length, 0);
+        assertEquals(0, getDownloadMessages().length);
       });
     });
   });
diff --git a/chrome/test/data/webui/side_panel/read_anything/voice_selection_test.ts b/chrome/test/data/webui/side_panel/read_anything/voice_selection_test.ts
index 70ab9a6..d101974 100644
--- a/chrome/test/data/webui/side_panel/read_anything/voice_selection_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/voice_selection_test.ts
@@ -6,7 +6,7 @@
 import type {ReadAnythingElement} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js';
 import {assertEquals} from 'chrome-untrusted://webui-test/chai_assert.js';
 
-import {suppressInnocuousErrors} from './common.js';
+import {createSpeechSynthesisVoice, suppressInnocuousErrors} from './common.js';
 import {FakeReadingMode} from './fake_reading_mode.js';
 import {FakeSpeechSynthesis} from './fake_speech_synthesis.js';
 import {TestColorUpdaterBrowserProxy} from './test_color_updater_browser_proxy.js';
@@ -16,17 +16,17 @@
   const pageLang = 'en';
   const differentLang = 'zh';
 
-  const firstVoiceWithLang = {
+  const firstVoiceWithLang = createSpeechSynthesisVoice({
     lang: defaultLang,
     name: 'Kristi',
-  } as SpeechSynthesisVoice;
-  const secondVoiceWithLang = {lang: defaultLang, name: 'Lauren'} as
-      SpeechSynthesisVoice;
-  const defaultVoiceForDifferentLang = {
+  });
+  const secondVoiceWithLang =
+      createSpeechSynthesisVoice({lang: defaultLang, name: 'Lauren'});
+  const defaultVoiceForDifferentLang = createSpeechSynthesisVoice({
     lang: differentLang,
     name: 'Eitan',
     default: true,
-  } as SpeechSynthesisVoice;
+  });
   const voices = [
     firstVoiceWithLang,
     secondVoiceWithLang,
@@ -64,21 +64,22 @@
     });
 
     test('it chooses the first voice with the same language', () => {
-      assertEquals(app.getSpeechSynthesisVoice(), firstVoiceWithLang);
+      assertEquals(firstVoiceWithLang, app.getSpeechSynthesisVoice());
     });
 
     test('it switches to a Natural voice if it later becomes available', () => {
       const voices = app.synth.getVoices();
       app.synth.getVoices = () => {
         return voices.concat(
-            {lang: defaultLang, name: 'Wall-e (Natural)'} as
-                SpeechSynthesisVoice,
-            {lang: defaultLang, name: 'Andy (Natural)'} as SpeechSynthesisVoice,
+            createSpeechSynthesisVoice(
+                {lang: defaultLang, name: 'Wall-e (Natural)'}),
+            createSpeechSynthesisVoice(
+                {lang: defaultLang, name: 'Andy (Natural)'}),
         );
       };
       app.onVoicesChanged();
 
-      assertEquals(app.getSpeechSynthesisVoice()?.name, 'Wall-e (Natural)');
+      assertEquals('Wall-e (Natural)', app.getSpeechSynthesisVoice()?.name);
     });
   });
 
@@ -88,7 +89,7 @@
       app.selectPreferredVoice();
     });
     test('it chooses the user stored voice', () => {
-      assertEquals(app.getSpeechSynthesisVoice(), secondVoiceWithLang);
+      assertEquals(secondVoiceWithLang, app.getSpeechSynthesisVoice());
     });
 
     test(
@@ -97,15 +98,15 @@
           const voices = app.synth.getVoices();
           app.synth.getVoices = () => {
             return voices.concat(
-                {lang: defaultLang, name: 'Wall-e (Natural)'} as
-                    SpeechSynthesisVoice,
-                {lang: defaultLang, name: 'Andy (Natural)'} as
-                    SpeechSynthesisVoice,
+                createSpeechSynthesisVoice(
+                    {lang: defaultLang, name: 'Wall-e (Natural)'}),
+                createSpeechSynthesisVoice(
+                    {lang: defaultLang, name: 'Andy (Natural)'}),
             );
           };
           app.onVoicesChanged();
 
-          assertEquals(app.getSpeechSynthesisVoice(), secondVoiceWithLang);
+          assertEquals(secondVoiceWithLang, app.getSpeechSynthesisVoice());
         });
   });
 });
diff --git a/chrome/test/data/webui/side_panel/read_anything/word_boundaries_used_for_speech.ts b/chrome/test/data/webui/side_panel/read_anything/word_boundaries_used_for_speech.ts
index 6109f7b8..bec0593 100644
--- a/chrome/test/data/webui/side_panel/read_anything/word_boundaries_used_for_speech.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/word_boundaries_used_for_speech.ts
@@ -10,7 +10,7 @@
 import {WordBoundaryMode} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js';
 import {assertEquals, assertTrue} from 'chrome-untrusted://webui-test/chai_assert.js';
 
-import {suppressInnocuousErrors} from './common.js';
+import {createSpeechSynthesisVoice, suppressInnocuousErrors} from './common.js';
 import {TestColorUpdaterBrowserProxy} from './test_color_updater_browser_proxy.js';
 
 suite('WordBoundariesUsedForSpeech', () => {
@@ -73,7 +73,8 @@
     document.body.appendChild(app);
     app.firstUtteranceSpoken = true;
     app.enabledLangs = ['en-US'];
-    app.selectedVoice = {lang: 'en', name: 'Kristi'} as SpeechSynthesisVoice;
+    app.selectedVoice =
+        createSpeechSynthesisVoice({lang: 'en', name: 'Kristi'});
     app.getSpeechSynthesisVoice();
     flush();
     playPauseButton =
@@ -85,9 +86,9 @@
   suite('by default', () => {
     test('wordBoundaryState in default state', () => {
       const state: WordBoundaryState = app.wordBoundaryState;
-      assertEquals(state.mode, WordBoundaryMode.BOUNDARIES_NOT_SUPPORTED);
-      assertEquals(state.previouslySpokenIndex, 0);
-      assertEquals(state.speechUtteranceStartIndex, 0);
+      assertEquals(WordBoundaryMode.BOUNDARIES_NOT_SUPPORTED, state.mode);
+      assertEquals(0, state.previouslySpokenIndex);
+      assertEquals(0, state.speechUtteranceStartIndex);
     });
   });
 
@@ -98,18 +99,18 @@
 
     test('wordBoundaryState in default state during speech', () => {
       const state: WordBoundaryState = app.wordBoundaryState;
-      assertEquals(state.mode, WordBoundaryMode.BOUNDARIES_NOT_SUPPORTED);
-      assertEquals(state.previouslySpokenIndex, 0);
-      assertEquals(state.speechUtteranceStartIndex, 0);
+      assertEquals(WordBoundaryMode.BOUNDARIES_NOT_SUPPORTED, state.mode);
+      assertEquals(0, state.previouslySpokenIndex);
+      assertEquals(0, state.speechUtteranceStartIndex);
     });
   });
 
   suite('by default', () => {
     test('wordBoundaryState in default state', () => {
       const state: WordBoundaryState = app.wordBoundaryState;
-      assertEquals(state.mode, WordBoundaryMode.BOUNDARIES_NOT_SUPPORTED);
-      assertEquals(state.previouslySpokenIndex, 0);
-      assertEquals(state.speechUtteranceStartIndex, 0);
+      assertEquals(WordBoundaryMode.BOUNDARIES_NOT_SUPPORTED, state.mode);
+      assertEquals(0, state.previouslySpokenIndex);
+      assertEquals(0, state.speechUtteranceStartIndex);
     });
   });
 
@@ -121,9 +122,9 @@
 
     test('wordBoundaryState uses most recent boundary', () => {
       const state: WordBoundaryState = app.wordBoundaryState;
-      assertEquals(state.mode, WordBoundaryMode.BOUNDARY_DETECTED);
-      assertEquals(state.previouslySpokenIndex, 10);
-      assertEquals(state.speechUtteranceStartIndex, 0);
+      assertEquals(WordBoundaryMode.BOUNDARY_DETECTED, state.mode);
+      assertEquals(10, state.previouslySpokenIndex);
+      assertEquals(0, state.speechUtteranceStartIndex);
     });
 
     test(
@@ -132,10 +133,10 @@
           playPauseButton.click();
           playPauseButton.click();
           const state: WordBoundaryState = app.wordBoundaryState;
-          assertEquals(state.mode, WordBoundaryMode.BOUNDARY_DETECTED);
+          assertEquals(WordBoundaryMode.BOUNDARY_DETECTED, state.mode);
           assertTrue(app.getSpeechSynthesisVoice() !== undefined);
-          assertEquals(state.previouslySpokenIndex, 0);
-          assertEquals(state.speechUtteranceStartIndex, 10);
+          assertEquals(0, state.previouslySpokenIndex);
+          assertEquals(10, state.speechUtteranceStartIndex);
         });
 
     test('word boundaries update after play / pause toggle', () => {
@@ -143,9 +144,9 @@
       playPauseButton.click();
       app.updateBoundary(3);
       const state: WordBoundaryState = app.wordBoundaryState;
-      assertEquals(state.mode, WordBoundaryMode.BOUNDARY_DETECTED);
-      assertEquals(state.previouslySpokenIndex, 3);
-      assertEquals(state.speechUtteranceStartIndex, 10);
+      assertEquals(WordBoundaryMode.BOUNDARY_DETECTED, state.mode);
+      assertEquals(3, state.previouslySpokenIndex);
+      assertEquals(10, state.speechUtteranceStartIndex);
     });
 
     test('word boundaries correct after multiple play / pause toggles', () => {
@@ -159,9 +160,9 @@
       playPauseButton.click();
       app.updateBoundary(1);
       const state: WordBoundaryState = app.wordBoundaryState;
-      assertEquals(state.mode, WordBoundaryMode.BOUNDARY_DETECTED);
-      assertEquals(state.previouslySpokenIndex, 1);
-      assertEquals(state.speechUtteranceStartIndex, 20);
+      assertEquals(WordBoundaryMode.BOUNDARY_DETECTED, state.mode);
+      assertEquals(1, state.previouslySpokenIndex);
+      assertEquals(20, state.speechUtteranceStartIndex);
     });
 
     test('sentence highlight used without flag', () => {
@@ -169,7 +170,7 @@
       const currentHighlight =
           app.$.container.querySelector('.current-read-highlight');
       assertTrue(currentHighlight !== undefined);
-      assertEquals(currentHighlight!.textContent, 'This is a link.');
+      assertEquals('This is a link.', currentHighlight!.textContent);
     });
   });
 
@@ -184,9 +185,9 @@
 
     test('wordBoundaryState in default state during speech', () => {
       const state: WordBoundaryState = app.wordBoundaryState;
-      assertEquals(state.mode, WordBoundaryMode.BOUNDARY_DETECTED);
-      assertEquals(state.previouslySpokenIndex, 40);
-      assertEquals(state.speechUtteranceStartIndex, 0);
+      assertEquals(WordBoundaryMode.BOUNDARY_DETECTED, state.mode);
+      assertEquals(40, state.previouslySpokenIndex);
+      assertEquals(0, state.speechUtteranceStartIndex);
     });
   });
 });
diff --git a/chrome/test/data/webui/side_panel/read_anything/word_highlighting.ts b/chrome/test/data/webui/side_panel/read_anything/word_highlighting.ts
index b9088d9..bd04fb1 100644
--- a/chrome/test/data/webui/side_panel/read_anything/word_highlighting.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/word_highlighting.ts
@@ -99,7 +99,7 @@
       const currentHighlight =
           app.$.container.querySelector('.current-read-highlight');
       assertTrue(currentHighlight !== undefined);
-      assertEquals(currentHighlight!.textContent, 'This is a link.');
+      assertEquals('This is a link.', currentHighlight!.textContent);
     });
   });
 
@@ -112,7 +112,7 @@
       const currentHighlight =
           app.$.container.querySelector('.current-read-highlight');
       assertTrue(currentHighlight !== undefined);
-      assertEquals(currentHighlight!.textContent, 'This is a link.');
+      assertEquals('This is a link.', currentHighlight!.textContent);
     });
   });
 });
diff --git a/chrome/test/fuzzing/in_process_fuzzer.cc b/chrome/test/fuzzing/in_process_fuzzer.cc
index c944601..89f872537 100644
--- a/chrome/test/fuzzing/in_process_fuzzer.cc
+++ b/chrome/test/fuzzing/in_process_fuzzer.cc
@@ -122,6 +122,25 @@
 
 void InProcessFuzzer::SetUpOnMainThread() {
   InProcessBrowserTest::SetUpOnMainThread();
+
+  // All of the engines that are being used to run those fuzzers are handling
+  // process interruption. In case we let Chrome handle those signals itself,
+  // we end up exiting the fuzzing process, and the engine records the last
+  // run as a crash since it cannot not determine the reason why the process
+  // terminated.
+#if BUILDFLAG(IS_POSIX)
+  signal(SIGTERM, SIG_DFL);
+  signal(SIGINT, SIG_DFL);
+#if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
+  // In case we're being built with a memory tool (asan, msan...), we should
+  // let it handle this signal so that we get better reporting.
+  // As of now, since both in-process stack traces and the crashpad handler are
+  // being disabled, this is the only signal that we need to reset since it's
+  // being set in
+  // https://source.chromium.org/chromium/chromium/src/+/main:content/public/test/browser_test_base.cc?q=SignalHandler
+  signal(SIGSEGV, SIG_DFL);
+#endif  // BUILDFLAG(MEMORY_TOOL_REPLACES_ALLOCATOR)
+#endif  // BUILDFLAG(IS_POSIX)
 }
 
 InProcessFuzzer* g_test;
@@ -280,6 +299,15 @@
     chromium_arguments.push_back(FILE_PATH_LITERAL("--no-sandbox"));
     chromium_arguments.push_back(FILE_PATH_LITERAL("--no-zygote"));
     chromium_arguments.push_back(FILE_PATH_LITERAL("--disable-gpu"));
+    chromium_arguments.push_back(
+        FILE_PATH_LITERAL("--disable-crashpad-for-testing"));
+#if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
+    // We disable in-process stack trace handling in case we're using memory
+    // tools so that we get better reporting on what happened in case of
+    // SIGSEGV.
+    chromium_arguments.push_back(
+        FILE_PATH_LITERAL("--disable-in-process-stack-traces"));
+#endif
     base::CommandLine::ForCurrentProcess()->InitFromArgv(chromium_arguments);
 
     // Various bits of setup are done by base::TestSuite::Initialize.
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn
index 88c445a..5f6f19df 100644
--- a/chrome/updater/BUILD.gn
+++ b/chrome/updater/BUILD.gn
@@ -91,16 +91,12 @@
       "crash_reporter.cc",
       "crash_reporter.h",
       "crx_downloader_factory.h",
-      "device_management/dm_cached_policy_info.cc",
-      "device_management/dm_cached_policy_info.h",
       "device_management/dm_client.cc",
       "device_management/dm_client.h",
       "device_management/dm_message.cc",
       "device_management/dm_message.h",
       "device_management/dm_response_validator.cc",
       "device_management/dm_response_validator.h",
-      "device_management/dm_storage.cc",
-      "device_management/dm_storage.h",
       "find_unregistered_apps_task.cc",
       "find_unregistered_apps_task.h",
       "installer.cc",
@@ -157,6 +153,7 @@
       "//base",
       "//base:i18n",
       "//build:chromeos_buildflags",
+      "//chrome/enterprise_companion/device_management_storage",
       "//chrome/updater/protos:omaha_proto",
       "//components/crash/core/common",
       "//components/crx_file",
@@ -194,7 +191,6 @@
       sources += [
         "activity_impl_util_mac.cc",
         "app/app_server_posix_mac.cc",
-        "device_management/dm_storage_mac.mm",
         "installer_mac.cc",
         "ipc/ipc_security_mac.cc",
         "mac/install_from_archive.h",
@@ -248,7 +244,6 @@
         "app/server/win/update_service_stub_win.h",
         "app/server/win/wrl_classes.cc",
         "change_owners_task_win.cc",
-        "device_management/dm_storage_win.cc",
         "ipc/update_service_internal_proxy_win.cc",
         "ipc/update_service_internal_proxy_win.h",
         "net/network_fetcher_win.cc",
@@ -360,7 +355,6 @@
       sources += [
         "activity_impl_util_linux.cc",
         "app/app_server_posix_linux.cc",
-        "device_management/dm_storage_linux.cc",
         "installer_linux.cc",
         "ipc/ipc_security_linux.cc",
         "linux/setup/setup.cc",
@@ -757,7 +751,6 @@
       "device_management/dm_policy_builder_for_testing.cc",
       "device_management/dm_policy_builder_for_testing.h",
       "device_management/dm_response_validator_unittest.cc",
-      "device_management/dm_storage_unittest.cc",
       "enum_traits_unittest.cc",
       "external_constants_builder.cc",
       "external_constants_builder.h",
@@ -805,6 +798,7 @@
       "//base",
       "//base/test:test_support",
       "//chrome/common:constants",
+      "//chrome/enterprise_companion/device_management_storage",
       "//chrome/updater/protos:omaha_proto",
       "//components/crx_file",
       "//components/policy/proto",
diff --git a/chrome/updater/DEPS b/chrome/updater/DEPS
index 04f8476..43214f9 100644
--- a/chrome/updater/DEPS
+++ b/chrome/updater/DEPS
@@ -1,5 +1,6 @@
 include_rules = [
   "+chrome/common",
+  "+chrome/enterprise_companion/device_management_storage",
   "+chrome/installer/util",
   "+components/crash/core/common",
   "+components/crx_file",
@@ -18,8 +19,8 @@
   "+third_party/crashpad",
   "+third_party/re2",
   "+third_party/updater",
-  "+third_party/zlib/google",
   "+third_party/wtl",
+  "+third_party/zlib/google",
 
   # The metainstaller should not depend on ICU, to minimize binary size.
   "-base/i18n",
diff --git a/chrome/updater/certificate_tag_internal.h b/chrome/updater/certificate_tag_internal.h
index a3808aa..5b18df7 100644
--- a/chrome/updater/certificate_tag_internal.h
+++ b/chrome/updater/certificate_tag_internal.h
@@ -16,6 +16,7 @@
 
 #include "base/containers/span.h"
 #include "base/gtest_prod_util.h"
+#include "base/memory/raw_span.h"
 #include "third_party/boringssl/src/include/openssl/bytestring.h"
 #include "third_party/boringssl/src/include/openssl/crypto.h"
 
@@ -49,10 +50,10 @@
   bool ParseTag();
 
   // binary_ contains the whole input binary.
-  base::span<const uint8_t> binary_;
+  base::raw_span<const uint8_t> binary_;
 
   // content_info_ contains the `WIN_CERTIFICATE` structure.
-  base::span<const uint8_t> content_info_;
+  base::raw_span<const uint8_t> content_info_;
 
   // tag_ contains the embedded tag, or `nullopt` if there isn't one.
   std::optional<std::vector<uint8_t>> tag_;
diff --git a/chrome/updater/device_management/dm_cached_policy_info.cc b/chrome/updater/device_management/dm_cached_policy_info.cc
deleted file mode 100644
index 254de187..0000000
--- a/chrome/updater/device_management/dm_cached_policy_info.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/updater/device_management/dm_cached_policy_info.h"
-
-#include "components/policy/proto/device_management_backend.pb.h"
-
-namespace updater {
-
-CachedPolicyInfo::CachedPolicyInfo() : key_version_(-1), timestamp_(0) {}
-CachedPolicyInfo::~CachedPolicyInfo() = default;
-
-bool CachedPolicyInfo::Populate(const std::string& raw_response) {
-  ::enterprise_management::PolicyFetchResponse response;
-  ::enterprise_management::PolicyData policy_data;
-  ::enterprise_management::PublicKeyVerificationData verification_data;
-  if (raw_response.empty() || !response.ParseFromString(raw_response) ||
-      !policy_data.ParseFromString(response.policy_data()) ||
-      !policy_data.has_timestamp() ||
-      !response.has_new_public_key_verification_data() ||
-      !verification_data.ParseFromString(
-          response.new_public_key_verification_data())) {
-    return false;
-  }
-
-  key_ = verification_data.new_public_key();
-  if (verification_data.has_new_public_key_version()) {
-    key_version_ = verification_data.new_public_key_version();
-  }
-  timestamp_ = policy_data.timestamp();
-  return true;
-}
-
-}  // namespace updater
diff --git a/chrome/updater/device_management/dm_cached_policy_info.h b/chrome/updater/device_management/dm_cached_policy_info.h
deleted file mode 100644
index c02bda6b..0000000
--- a/chrome/updater/device_management/dm_cached_policy_info.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_UPDATER_DEVICE_MANAGEMENT_DM_CACHED_POLICY_INFO_H_
-#define CHROME_UPDATER_DEVICE_MANAGEMENT_DM_CACHED_POLICY_INFO_H_
-
-#include <stdint.h>
-
-#include <string>
-
-namespace updater {
-
-class CachedPolicyInfo {
- public:
-  CachedPolicyInfo();
-  ~CachedPolicyInfo();
-
-  // Populate members with serialized data of DM PolicyFetchResponse.
-  bool Populate(const std::string& raw_response);
-
-  // Public key of the policy.
-  std::string public_key() const { return key_; }
-
-  // Version of the public key. -1 means the key is not versioned or unknown.
-  int32_t key_version() const { return key_version_; }
-
-  bool has_key_version() const { return key_version_ >= 0; }
-
-  // Signing timestamp.
-  int64_t timestamp() const { return timestamp_; }
-
- private:
-  std::string key_;
-  int32_t key_version_;
-  int64_t timestamp_;
-};
-
-}  // namespace updater
-
-#endif  // CHROME_UPDATER_DEVICE_MANAGEMENT_DM_CACHED_POLICY_INFO_H_
diff --git a/chrome/updater/device_management/dm_client.cc b/chrome/updater/device_management/dm_client.cc
index 3eb84963..02d070a 100644
--- a/chrome/updater/device_management/dm_client.cc
+++ b/chrome/updater/device_management/dm_client.cc
@@ -22,9 +22,9 @@
 #include "base/system/sys_info.h"
 #include "base/task/sequenced_task_runner.h"
 #include "build/build_config.h"
-#include "chrome/updater/device_management/dm_cached_policy_info.h"
+#include "chrome/enterprise_companion/device_management_storage/dm_storage.h"
+#include "chrome/updater/device_management/dm_message.h"
 #include "chrome/updater/device_management/dm_response_validator.h"
-#include "chrome/updater/device_management/dm_storage.h"
 #include "chrome/updater/net/network.h"
 #include "chrome/updater/policy/service.h"
 #include "chrome/updater/updater_branding.h"
@@ -127,14 +127,16 @@
                               std::unique_ptr<std::string> response_body)>;
 
   DMFetch(std::unique_ptr<DMClient::Configurator> config,
-          scoped_refptr<DMStorage> storage);
+          scoped_refptr<device_management_storage::DMStorage> storage);
   DMFetch(const DMFetch&) = delete;
   DMFetch& operator=(const DMFetch&) = delete;
 
   const DMClient::Configurator* config() const { return config_.get(); }
 
   // Returns the storage where this client saves the data from DM server.
-  scoped_refptr<DMStorage> storage() const { return storage_; }
+  scoped_refptr<device_management_storage::DMStorage> storage() const {
+    return storage_;
+  }
 
   void PostRequest(const std::string& request_type,
                    TokenType token_type,
@@ -164,7 +166,7 @@
                          int64_t xheader_retry_after_sec);
 
   std::unique_ptr<DMClient::Configurator> config_;
-  scoped_refptr<DMStorage> storage_;
+  scoped_refptr<device_management_storage::DMStorage> storage_;
 
   std::unique_ptr<update_client::NetworkFetcher> network_fetcher_;
   int http_status_code_ = 0;
@@ -174,7 +176,7 @@
 };
 
 DMFetch::DMFetch(std::unique_ptr<DMClient::Configurator> config,
-                 scoped_refptr<DMStorage> storage)
+                 scoped_refptr<device_management_storage::DMStorage> storage)
     : config_(std::move(config)),
       storage_(storage),
       network_fetcher_(config_->CreateNetworkFetcher()) {}
@@ -321,14 +323,15 @@
 void OnDMPolicyFetchRequestComplete(
     scoped_refptr<DMFetch> dm_fetch,
     DMClient::PolicyFetchCallback callback,
-    std::unique_ptr<CachedPolicyInfo> cached_info,
+    std::unique_ptr<device_management_storage::CachedPolicyInfo> cached_info,
     DMClient::RequestResult result,
     std::unique_ptr<std::string> response_body) {
   VLOG(2) << __func__ << ": result=" << result;
   std::vector<PolicyValidationResult> validation_results;
-  scoped_refptr<DMStorage> storage = dm_fetch->storage();
+  scoped_refptr<device_management_storage::DMStorage> storage =
+      dm_fetch->storage();
   if (result == DMClient::RequestResult::kSuccess) {
-    DMPolicyMap policies = ParsePolicyFetchResponse(
+    device_management_storage::DMPolicyMap policies = ParsePolicyFetchResponse(
         *response_body, *cached_info, storage->GetDmToken(),
         storage->GetDeviceID(), validation_results);
 
@@ -362,9 +365,10 @@
 
 }  // namespace
 
-void DMClient::RegisterDevice(std::unique_ptr<Configurator> config,
-                              scoped_refptr<DMStorage> storage,
-                              RegisterCallback callback) {
+void DMClient::RegisterDevice(
+    std::unique_ptr<Configurator> config,
+    scoped_refptr<device_management_storage::DMStorage> storage,
+    RegisterCallback callback) {
   VLOG(2) << __func__;
   auto dm_fetch = base::MakeRefCounted<DMFetch>(std::move(config), storage);
   dm_fetch->PostRequest(kRegistrationRequestType,
@@ -374,9 +378,10 @@
                                        std::move(callback)));
 }
 
-void DMClient::FetchPolicy(std::unique_ptr<Configurator> config,
-                           scoped_refptr<DMStorage> storage,
-                           PolicyFetchCallback callback) {
+void DMClient::FetchPolicy(
+    std::unique_ptr<Configurator> config,
+    scoped_refptr<device_management_storage::DMStorage> storage,
+    PolicyFetchCallback callback) {
   VLOG(2) << __func__;
   if (!storage->CanPersistPolicies()) {
     VLOG(2) << "Cannot persist policies.";
@@ -388,7 +393,7 @@
   }
 
   auto dm_fetch = base::MakeRefCounted<DMFetch>(std::move(config), storage);
-  std::unique_ptr<CachedPolicyInfo> cached_info =
+  std::unique_ptr<device_management_storage::CachedPolicyInfo> cached_info =
       dm_fetch->storage()->GetCachedPolicyInfo();
   const std::string request_data =
       GetPolicyFetchRequestData(kGoogleUpdateMachineLevelApps, *cached_info);
@@ -400,7 +405,7 @@
 
 void DMClient::ReportPolicyValidationErrors(
     std::unique_ptr<Configurator> config,
-    scoped_refptr<DMStorage> storage,
+    scoped_refptr<device_management_storage::DMStorage> storage,
     const PolicyValidationResult& validation_result,
     PolicyValidationReportCallback callback) {
   VLOG(2) << __func__;
diff --git a/chrome/updater/device_management/dm_client.h b/chrome/updater/device_management/dm_client.h
index 1b7f7e5..7798053 100644
--- a/chrome/updater/device_management/dm_client.h
+++ b/chrome/updater/device_management/dm_client.h
@@ -13,6 +13,7 @@
 
 #include "base/functional/callback.h"
 #include "base/memory/scoped_refptr.h"
+#include "chrome/enterprise_companion/device_management_storage/dm_storage.h"
 
 class GURL;
 
@@ -107,9 +108,10 @@
   //   3) Server unregisters the device and the device is marked as such.
   //   4) Registration fails, device status is not changed.
   //
-  static void RegisterDevice(std::unique_ptr<Configurator> config,
-                             scoped_refptr<DMStorage> storage,
-                             RegisterCallback callback);
+  static void RegisterDevice(
+      std::unique_ptr<Configurator> config,
+      scoped_refptr<device_management_storage::DMStorage> storage,
+      RegisterCallback callback);
 
   // Fetches policies from the DM server.
   // Possible outcome:
@@ -121,9 +123,10 @@
   //      exits management.
   //   4) Fetch fails, device status is not changed.
   //
-  static void FetchPolicy(std::unique_ptr<Configurator> config,
-                          scoped_refptr<DMStorage> storage,
-                          PolicyFetchCallback callback);
+  static void FetchPolicy(
+      std::unique_ptr<Configurator> config,
+      scoped_refptr<device_management_storage::DMStorage> storage,
+      PolicyFetchCallback callback);
 
   // Posts the policy validation report back to DM server.
   // The report request is skipped if there's no valid DM token or
@@ -132,7 +135,7 @@
   //
   static void ReportPolicyValidationErrors(
       std::unique_ptr<Configurator> config,
-      scoped_refptr<DMStorage> storage,
+      scoped_refptr<device_management_storage::DMStorage> storage,
       const PolicyValidationResult& validation_result,
       PolicyValidationReportCallback callback);
 
diff --git a/chrome/updater/device_management/dm_client_unittest.cc b/chrome/updater/device_management/dm_client_unittest.cc
index 1663bab2..cb029fb1 100644
--- a/chrome/updater/device_management/dm_client_unittest.cc
+++ b/chrome/updater/device_management/dm_client_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <sstream>
 #include <string>
 #include <utility>
@@ -18,12 +19,12 @@
 #include "base/test/gmock_callback_support.h"
 #include "base/test/task_environment.h"
 #include "build/build_config.h"
-#include "chrome/updater/device_management/dm_cached_policy_info.h"
+#include "chrome/enterprise_companion/device_management_storage/dm_storage.h"
 #include "chrome/updater/device_management/dm_message.h"
 #include "chrome/updater/device_management/dm_policy_builder_for_testing.h"
 #include "chrome/updater/device_management/dm_response_validator.h"
-#include "chrome/updater/device_management/dm_storage.h"
 #include "chrome/updater/net/network.h"
+#include "chrome/updater/policy/dm_policy_manager.h"
 #include "chrome/updater/policy/service.h"
 #include "chrome/updater/protos/omaha_settings.pb.h"
 #include "chrome/updater/test/unit_test_util.h"
@@ -43,7 +44,8 @@
 namespace updater {
 namespace {
 
-class TestTokenService : public TokenServiceInterface {
+class TestTokenService
+    : public device_management_storage::TokenServiceInterface {
  public:
   TestTokenService(const std::string& enrollment_token,
                    const std::string& dm_token)
@@ -127,7 +129,7 @@
     ASSERT_TRUE(storage_dir_.CreateUniqueTempDir());
     constexpr char kEnrollmentToken[] = "TestEnrollmentToken";
     constexpr char kDmToken[] = "test-dm-token";
-    storage_ = base::MakeRefCounted<DMStorage>(
+    storage_ = base::MakeRefCounted<device_management_storage::DMStorage>(
         storage_dir_.GetPath(),
         std::make_unique<TestTokenService>(kEnrollmentToken,
                                            init_dm_token ? kDmToken : ""));
@@ -138,7 +140,8 @@
           dm_response = GetDefaultTestingPolicyFetchDMResponse(
               /*first_request=*/true, /*rotate_to_new_key=*/false,
               DMPolicyBuilderForTesting::SigningOption::kSignNormally);
-      std::unique_ptr<CachedPolicyInfo> info = storage_->GetCachedPolicyInfo();
+      std::unique_ptr<device_management_storage::CachedPolicyInfo> info =
+          storage_->GetCachedPolicyInfo();
       std::vector<PolicyValidationResult> validation_results;
       DMPolicyMap policies = ParsePolicyFetchResponse(
           dm_response->SerializeAsString(), *info.get(), storage_->GetDmToken(),
@@ -160,13 +163,15 @@
     expected_public_key_type_ = expect_key_type;
   }
 
-  scoped_refptr<DMStorage> GetStorage() { return storage_; }
+  scoped_refptr<device_management_storage::DMStorage> GetStorage() {
+    return storage_;
+  }
 
  protected:
   virtual ~DMRequestCallbackHandler() = default;
 
   base::ScopedTempDir storage_dir_;
-  scoped_refptr<DMStorage> storage_;
+  scoped_refptr<device_management_storage::DMStorage> storage_;
 
   net::HttpStatusCode expected_http_status_ = net::HTTP_OK;
   DMClient::RequestResult expected_result_ = DMClient::RequestResult::kSuccess;
@@ -223,7 +228,8 @@
       return;
     }
 
-    std::unique_ptr<CachedPolicyInfo> info = storage_->GetCachedPolicyInfo();
+    std::unique_ptr<device_management_storage::CachedPolicyInfo> info =
+        storage_->GetCachedPolicyInfo();
     switch (expected_public_key_type_) {
       case PublicKeyType::kTestKey1:
         EXPECT_EQ(info->public_key(), GetTestKey1()->GetPublicKeyString());
@@ -238,10 +244,10 @@
     }
 
     if (result == DMClient::RequestResult::kSuccess) {
-      std::unique_ptr<::wireless_android_enterprise_devicemanagement::
-                          OmahaSettingsClientProto>
-          omaha_settings = storage_->GetOmahaPolicySettings();
-      EXPECT_NE(omaha_settings, nullptr);
+      std::optional<::wireless_android_enterprise_devicemanagement::
+                        OmahaSettingsClientProto>
+          omaha_settings = GetOmahaPolicySettings(storage_);
+      EXPECT_TRUE(omaha_settings);
 
       // Sample some of the policy values and check they are expected.
       EXPECT_EQ(omaha_settings->proxy_mode(), "pac_script");
diff --git a/chrome/updater/device_management/dm_message.cc b/chrome/updater/device_management/dm_message.cc
index 006697ba..4ae4aaf 100644
--- a/chrome/updater/device_management/dm_message.cc
+++ b/chrome/updater/device_management/dm_message.cc
@@ -10,6 +10,7 @@
 #include "base/containers/fixed_flat_map.h"
 #include "base/logging.h"
 #include "base/ranges/algorithm.h"
+#include "chrome/enterprise_companion/device_management_storage/dm_storage.h"
 #include "chrome/updater/device_management/dm_response_validator.h"
 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
 #include "components/policy/core/common/cloud/cloud_policy_util.h"
@@ -92,8 +93,9 @@
   return dm_request.SerializeAsString();
 }
 
-std::string GetPolicyFetchRequestData(const std::string& policy_type,
-                                      const CachedPolicyInfo& policy_info) {
+std::string GetPolicyFetchRequestData(
+    const std::string& policy_type,
+    const device_management_storage::CachedPolicyInfo& policy_info) {
   enterprise_management::DeviceManagementRequest dm_request;
   enterprise_management::DevicePolicyRequest* device_policy_request =
       dm_request.mutable_policy_request();
@@ -189,7 +191,7 @@
 
 DMPolicyMap ParsePolicyFetchResponse(
     const std::string& response_data,
-    const CachedPolicyInfo& policy_info,
+    const device_management_storage::CachedPolicyInfo& policy_info,
     const std::string& expected_dm_token,
     const std::string& expected_device_id,
     std::vector<PolicyValidationResult>& validation_results) {
diff --git a/chrome/updater/device_management/dm_message.h b/chrome/updater/device_management/dm_message.h
index 5e10ef5..5257514 100644
--- a/chrome/updater/device_management/dm_message.h
+++ b/chrome/updater/device_management/dm_message.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/containers/flat_map.h"
+#include "chrome/enterprise_companion/device_management_storage/dm_storage.h"
 
 namespace updater {
 
@@ -27,8 +28,9 @@
 
 // Returns the serialized data from a DeviceManagementRequest, which wraps
 // a PolicyFetchRequest, to fetch policies for the given type.
-std::string GetPolicyFetchRequestData(const std::string& policy_type,
-                                      const CachedPolicyInfo& policy_info);
+std::string GetPolicyFetchRequestData(
+    const std::string& policy_type,
+    const device_management_storage::CachedPolicyInfo& policy_info);
 
 // Returns the serialized data from a DeviceManagementRequest, which wraps
 // a PolicyValidationReportRequest, to report possible policy validation errors.
@@ -51,7 +53,7 @@
 // response's the signatures and whether it is intended for current device.
 DMPolicyMap ParsePolicyFetchResponse(
     const std::string& response_data,
-    const CachedPolicyInfo& policy_info,
+    const device_management_storage::CachedPolicyInfo& policy_info,
     const std::string& expected_dm_token,
     const std::string& expected_device_id,
     std::vector<PolicyValidationResult>& validation_results);
diff --git a/chrome/updater/device_management/dm_message_unittest.cc b/chrome/updater/device_management/dm_message_unittest.cc
index 81d397af..3495dd6 100644
--- a/chrome/updater/device_management/dm_message_unittest.cc
+++ b/chrome/updater/device_management/dm_message_unittest.cc
@@ -11,7 +11,7 @@
 #include <utility>
 
 #include "base/time/time.h"
-#include "chrome/updater/device_management/dm_cached_policy_info.h"
+#include "chrome/enterprise_companion/device_management_storage/dm_storage.h"
 #include "chrome/updater/device_management/dm_policy_builder_for_testing.h"
 #include "chrome/updater/device_management/dm_response_validator.h"
 #include "chrome/updater/protos/omaha_settings.pb.h"
@@ -39,7 +39,7 @@
       policy_builder->GetResponseBlobForPolicyPayload(
           policy_type, omaha_settings->SerializeAsString()));
 
-  CachedPolicyInfo policy_info;
+  device_management_storage::CachedPolicyInfo policy_info;
   ASSERT_TRUE(policy_info.Populate(policy_response_string));
   const std::string request_data =
       GetPolicyFetchRequestData(policy_type, policy_info);
@@ -73,7 +73,7 @@
           true /* first_request */, false /* rotate_to_new_key */,
           DMPolicyBuilderForTesting::SigningOption::kSignNormally);
 
-  CachedPolicyInfo initial_policy_info;
+  device_management_storage::CachedPolicyInfo initial_policy_info;
   std::vector<PolicyValidationResult> validation_results;
   DMPolicyMap policy_map = ParsePolicyFetchResponse(
       dm_response->SerializeAsString(), initial_policy_info, "test-dm-token",
@@ -83,7 +83,7 @@
   EXPECT_NE(policy_map.find(policy_type), policy_map.end());
   std::string policy_data = policy_map[policy_type];
 
-  CachedPolicyInfo updated_policy_info;
+  device_management_storage::CachedPolicyInfo updated_policy_info;
   updated_policy_info.Populate(policy_data);
   EXPECT_FALSE(updated_policy_info.public_key().empty());
   EXPECT_GE(base::Time::UnixEpoch() +
@@ -101,7 +101,7 @@
   EXPECT_EQ(policy_map.size(), size_t{1});
   EXPECT_NE(policy_map.find(policy_type), policy_map.end());
 
-  CachedPolicyInfo updated_policy_info2;
+  device_management_storage::CachedPolicyInfo updated_policy_info2;
   updated_policy_info.Populate(policy_map[policy_type]);
   EXPECT_TRUE(updated_policy_info2.public_key().empty());
 
@@ -118,7 +118,7 @@
   EXPECT_NE(policy_map.find(policy_type), policy_map.end());
 
   // Verify that we got a new public key.
-  CachedPolicyInfo updated_policy_info3;
+  device_management_storage::CachedPolicyInfo updated_policy_info3;
   updated_policy_info3.Populate(policy_map[policy_type]);
   std::string new_public_key = updated_policy_info3.public_key();
   EXPECT_FALSE(new_public_key.empty());
@@ -137,7 +137,7 @@
           DMPolicyBuilderForTesting::SigningOption::kSignNormally);
   const std::string dm_response_data = dm_response->SerializeAsString();
 
-  CachedPolicyInfo initial_policy_info;
+  device_management_storage::CachedPolicyInfo initial_policy_info;
   const std::string bad_dm_token = "bad-dm-token";
   std::vector<PolicyValidationResult> validation_results;
   DMPolicyMap policy_map = ParsePolicyFetchResponse(
@@ -189,7 +189,7 @@
                                         initial_policy_info, "test-dm-token",
                                         "test-device-id", validation_results);
   EXPECT_TRUE(validation_results.empty());
-  CachedPolicyInfo updated_policy_info;
+  device_management_storage::CachedPolicyInfo updated_policy_info;
   updated_policy_info.Populate(policy_map[policy_type]);
   EXPECT_FALSE(updated_policy_info.public_key().empty());
 
diff --git a/chrome/updater/device_management/dm_response_validator.cc b/chrome/updater/device_management/dm_response_validator.cc
index a07ab25..7e67ce9 100644
--- a/chrome/updater/device_management/dm_response_validator.cc
+++ b/chrome/updater/device_management/dm_response_validator.cc
@@ -14,8 +14,8 @@
 #include "base/logging.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/enterprise_companion/device_management_storage/dm_storage.h"
 #include "chrome/updater/constants.h"
-#include "chrome/updater/device_management/dm_cached_policy_info.h"
 #include "chrome/updater/device_management/dm_message.h"
 #include "chrome/updater/protos/omaha_settings.pb.h"
 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
@@ -267,9 +267,10 @@
     const PolicyValidationResult& other) = default;
 PolicyValidationResult::~PolicyValidationResult() = default;
 
-DMResponseValidator::DMResponseValidator(const CachedPolicyInfo& policy_info,
-                                         const std::string& expected_dm_token,
-                                         const std::string& expected_device_id)
+DMResponseValidator::DMResponseValidator(
+    const device_management_storage::CachedPolicyInfo& policy_info,
+    const std::string& expected_dm_token,
+    const std::string& expected_device_id)
     : policy_info_(policy_info),
       expected_dm_token_(expected_dm_token),
       expected_device_id_(expected_device_id) {}
diff --git a/chrome/updater/device_management/dm_response_validator.h b/chrome/updater/device_management/dm_response_validator.h
index 587d7374..34abe38 100644
--- a/chrome/updater/device_management/dm_response_validator.h
+++ b/chrome/updater/device_management/dm_response_validator.h
@@ -9,7 +9,7 @@
 #include <vector>
 
 #include "base/ranges/algorithm.h"
-#include "chrome/updater/device_management/dm_cached_policy_info.h"
+#include "chrome/enterprise_companion/device_management_storage/dm_storage.h"
 
 namespace enterprise_management {
 
@@ -98,9 +98,10 @@
 
 class DMResponseValidator {
  public:
-  DMResponseValidator(const CachedPolicyInfo& policy_info,
-                      const std::string& expected_dm_token,
-                      const std::string& expected_device_id);
+  DMResponseValidator(
+      const device_management_storage::CachedPolicyInfo& policy_info,
+      const std::string& expected_dm_token,
+      const std::string& expected_device_id);
   ~DMResponseValidator();
 
   // Validates a single policy fetch response.
@@ -153,7 +154,7 @@
       const enterprise_management::PolicyData& policy_data,
       PolicyValidationResult& validation_result) const;
 
-  const CachedPolicyInfo policy_info_;
+  const device_management_storage::CachedPolicyInfo policy_info_;
   const std::string expected_dm_token_;
   const std::string expected_device_id_;
 };
diff --git a/chrome/updater/device_management/dm_response_validator_unittest.cc b/chrome/updater/device_management/dm_response_validator_unittest.cc
index e1b4cd6..f8f328e5 100644
--- a/chrome/updater/device_management/dm_response_validator_unittest.cc
+++ b/chrome/updater/device_management/dm_response_validator_unittest.cc
@@ -8,7 +8,7 @@
 #include <memory>
 #include <utility>
 
-#include "chrome/updater/device_management/dm_cached_policy_info.h"
+#include "chrome/enterprise_companion/device_management_storage/dm_storage.h"
 #include "chrome/updater/device_management/dm_message.h"
 #include "chrome/updater/device_management/dm_policy_builder_for_testing.h"
 #include "chrome/updater/protos/omaha_settings.pb.h"
@@ -22,7 +22,8 @@
 
 class DMResponseValidatorTests : public ::testing::Test {
  protected:
-  void GetCachedInfoWithPublicKey(CachedPolicyInfo& cached_info) const;
+  void GetCachedInfoWithPublicKey(
+      device_management_storage::CachedPolicyInfo& cached_info) const;
 
   std::unique_ptr<::enterprise_management::DeviceManagementResponse>
   GetDMResponseWithOmahaPolicy(
@@ -30,7 +31,7 @@
 };
 
 void DMResponseValidatorTests::GetCachedInfoWithPublicKey(
-    CachedPolicyInfo& cached_info) const {
+    device_management_storage::CachedPolicyInfo& cached_info) const {
   std::unique_ptr<::enterprise_management::DeviceManagementResponse>
       dm_response = GetDefaultTestingPolicyFetchDMResponse(
           /*first_request=*/true, /*rotate_to_new_key=*/false,
@@ -69,8 +70,8 @@
   const ::enterprise_management::PolicyFetchResponse& response =
       dm_response->policy_response().responses(0);
 
-  DMResponseValidator validator(CachedPolicyInfo(), "test-dm-token",
-                                "test-device-id");
+  DMResponseValidator validator(device_management_storage::CachedPolicyInfo(),
+                                "test-dm-token", "test-device-id");
   PolicyValidationResult validation_result;
   EXPECT_TRUE(validator.ValidatePolicyResponse(response, validation_result));
   EXPECT_EQ(validation_result.status,
@@ -80,7 +81,7 @@
 
 TEST_F(DMResponseValidatorTests, ValidationOKWithPublicKey) {
   // Cached info should be created before parsing next policy response.
-  CachedPolicyInfo cached_info;
+  device_management_storage::CachedPolicyInfo cached_info;
   GetCachedInfoWithPublicKey(cached_info);
 
   std::unique_ptr<::enterprise_management::DeviceManagementResponse>
@@ -110,8 +111,8 @@
   const ::enterprise_management::PolicyFetchResponse& response =
       dm_response->policy_response().responses(0);
 
-  DMResponseValidator validator(CachedPolicyInfo(), "wrong-dm-token",
-                                "test-device-id");
+  DMResponseValidator validator(device_management_storage::CachedPolicyInfo(),
+                                "wrong-dm-token", "test-device-id");
   PolicyValidationResult validation_result;
   EXPECT_FALSE(validator.ValidatePolicyResponse(response, validation_result));
   EXPECT_EQ(validation_result.policy_type, "google/machine-level-omaha");
@@ -130,8 +131,8 @@
   const ::enterprise_management::PolicyFetchResponse& response =
       dm_response->policy_response().responses(0);
 
-  DMResponseValidator validator(CachedPolicyInfo(), "test-dm-token",
-                                "unexpected-device-id");
+  DMResponseValidator validator(device_management_storage::CachedPolicyInfo(),
+                                "test-dm-token", "unexpected-device-id");
   PolicyValidationResult validation_result;
   EXPECT_FALSE(validator.ValidatePolicyResponse(response, validation_result));
   EXPECT_EQ(validation_result.policy_type, "google/machine-level-omaha");
@@ -152,8 +153,8 @@
   const ::enterprise_management::PolicyFetchResponse& response =
       dm_response->policy_response().responses(0);
 
-  DMResponseValidator validator(CachedPolicyInfo(), "test-dm-token",
-                                "test-device-id");
+  DMResponseValidator validator(device_management_storage::CachedPolicyInfo(),
+                                "test-dm-token", "test-device-id");
   PolicyValidationResult validation_result;
   EXPECT_FALSE(validator.ValidatePolicyResponse(response, validation_result));
   EXPECT_EQ(validation_result.policy_type, "google/machine-level-omaha");
@@ -164,7 +165,7 @@
 
 TEST_F(DMResponseValidatorTests, BadSignedPublicKey) {
   // Cached info should be created before parsing next policy response.
-  CachedPolicyInfo cached_info;
+  device_management_storage::CachedPolicyInfo cached_info;
   GetCachedInfoWithPublicKey(cached_info);
 
   // Validation should fail if the public key is not signed properly.
@@ -198,8 +199,8 @@
   const ::enterprise_management::PolicyFetchResponse& response =
       dm_response->policy_response().responses(0);
 
-  DMResponseValidator validator(CachedPolicyInfo(), "test-dm-token",
-                                "test-device-id");
+  DMResponseValidator validator(device_management_storage::CachedPolicyInfo(),
+                                "test-dm-token", "test-device-id");
   PolicyValidationResult validation_result;
   EXPECT_FALSE(validator.ValidatePolicyResponse(response, validation_result));
   EXPECT_EQ(validation_result.status,
@@ -238,8 +239,8 @@
   const ::enterprise_management::PolicyFetchResponse& response =
       dm_response->policy_response().responses(0);
 
-  DMResponseValidator validator(CachedPolicyInfo(), "test-dm-token",
-                                "test-device-id");
+  DMResponseValidator validator(device_management_storage::CachedPolicyInfo(),
+                                "test-dm-token", "test-device-id");
   PolicyValidationResult validation_result;
   EXPECT_FALSE(validator.ValidatePolicyResponse(response, validation_result));
   EXPECT_EQ(validation_result.policy_type, kGoogleUpdatePolicyType);
diff --git a/chrome/updater/device_management/dm_storage.cc b/chrome/updater/device_management/dm_storage.cc
deleted file mode 100644
index 021db289..0000000
--- a/chrome/updater/device_management/dm_storage.cc
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/updater/device_management/dm_storage.h"
-
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-
-#include "base/base64.h"
-#include "base/check.h"
-#include "base/files/file_enumerator.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/important_file_writer.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/logging.h"
-#include "build/build_config.h"
-#include "chrome/updater/device_management/dm_cached_policy_info.h"
-#include "chrome/updater/device_management/dm_message.h"
-#include "chrome/updater/protos/omaha_settings.pb.h"
-#include "components/policy/proto/device_management_backend.pb.h"
-
-namespace updater {
-
-namespace {
-
-// This DM Token value is persisted if the server asks the client to invalidate
-// the DM Token.
-constexpr char kInvalidTokenValue[] = "INVALID_DM_TOKEN";
-
-// This is the standard name for the file that PersistPolicies() uses to store
-// a PolicyFetchResponse received from the DMServer during the previous request.
-// The data within the PolicyFetchResponse, such as the public key, version, and
-// timestamp are used for subsequent requests and validations of DMServer
-// responses.
-constexpr char kPolicyInfoFileName[] = "CachedPolicyInfo";
-
-// This is the standard name for the file that PersistPolicies() uses for each
-// {policy_type} that it receives from the DMServer.
-constexpr char kPolicyFileName[] = "PolicyFetchResponse";
-
-// Deletes the child directories in the cache root if they do not appear in
-// `exclusion_set`.
-bool DeletePolicies(const base::FilePath& cache_root,
-                    const std::set<std::string>& exclusion_set) {
-  bool result = true;
-  base::FileEnumerator(cache_root,
-                       /*recursive=*/false, base::FileEnumerator::DIRECTORIES,
-                       FILE_PATH_LITERAL("*"))
-      .ForEach([&exclusion_set, &result](const base::FilePath& file) {
-        if (exclusion_set.contains(file.BaseName().MaybeAsASCII())) {
-          return;
-        }
-
-        if (!base::DeletePathRecursively(file)) {
-          result = false;
-        }
-      });
-
-  return result;
-}
-
-bool MakePathGlobalAccessible(const base::FilePath& path) {
-#if BUILDFLAG(IS_POSIX)
-  return base::SetPosixFilePermissions(
-      path, base::FILE_PERMISSION_USER_MASK |
-                base::FILE_PERMISSION_READ_BY_GROUP |
-                base::FILE_PERMISSION_EXECUTE_BY_GROUP |
-                base::FILE_PERMISSION_READ_BY_OTHERS |
-                base::FILE_PERMISSION_EXECUTE_BY_OTHERS);
-#else
-  // Use system default permission for that path.
-  return true;
-#endif  // BUILDFLAG(IS_POSIX)
-}
-
-}  // namespace
-
-bool CreateGlobalAccessibleDirectory(const base::FilePath& path) {
-  return base::CreateDirectory(path) && MakePathGlobalAccessible(path);
-}
-
-bool WriteContentToGlobalReadableFile(const base::FilePath& path,
-                                      const std::string& content) {
-  return base::ImportantFileWriter::WriteFileAtomically(path, content) &&
-         MakePathGlobalAccessible(path);
-}
-
-DMStorage::DMStorage(const base::FilePath& policy_cache_root,
-                     std::unique_ptr<TokenServiceInterface> token_service)
-    : policy_cache_root_(policy_cache_root),
-      policy_info_file_(policy_cache_root_.AppendASCII(kPolicyInfoFileName)),
-      token_service_(std::move(token_service)) {
-  CHECK(token_service_);
-}
-
-DMStorage::~DMStorage() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-bool DMStorage::InvalidateDMToken() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  VLOG(1) << __func__;
-  return token_service_->StoreDmToken(kInvalidTokenValue);
-}
-
-bool DMStorage::DeleteDMToken() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  VLOG(1) << __func__;
-  return token_service_->DeleteDmToken();
-}
-
-bool DMStorage::IsValidDMToken() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  std::string dm_token = GetDmToken();
-  return !dm_token.empty() && dm_token != kInvalidTokenValue;
-}
-
-bool DMStorage::IsDeviceDeregistered() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return GetDmToken() == kInvalidTokenValue;
-}
-
-bool DMStorage::CanPersistPolicies() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  return base::PathExists(policy_info_file_)
-             ? base::PathIsWritable(policy_info_file_)
-             : base::ScopedTempDir().CreateUniqueTempDirUnderPath(
-                   policy_cache_root_) &&
-                   MakePathGlobalAccessible(policy_cache_root_);
-}
-
-bool DMStorage::PersistPolicies(const DMPolicyMap& policy_map) const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (policy_map.empty()) {
-    return true;
-  }
-
-  // Persists individual policies.
-  std::set<std::string> updated_policy_set;
-  bool policy_info_data_saved = false;
-  for (const auto& policy_entry : policy_map) {
-    const std::string& policy_type = policy_entry.first;
-    const std::string& policy_value = policy_entry.second;
-    if (!policy_info_data_saved) {
-      // Policy info has a new public key when server rotates the key.
-      // In this case, persists the policy info as the cached policy info
-      // for future policy fetch.
-      CachedPolicyInfo cached_info;
-      if (cached_info.Populate(policy_value) &&
-          !cached_info.public_key().empty() &&
-          WriteContentToGlobalReadableFile(policy_info_file_, policy_value)) {
-        VLOG(1) << "Public key rotated.";
-        policy_info_data_saved = true;
-      }
-    }
-
-    std::string encoded_policy_type = base::Base64Encode(policy_type);
-    updated_policy_set.emplace(encoded_policy_type);
-
-    const base::FilePath policy_dir =
-        policy_cache_root_.AppendASCII(encoded_policy_type);
-    if (!CreateGlobalAccessibleDirectory(policy_dir) ||
-        !WriteContentToGlobalReadableFile(
-            policy_dir.AppendASCII(kPolicyFileName), policy_value)) {
-      return false;
-    }
-  }
-
-  // All policies not in `updated_policy_set` are considered stale and deleted.
-  return DeletePolicies(policy_cache_root_, updated_policy_set);
-}
-
-bool DMStorage::RemoveAllPolicies() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  VLOG(1) << __func__;
-  return base::DeleteFile(policy_info_file_) &&
-         DeletePolicies(policy_cache_root_, /*exclusion_set=*/{});
-}
-
-std::unique_ptr<CachedPolicyInfo> DMStorage::GetCachedPolicyInfo() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  auto cached_info = std::make_unique<CachedPolicyInfo>();
-
-  std::string policy_info_data;
-  if (IsValidDMToken() && base::PathExists(policy_info_file_) &&
-      base::ReadFileToString(policy_info_file_, &policy_info_data)) {
-    cached_info->Populate(policy_info_data);
-  }
-
-  return cached_info;
-}
-
-std::unique_ptr<
-    ::wireless_android_enterprise_devicemanagement::OmahaSettingsClientProto>
-DMStorage::GetOmahaPolicySettings() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  if (!IsValidDMToken()) {
-    VLOG(1) << "No valid DM token.";
-    return nullptr;
-  }
-
-  std::string encoded_omaha_policy_type =
-      base::Base64Encode(kGoogleUpdatePolicyType);
-
-  base::FilePath omaha_policy_file =
-      policy_cache_root_.AppendASCII(encoded_omaha_policy_type)
-          .AppendASCII(kPolicyFileName);
-  std::string response_data;
-  ::enterprise_management::PolicyFetchResponse response;
-  ::enterprise_management::PolicyData policy_data;
-  auto omaha_settings =
-      std::make_unique<::wireless_android_enterprise_devicemanagement::
-                           OmahaSettingsClientProto>();
-  if (!base::PathExists(omaha_policy_file) ||
-      !base::ReadFileToString(omaha_policy_file, &response_data) ||
-      response_data.empty() || !response.ParseFromString(response_data) ||
-      !policy_data.ParseFromString(response.policy_data()) ||
-      !policy_data.has_policy_value() ||
-      !omaha_settings->ParseFromString(policy_data.policy_value())) {
-    VLOG(1) << "No Omaha policies.";
-    return nullptr;
-  }
-
-  return omaha_settings;
-}
-
-}  // namespace updater
diff --git a/chrome/updater/device_management/dm_storage.h b/chrome/updater/device_management/dm_storage.h
deleted file mode 100644
index 10898b5..0000000
--- a/chrome/updater/device_management/dm_storage.h
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_UPDATER_DEVICE_MANAGEMENT_DM_STORAGE_H_
-#define CHROME_UPDATER_DEVICE_MANAGEMENT_DM_STORAGE_H_
-
-#include <memory>
-#include <string>
-
-#include "base/files/file_path.h"
-#include "base/memory/ref_counted.h"
-#include "base/sequence_checker.h"
-#include "build/build_config.h"
-#include "chrome/updater/device_management/dm_message.h"
-
-namespace wireless_android_enterprise_devicemanagement {
-class OmahaSettingsClientProto;
-}
-
-namespace updater {
-
-class CachedPolicyInfo;
-
-bool CreateGlobalAccessibleDirectory(const base::FilePath& path);
-bool WriteContentToGlobalReadableFile(const base::FilePath& path,
-                                      const std::string& content_to_write);
-
-// The token service interface defines how to serialize tokens.
-class TokenServiceInterface {
- public:
-  virtual ~TokenServiceInterface() = default;
-
-  // ID of the device that the tokens target to.
-  virtual std::string GetDeviceID() const = 0;
-
-  // Checks if enrollment is mandatory.
-  virtual bool IsEnrollmentMandatory() const = 0;
-
-  // Writes |enrollment_token| to storage.
-  virtual bool StoreEnrollmentToken(const std::string& enrollment_token) = 0;
-
-  // Deletes |enrollment_token| from storage.
-  virtual bool DeleteEnrollmentToken() = 0;
-
-  // Reads the enrollment token from sources as-needed to find one.
-  // Returns an empty string if no enrollment token is found.
-  virtual std::string GetEnrollmentToken() const = 0;
-
-  // Writes |dm_token| into storage.
-  virtual bool StoreDmToken(const std::string& dm_token) = 0;
-
-  // Deletes the DM token from storage.
-  virtual bool DeleteDmToken() = 0;
-
-  // Returns the device management token from storage, or returns an empty
-  // string if no device management token is found.
-  virtual std::string GetDmToken() const = 0;
-};
-
-// The DMStorage is responsible for serialization of:
-//   1) DM enrollment token.
-//   2) DM token.
-//   3) DM policies.
-class DMStorage : public base::RefCountedThreadSafe<DMStorage> {
- public:
-  static constexpr size_t kMaxDmTokenLength = 4096;
-#if BUILDFLAG(IS_WIN)
-  explicit DMStorage(const base::FilePath& policy_cache_root);
-#else
-  DMStorage(const base::FilePath& policy_cache_root,
-            const base::FilePath& enrollment_token_path = {},
-            const base::FilePath& dm_token_path = {});
-#endif
-  DMStorage(const base::FilePath& policy_cache_root,
-            std::unique_ptr<TokenServiceInterface> token_service);
-  DMStorage(const DMStorage&) = delete;
-  DMStorage& operator=(const DMStorage&) = delete;
-
-  // Forwards to token service to get device ID
-  std::string GetDeviceID() const { return token_service_->GetDeviceID(); }
-
-  // Forwards to token service to check if enrollment is mandatory.
-  bool IsEnrollmentMandatory() const {
-    return token_service_->IsEnrollmentMandatory();
-  }
-
-  // Forwards to token service to save enrollment token.
-  bool StoreEnrollmentToken(const std::string& enrollment_token) {
-    return token_service_->StoreEnrollmentToken(enrollment_token);
-  }
-
-  // Forwards to token service to delete enrollment token.
-  bool DeleteEnrollmentToken() {
-    return token_service_->DeleteEnrollmentToken();
-  }
-
-  // Forwards to token service to get enrollment token.
-  std::string GetEnrollmentToken() const {
-    return token_service_->GetEnrollmentToken();
-  }
-
-  // Forwards to token service to save DM token.
-  bool StoreDmToken(const std::string& dm_token) {
-    return token_service_->StoreDmToken(dm_token);
-  }
-
-  // Forwards to token service to get DM token.
-  std::string GetDmToken() const { return token_service_->GetDmToken(); }
-
-  // Writes a special DM token to storage to mark current device as
-  // deregistered.
-  bool InvalidateDMToken();
-
-  // Deletes the existing DM token for re-registration.
-  bool DeleteDMToken();
-
-  // Returns true if the DM token is valid, where valid is defined as non-blank
-  // and not de-registered.
-  bool IsValidDMToken() const;
-
-  // Returns true if the device is de-registered.
-  bool IsDeviceDeregistered() const;
-
-  // Checks if the caller has permissions to persist the DM policies.
-  bool CanPersistPolicies() const;
-
-  // Persists DM policies.
-  //
-  // If the first policy in the map contains a valid public key, its serialized
-  // data will be saved into a fixed file named "CachedPolicyInfo" in the cache
-  // root. The file content will be used to construct an
-  // updater::CachedPolicyInfo object to get public key, its version, and
-  // signing timestamp. The values will be used in subsequent policy fetches.
-  //
-  // Each entry in |policy_map| will be stored within a sub-directory named
-  // {Base64Encoded{policy_type}}, with a fixed file name of
-  // "PolicyFetchResponse", where the file contents are serialized data of
-  // the policy object.
-  //
-  // Please note that this function also purges all stale polices whose policy
-  // type does not appear in keys of |policies|.
-  //
-  // Visualized directory structure example:
-  //  <policy_cache_root_>
-  //   |-- CachedPolicyInfo                      # Policy meta-data file.
-  //   |-- Z29vZ2xlL21hY2hpbmUtbGV2ZWwtb21haGE=
-  //   |       `--PolicyFetchResponse            # Policy response data.
-  //   `-- Zm9vYmFy                              # b64("foobar").
-  //           `--PolicyFetchResponse            # Policy response data.
-  //
-  //  ('Z29vZ2xlL21hY2hpbmUtbGV2ZWwtb21haGE=' is base64 encoding of
-  //  "google/machine-level-omaha").
-  //
-  bool PersistPolicies(const DMPolicyMap& policy_map) const;
-
-  // Removes all the cached policies, including the cached policy info.
-  bool RemoveAllPolicies() const;
-
-  // Creates a CachedPolicyInfo object and populates it with the public key
-  // information loaded from file |policy_cache_root_|\CachedPolicyInfo.
-  std::unique_ptr<CachedPolicyInfo> GetCachedPolicyInfo() const;
-
-  // Returns the Omaha policy settings loaded from PolicyFetchResponse file in
-  // |policy_cache_root_|\{Base64Encoded{kGoogleUpdatePolicyType}} directory.
-  std::unique_ptr<
-      ::wireless_android_enterprise_devicemanagement::OmahaSettingsClientProto>
-  GetOmahaPolicySettings() const;
-
-  // Returns the folder that caches the downloaded policies.
-  base::FilePath policy_cache_folder() const { return policy_cache_root_; }
-
- private:
-  friend class base::RefCountedThreadSafe<DMStorage>;
-  ~DMStorage();
-
-  const base::FilePath policy_cache_root_;
-  const base::FilePath policy_info_file_;
-  std::unique_ptr<TokenServiceInterface> token_service_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-};
-
-// Returns the DMStorage under which the Device Management policies are
-// persisted. For Windows, this is `%ProgramFiles(x86)%\{CompanyName}\Policies`.
-// For macOS, this is `/Library/{CompanyName}/{KEYSTONE_NAME}/DeviceManagement`.
-scoped_refptr<DMStorage> GetDefaultDMStorage();
-
-}  // namespace updater
-
-#endif  // CHROME_UPDATER_DEVICE_MANAGEMENT_DM_STORAGE_H_
diff --git a/chrome/updater/device_management/dm_storage_linux.cc b/chrome/updater/device_management/dm_storage_linux.cc
deleted file mode 100644
index 1dff532..0000000
--- a/chrome/updater/device_management/dm_storage_linux.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/updater/device_management/dm_storage.h"
-
-#include <string>
-
-#include "base/check.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/important_file_writer.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/strings/string_util.h"
-#include "chrome/updater/updater_branding.h"
-
-namespace updater {
-namespace {
-
-constexpr char kEnrollmentTokenFilePath[] =
-    "/opt/" COMPANY_SHORTNAME_STRING "/" PRODUCT_FULLNAME_STRING
-    "/CloudManagementEnrollmentToken";
-constexpr char kDmTokenFilePath[] =
-    "/opt/" COMPANY_SHORTNAME_STRING "/" PRODUCT_FULLNAME_STRING
-    "/CloudManagement";
-
-std::string GetMachineId() {
-  std::string machine_id;
-  if (!base::ReadFileToString(base::FilePath("/etc/machine-id"), &machine_id)) {
-    return std::string();
-  }
-  return machine_id;
-}
-
-// Reads a token from the given file. Returns the empty string if the file could
-// not be read.
-std::string LoadTokenFromFile(const base::FilePath& token_file_path) {
-  std::string token_value;
-  if (!base::ReadFileToString(token_file_path, &token_value)) {
-    return std::string();
-  }
-
-  return std::string(base::TrimWhitespaceASCII(token_value, base::TRIM_ALL));
-}
-}  // namespace
-
-class TokenService : public TokenServiceInterface {
- public:
-  TokenService(const base::FilePath& enrollment_token_path,
-               const base::FilePath& dm_token_path)
-      : enrollment_token_path_(enrollment_token_path.empty()
-                                   ? base::FilePath(kEnrollmentTokenFilePath)
-                                   : enrollment_token_path),
-        dm_token_path_(dm_token_path.empty() ? base::FilePath(kDmTokenFilePath)
-                                             : dm_token_path),
-        enrollment_token_(LoadTokenFromFile(enrollment_token_path_)),
-        dm_token_(LoadTokenFromFile(dm_token_path_)) {}
-  ~TokenService() override = default;
-
-  // Overrides for TokenServiceInterface.
-  std::string GetDeviceID() const override { return device_id_; }
-
-  bool IsEnrollmentMandatory() const override { return false; }
-
-  bool StoreEnrollmentToken(const std::string& enrollment_token) override {
-    if (!WriteContentToGlobalReadableFile(enrollment_token_path_,
-                                          enrollment_token)) {
-      return false;
-    }
-
-    enrollment_token_ = enrollment_token;
-    return true;
-  }
-
-  bool DeleteEnrollmentToken() override {
-    if (!base::DeleteFile(enrollment_token_path_)) {
-      return false;
-    }
-    enrollment_token_.clear();
-    return true;
-  }
-
-  std::string GetEnrollmentToken() const override { return enrollment_token_; }
-
-  bool StoreDmToken(const std::string& dm_token) override {
-    if (!WriteContentToGlobalReadableFile(dm_token_path_, dm_token)) {
-      return false;
-    }
-    dm_token_ = dm_token;
-    return true;
-  }
-
-  bool DeleteDmToken() override {
-    if (!base::DeleteFile(dm_token_path_)) {
-      return false;
-    }
-    dm_token_.clear();
-    return true;
-  }
-
-  std::string GetDmToken() const override { return dm_token_; }
-
- private:
-  // Cached values in memory.
-  const std::string device_id_ = GetMachineId();
-  const base::FilePath enrollment_token_path_;
-  const base::FilePath dm_token_path_;
-  std::string enrollment_token_;
-  std::string dm_token_;
-};
-
-DMStorage::DMStorage(const base::FilePath& policy_cache_root,
-                     const base::FilePath& enrollment_token_path,
-                     const base::FilePath& dm_token_path)
-    : DMStorage(policy_cache_root,
-                std::make_unique<TokenService>(enrollment_token_path,
-                                               dm_token_path)) {}
-
-scoped_refptr<DMStorage> GetDefaultDMStorage() {
-  return base::MakeRefCounted<DMStorage>(
-      base::FilePath("/opt")
-          .AppendASCII(COMPANY_SHORTNAME_STRING)
-          .AppendASCII(PRODUCT_FULLNAME_STRING)
-          .AppendASCII("DeviceManagement"));
-}
-
-}  // namespace updater
diff --git a/chrome/updater/device_management/dm_storage_mac.mm b/chrome/updater/device_management/dm_storage_mac.mm
deleted file mode 100644
index ea2efc22a..0000000
--- a/chrome/updater/device_management/dm_storage_mac.mm
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/updater/device_management/dm_storage.h"
-
-#import <Foundation/Foundation.h>
-
-#include <optional>
-#include <string>
-
-#include "base/apple/foundation_util.h"
-#include "base/apple/scoped_cftyperef.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/important_file_writer.h"
-#include "base/logging.h"
-#include "base/mac/mac_util.h"
-#include "base/mac/scoped_ioobject.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/strings/string_util.h"
-#include "base/strings/sys_string_conversions.h"
-#include "chrome/updater/updater_branding.h"
-#include "chrome/updater/util/mac_util.h"
-
-namespace updater {
-namespace {
-
-const CFStringRef kEnrollmentTokenLegacyName = CFSTR("EnrollmentToken");
-const CFStringRef kEnrollmentTokenKey = CFSTR("CloudManagementEnrollmentToken");
-const CFStringRef kBrowserBundleId =
-    CFSTR(MAC_BROWSER_BUNDLE_IDENTIFIER_STRING);
-
-std::string LoadEnrollmentTokenFromPolicyAtKey(CFStringRef key) {
-  base::apple::ScopedCFTypeRef<CFPropertyListRef> token_value(
-      CFPreferencesCopyAppValue(key, kBrowserBundleId));
-  if (!token_value || CFGetTypeID(token_value.get()) != CFStringGetTypeID() ||
-      !CFPreferencesAppValueIsForced(key, kBrowserBundleId)) {
-    return {};
-  }
-
-  CFStringRef value_string =
-      base::apple::CFCast<CFStringRef>(token_value.get());
-  if (!value_string) {
-    return {};
-  }
-
-  return base::SysCFStringRefToUTF8(value_string);
-}
-
-std::string LoadEnrollmentTokenFromPolicy() {
-  std::string enrollment_token =
-      LoadEnrollmentTokenFromPolicyAtKey(kEnrollmentTokenKey);
-
-  return enrollment_token.empty()
-             ? LoadEnrollmentTokenFromPolicyAtKey(kEnrollmentTokenLegacyName)
-             : enrollment_token;
-}
-
-void DeletePolicyEnrollmentToken() {
-  CFPreferencesSetValue(kEnrollmentTokenLegacyName, nil, kBrowserBundleId,
-                        kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
-  CFPreferencesSetValue(kEnrollmentTokenKey, nil, kBrowserBundleId,
-                        kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
-  CFPreferencesSynchronize(kBrowserBundleId, kCFPreferencesAnyUser,
-                           kCFPreferencesCurrentHost);
-}
-
-// Enrollment token path:
-//   /Library/Google/Chrome/CloudManagementEnrollmentToken.
-base::FilePath GetEnrollmentTokenFilePath() {
-  base::FilePath lib_path;
-  if (!base::apple::GetLocalDirectory(NSLibraryDirectory, &lib_path)) {
-    VLOG(1) << "Failed to get local library path.";
-    return base::FilePath();
-  }
-
-  return lib_path.AppendASCII(COMPANY_SHORTNAME_STRING)
-      .AppendASCII(BROWSER_NAME_STRING)
-      .AppendASCII("CloudManagementEnrollmentToken");
-}
-
-// DM token path:
-//   /Library/Application Support/Google/CloudManagement.
-base::FilePath GetDmTokenFilePath() {
-  base::FilePath app_path;
-  if (!base::apple::GetLocalDirectory(NSApplicationSupportDirectory,
-                                      &app_path)) {
-    VLOG(1) << "Failed to get Application support path.";
-    return base::FilePath();
-  }
-
-  return app_path.AppendASCII(COMPANY_SHORTNAME_STRING)
-      .AppendASCII("CloudManagement");
-}
-
-std::string LoadTokenFromFile(const base::FilePath& token_file_path) {
-  std::string token_value;
-  if (token_file_path.empty() ||
-      !base::ReadFileToString(token_file_path, &token_value)) {
-    return {};
-  }
-
-  return std::string(base::TrimWhitespaceASCII(token_value, base::TRIM_ALL));
-}
-
-class TokenService : public TokenServiceInterface {
- public:
-  TokenService(const base::FilePath& enrollment_token_path,
-               const base::FilePath& dm_token_path);
-  ~TokenService() override = default;
-
-  // Overrides for TokenServiceInterface.
-  std::string GetDeviceID() const override { return device_id_; }
-  bool IsEnrollmentMandatory() const override { return false; }
-  bool StoreEnrollmentToken(const std::string& enrollment_token) override;
-  bool DeleteEnrollmentToken() override;
-  std::string GetEnrollmentToken() const override { return enrollment_token_; }
-  bool StoreDmToken(const std::string& dm_token) override;
-  bool DeleteDmToken() override;
-  std::string GetDmToken() const override { return dm_token_; }
-
- private:
-  // Cached values in memory.
-  const std::string device_id_ = base::mac::GetPlatformSerialNumber();
-  const base::FilePath enrollment_token_path_;
-  const base::FilePath dm_token_path_;
-  std::string enrollment_token_;
-  std::string dm_token_;
-};
-
-TokenService::TokenService(const base::FilePath& enrollment_token_path,
-                           const base::FilePath& dm_token_path)
-    : enrollment_token_path_(enrollment_token_path.empty()
-                                 ? GetEnrollmentTokenFilePath()
-                                 : enrollment_token_path),
-      dm_token_path_(dm_token_path.empty() ? GetDmTokenFilePath()
-                                           : dm_token_path),
-      dm_token_(LoadTokenFromFile(dm_token_path_)) {
-  enrollment_token_ = LoadEnrollmentTokenFromPolicy();
-  if (enrollment_token_.empty()) {
-    enrollment_token_ = LoadTokenFromFile(enrollment_token_path_);
-  }
-}
-
-bool TokenService::StoreEnrollmentToken(const std::string& enrollment_token) {
-  if (enrollment_token_path_.empty() ||
-      !CreateGlobalAccessibleDirectory(enrollment_token_path_.DirName()) ||
-      !WriteContentToGlobalReadableFile(enrollment_token_path_,
-                                        enrollment_token)) {
-    VLOG(1) << "Failed to update enrollment token.";
-    return false;
-  }
-
-  enrollment_token_ = enrollment_token;
-  VLOG(1) << "Updated enrollment token to: " << enrollment_token;
-  return true;
-}
-
-bool TokenService::DeleteEnrollmentToken() {
-  enrollment_token_ = "";
-  DeletePolicyEnrollmentToken();
-  return base::DeleteFile(base::FilePath(enrollment_token_path_));
-}
-
-bool TokenService::StoreDmToken(const std::string& token) {
-  if (dm_token_path_.empty() ||
-      !CreateGlobalAccessibleDirectory(dm_token_path_.DirName()) ||
-      !WriteContentToGlobalReadableFile(dm_token_path_, token)) {
-    VLOG(1) << "Failed to update DM token.";
-    return false;
-  }
-  dm_token_ = token;
-  VLOG(1) << "Updated DM token to: " << token;
-  return true;
-}
-
-bool TokenService::DeleteDmToken() {
-  if (dm_token_path_.empty() || !base::DeleteFile(dm_token_path_)) {
-    VLOG(1) << "Failed to delete DM token.";
-    return false;
-  }
-  dm_token_.clear();
-  VLOG(1) << "DM token deleted.";
-  return true;
-}
-
-}  // namespace
-
-DMStorage::DMStorage(const base::FilePath& policy_cache_root,
-                     const base::FilePath& enrollment_token_path,
-                     const base::FilePath& dm_token_path)
-    : DMStorage(policy_cache_root,
-                std::make_unique<TokenService>(enrollment_token_path,
-                                               dm_token_path)) {}
-
-scoped_refptr<DMStorage> GetDefaultDMStorage() {
-  std::optional<base::FilePath> keystone_path =
-      GetKeystoneFolderPath(UpdaterScope::kSystem);
-  return keystone_path ? base::MakeRefCounted<DMStorage>(
-                             keystone_path->AppendASCII("DeviceManagement"))
-                       : nullptr;
-}
-
-}  // namespace updater
diff --git a/chrome/updater/device_management/dm_storage_unittest.cc b/chrome/updater/device_management/dm_storage_unittest.cc
deleted file mode 100644
index acdd81f..0000000
--- a/chrome/updater/device_management/dm_storage_unittest.cc
+++ /dev/null
@@ -1,386 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/updater/device_management/dm_storage.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/memory/scoped_refptr.h"
-#include "build/build_config.h"
-#include "chrome/updater/device_management/dm_cached_policy_info.h"
-#include "chrome/updater/protos/omaha_settings.pb.h"
-#include "chrome/updater/test/test_scope.h"
-#include "chrome/updater/test/unit_test_util.h"
-#include "chrome/updater/updater_scope.h"
-#include "components/policy/proto/device_management_backend.pb.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#if BUILDFLAG(IS_WIN)
-#include "base/test/test_reg_util_win.h"
-#include "base/win/registry.h"
-#include "chrome/updater/util/win_util.h"
-#include "chrome/updater/win/win_constants.h"
-#endif  // BUILDFLAG(IS_WIN)
-
-namespace updater {
-
-namespace {
-
-constexpr char kTestDmToken[] = "TestDMToken";
-
-class TestTokenService : public TokenServiceInterface {
- public:
-  TestTokenService()
-      : enrollment_token_("TestEnrollmentToken"), dm_token_(kTestDmToken) {}
-  ~TestTokenService() override = default;
-
-  // Overrides for TokenServiceInterface.
-  std::string GetDeviceID() const override { return "TestDeviceID"; }
-
-  bool IsEnrollmentMandatory() const override { return false; }
-
-  bool StoreEnrollmentToken(const std::string& enrollment_token) override {
-    enrollment_token_ = enrollment_token;
-    return true;
-  }
-
-  bool DeleteEnrollmentToken() override { return StoreEnrollmentToken(""); }
-
-  std::string GetEnrollmentToken() const override { return enrollment_token_; }
-
-  bool StoreDmToken(const std::string& dm_token) override {
-    dm_token_ = dm_token;
-    return true;
-  }
-
-  bool DeleteDmToken() override {
-    dm_token_.clear();
-    return true;
-  }
-
-  std::string GetDmToken() const override { return dm_token_; }
-
- private:
-  std::string enrollment_token_;
-  std::string dm_token_;
-};
-
-std::string CannedOmahaPolicyFetchResponse() {
-  ::wireless_android_enterprise_devicemanagement::OmahaSettingsClientProto
-      omaha_settings;
-
-  omaha_settings.set_auto_update_check_period_minutes(111);
-  omaha_settings.set_download_preference("cacheable");
-  omaha_settings.mutable_updates_suppressed()->set_start_hour(8);
-  omaha_settings.mutable_updates_suppressed()->set_start_minute(8);
-  omaha_settings.mutable_updates_suppressed()->set_duration_min(47);
-  omaha_settings.set_proxy_mode("proxy_pac_script");
-  omaha_settings.set_proxy_pac_url("foo.c/proxy.pa");
-  omaha_settings.set_install_default(
-      ::wireless_android_enterprise_devicemanagement::INSTALL_DEFAULT_DISABLED);
-  omaha_settings.set_update_default(
-      ::wireless_android_enterprise_devicemanagement::MANUAL_UPDATES_ONLY);
-
-  ::wireless_android_enterprise_devicemanagement::ApplicationSettings app;
-  app.set_app_guid(test::kChromeAppId);
-
-  app.set_install(
-      ::wireless_android_enterprise_devicemanagement::INSTALL_DISABLED);
-  app.set_update(
-      ::wireless_android_enterprise_devicemanagement::AUTOMATIC_UPDATES_ONLY);
-  app.set_target_version_prefix("3.6.55");
-  app.set_rollback_to_target_version(
-      ::wireless_android_enterprise_devicemanagement::
-          ROLLBACK_TO_TARGET_VERSION_ENABLED);
-
-  omaha_settings.mutable_application_settings()->Add(std::move(app));
-
-  ::enterprise_management::PolicyData policy_data;
-  policy_data.set_policy_value(omaha_settings.SerializeAsString());
-
-  ::enterprise_management::PolicyFetchResponse response;
-  response.set_policy_data(policy_data.SerializeAsString());
-  return response.SerializeAsString();
-}
-
-}  // namespace
-
-#if BUILDFLAG(IS_MAC)
-TEST(DMStorage, LoadDeviceID) {
-  auto storage = base::MakeRefCounted<DMStorage>(
-      base::FilePath(FILE_PATH_LITERAL("/TestPolicyCacheRoot")));
-  EXPECT_FALSE(storage->GetDeviceID().empty());
-}
-#endif  // BUILDFLAG(IS_MAC)
-
-#if BUILDFLAG(IS_WIN)
-TEST(DMStorage, LoadEnrollmentToken) {
-  registry_util::RegistryOverrideManager registry_overrides;
-  ASSERT_NO_FATAL_FAILURE(
-      registry_overrides.OverrideRegistry(HKEY_LOCAL_MACHINE));
-
-  base::ScopedTempDir cache_root;
-  ASSERT_TRUE(cache_root.CreateUniqueTempDir());
-  auto storage = base::MakeRefCounted<DMStorage>(cache_root.GetPath());
-  EXPECT_TRUE(storage->GetEnrollmentToken().empty());
-
-  base::win::RegKey legacy_key;
-  EXPECT_EQ(
-      legacy_key.Create(HKEY_LOCAL_MACHINE, kRegKeyCompanyLegacyCloudManagement,
-                        Wow6432(KEY_WRITE)),
-      ERROR_SUCCESS);
-  EXPECT_EQ(legacy_key.WriteValue(kRegValueCloudManagementEnrollmentToken,
-                                  L"legacy_test_enrollment_token"),
-            ERROR_SUCCESS);
-  EXPECT_EQ(storage->GetEnrollmentToken(), "legacy_test_enrollment_token");
-
-  base::win::RegKey key;
-  EXPECT_EQ(key.Create(HKEY_LOCAL_MACHINE, kRegKeyCompanyCloudManagement,
-                       Wow6432(KEY_WRITE)),
-            ERROR_SUCCESS);
-  EXPECT_EQ(key.WriteValue(kRegValueEnrollmentToken, L"test_enrollment_token"),
-            ERROR_SUCCESS);
-  EXPECT_EQ(storage->GetEnrollmentToken(), "test_enrollment_token");
-}
-
-TEST(DMStorage, StoreEnrollmentToken) {
-  registry_util::RegistryOverrideManager registry_overrides;
-  ASSERT_NO_FATAL_FAILURE(
-      registry_overrides.OverrideRegistry(HKEY_LOCAL_MACHINE));
-
-  base::ScopedTempDir cache_root;
-  ASSERT_TRUE(cache_root.CreateUniqueTempDir());
-  auto storage = base::MakeRefCounted<DMStorage>(cache_root.GetPath());
-  EXPECT_TRUE(storage->GetEnrollmentToken().empty());
-
-  EXPECT_TRUE(storage->StoreEnrollmentToken("enrollment_token"));
-  EXPECT_EQ(storage->GetEnrollmentToken(), "enrollment_token");
-
-  EXPECT_TRUE(storage->StoreEnrollmentToken("new_enrollment_token"));
-  EXPECT_EQ(storage->GetEnrollmentToken(), "new_enrollment_token");
-}
-
-TEST(DMStorage, DeleteEnrollmentToken) {
-  registry_util::RegistryOverrideManager registry_overrides;
-  ASSERT_NO_FATAL_FAILURE(
-      registry_overrides.OverrideRegistry(HKEY_LOCAL_MACHINE));
-
-  base::ScopedTempDir cache_root;
-  ASSERT_TRUE(cache_root.CreateUniqueTempDir());
-  auto storage = base::MakeRefCounted<DMStorage>(cache_root.GetPath());
-  EXPECT_TRUE(storage->GetEnrollmentToken().empty());
-
-  EXPECT_TRUE(storage->StoreEnrollmentToken("test_token"));
-  base::win::RegKey legacy_key;
-  EXPECT_EQ(
-      legacy_key.Create(HKEY_LOCAL_MACHINE, kRegKeyCompanyLegacyCloudManagement,
-                        Wow6432(KEY_WRITE)),
-      ERROR_SUCCESS);
-  EXPECT_EQ(legacy_key.WriteValue(kRegValueCloudManagementEnrollmentToken,
-                                  L"legacy_test_token"),
-            ERROR_SUCCESS);
-
-  EXPECT_TRUE(storage->DeleteEnrollmentToken());
-  EXPECT_EQ(storage->GetEnrollmentToken(), "");
-}
-#else
-TEST(DMStorage, StoreEnrollmentToken) {
-  base::ScopedTempDir cache_root;
-  ASSERT_TRUE(cache_root.CreateUniqueTempDir());
-  const base::FilePath cache_root_path = cache_root.GetPath();
-  auto storage = base::MakeRefCounted<DMStorage>(
-      cache_root_path, cache_root_path.AppendASCII("enrollment_token_file"),
-      cache_root_path.AppendASCII("dm_token_file"));
-  EXPECT_TRUE(storage->GetEnrollmentToken().empty());
-
-  EXPECT_TRUE(storage->StoreEnrollmentToken("enrollment_token"));
-  EXPECT_EQ(storage->GetEnrollmentToken(), "enrollment_token");
-
-  EXPECT_TRUE(storage->StoreEnrollmentToken("new_enrollment_token"));
-  EXPECT_EQ(storage->GetEnrollmentToken(), "new_enrollment_token");
-}
-
-TEST(DMStorage, DeleteEnrollmentToken) {
-  base::ScopedTempDir cache_root;
-  ASSERT_TRUE(cache_root.CreateUniqueTempDir());
-  const base::FilePath cache_root_path = cache_root.GetPath();
-  auto storage = base::MakeRefCounted<DMStorage>(
-      cache_root_path, cache_root_path.AppendASCII("enrollment_token_file"),
-      cache_root_path.AppendASCII("dm_token_file"));
-  EXPECT_TRUE(storage->GetEnrollmentToken().empty());
-  EXPECT_TRUE(storage->StoreEnrollmentToken("test_token"));
-  EXPECT_TRUE(storage->DeleteEnrollmentToken());
-  EXPECT_EQ(storage->GetEnrollmentToken(), "");
-}
-#endif  // BUILDFLAG(IS_WIN)
-
-TEST(DMStorage, DMToken) {
-  base::ScopedTempDir cache_root;
-  ASSERT_TRUE(cache_root.CreateUniqueTempDir());
-  auto storage = base::MakeRefCounted<DMStorage>(
-      cache_root.GetPath(), std::make_unique<TestTokenService>());
-  EXPECT_TRUE(storage->IsValidDMToken());
-  EXPECT_FALSE(storage->GetDmToken().empty());
-  EXPECT_FALSE(storage->IsDeviceDeregistered());
-
-  // Deregister using DM token invalidation.
-  storage->InvalidateDMToken();
-  EXPECT_FALSE(storage->IsValidDMToken());
-  EXPECT_FALSE(storage->GetDmToken().empty());
-  EXPECT_TRUE(storage->IsDeviceDeregistered());
-
-  storage->StoreDmToken(kTestDmToken);
-  EXPECT_TRUE(storage->IsValidDMToken());
-  EXPECT_FALSE(storage->GetDmToken().empty());
-  EXPECT_FALSE(storage->IsDeviceDeregistered());
-
-  // Deregister using DM token deletion.
-  storage->DeleteDMToken();
-  EXPECT_FALSE(storage->IsValidDMToken());
-  EXPECT_TRUE(storage->GetDmToken().empty());
-  // Although the device is deregistered, it is not treated as deregistered due
-  // to potential re-registration. Instead, it is treated as having an empty DM
-  // token.
-  EXPECT_FALSE(storage->IsDeviceDeregistered());
-}
-
-TEST(DMStorage, PersistPolicies) {
-  DMPolicyMap policies({
-      {"google/machine-level-omaha", "serialized-omaha-policy-data"},
-      {"foobar", "serialized-foobar-policy-data"},
-  });
-  base::ScopedTempDir cache_root;
-  ASSERT_TRUE(cache_root.CreateUniqueTempDir());
-
-  // Mock stale policy files
-  base::FilePath stale_poliy =
-      cache_root.GetPath().Append(FILE_PATH_LITERAL("stale_policy_dir"));
-  EXPECT_TRUE(base::CreateDirectory(stale_poliy));
-  EXPECT_TRUE(base::DirectoryExists(stale_poliy));
-
-  auto storage = base::MakeRefCounted<DMStorage>(cache_root.GetPath());
-  EXPECT_TRUE(storage->CanPersistPolicies());
-  EXPECT_TRUE(storage->PersistPolicies(policies));
-  base::FilePath policy_info_file =
-      cache_root.GetPath().AppendASCII("CachedPolicyInfo");
-  EXPECT_FALSE(base::PathExists(policy_info_file));
-
-  base::FilePath omaha_policy_file =
-      cache_root.GetPath()
-          .AppendASCII("Z29vZ2xlL21hY2hpbmUtbGV2ZWwtb21haGE=")
-          .AppendASCII("PolicyFetchResponse");
-  EXPECT_TRUE(base::PathExists(omaha_policy_file));
-  std::string omaha_policy;
-  EXPECT_TRUE(base::ReadFileToString(omaha_policy_file, &omaha_policy));
-  EXPECT_EQ(omaha_policy, "serialized-omaha-policy-data");
-
-  base::FilePath foobar_policy_file = cache_root.GetPath()
-                                          .AppendASCII("Zm9vYmFy")
-                                          .AppendASCII("PolicyFetchResponse");
-  EXPECT_TRUE(base::PathExists(foobar_policy_file));
-  std::string foobar_policy;
-  EXPECT_TRUE(base::ReadFileToString(foobar_policy_file, &foobar_policy));
-  EXPECT_EQ(foobar_policy, "serialized-foobar-policy-data");
-
-  // Stale policies should be purged.
-  EXPECT_FALSE(base::DirectoryExists(stale_poliy));
-
-  EXPECT_TRUE(storage->RemoveAllPolicies());
-  EXPECT_FALSE(base::PathExists(omaha_policy_file));
-  EXPECT_FALSE(base::PathExists(foobar_policy_file));
-}
-
-TEST(DMStorage, GetCachedPolicyInfo) {
-  enterprise_management::PolicyData policy_data;
-  policy_data.set_policy_value("SerializedProtobufDataFromPolicy");
-  policy_data.set_policy_type("TestPolicyType1");
-  policy_data.set_request_token(kTestDmToken);
-  policy_data.set_timestamp(12340000);
-  policy_data.set_device_id(kTestDmToken);
-  policy_data.set_request_token(kTestDmToken);
-
-  std::string new_public_key = "SampleNewPublicKeyData";
-  enterprise_management::PublicKeyVerificationData key_verif_data;
-  key_verif_data.set_new_public_key(new_public_key);
-  key_verif_data.set_new_public_key_version(15);
-
-  enterprise_management::PolicyFetchResponse response;
-  response.set_policy_data(policy_data.SerializeAsString());
-  response.set_new_public_key(new_public_key);
-  response.set_new_public_key_verification_data(
-      key_verif_data.SerializeAsString());
-
-  base::ScopedTempDir cache_root;
-  ASSERT_TRUE(cache_root.CreateUniqueTempDir());
-  auto storage = base::MakeRefCounted<DMStorage>(
-      cache_root.GetPath(), std::make_unique<TestTokenService>());
-  EXPECT_TRUE(storage->CanPersistPolicies());
-  EXPECT_TRUE(storage->PersistPolicies({
-      {"sample-policy-type", response.SerializeAsString()},
-  }));
-
-  auto policy_info = storage->GetCachedPolicyInfo();
-  ASSERT_NE(policy_info, nullptr);
-  EXPECT_EQ(policy_info->public_key(), "SampleNewPublicKeyData");
-  EXPECT_TRUE(policy_info->has_key_version());
-  EXPECT_EQ(policy_info->key_version(), 15);
-  EXPECT_EQ(policy_info->timestamp(), 12340000);
-
-  EXPECT_TRUE(storage->RemoveAllPolicies());
-  policy_info = storage->GetCachedPolicyInfo();
-  EXPECT_TRUE(policy_info->public_key().empty());
-  EXPECT_FALSE(policy_info->has_key_version());
-  EXPECT_EQ(policy_info->timestamp(), 0);
-}
-
-TEST(DMStorage, ReadCachedOmahaPolicy) {
-  DMPolicyMap policies({
-      {"google/machine-level-omaha", CannedOmahaPolicyFetchResponse()},
-  });
-  base::ScopedTempDir cache_root;
-  ASSERT_TRUE(cache_root.CreateUniqueTempDir());
-  auto storage = base::MakeRefCounted<DMStorage>(
-      cache_root.GetPath(), std::make_unique<TestTokenService>());
-  EXPECT_TRUE(storage->CanPersistPolicies());
-  EXPECT_TRUE(storage->PersistPolicies(policies));
-
-  std::unique_ptr<
-      ::wireless_android_enterprise_devicemanagement::OmahaSettingsClientProto>
-      omaha_settings = storage->GetOmahaPolicySettings();
-  ASSERT_NE(omaha_settings, nullptr);
-  EXPECT_EQ(omaha_settings->auto_update_check_period_minutes(), 111);
-
-  EXPECT_EQ(omaha_settings->updates_suppressed().start_hour(), 8);
-  EXPECT_EQ(omaha_settings->updates_suppressed().start_minute(), 8);
-  EXPECT_EQ(omaha_settings->updates_suppressed().duration_min(), 47);
-
-  EXPECT_EQ(omaha_settings->proxy_mode(), "proxy_pac_script");
-  EXPECT_EQ(omaha_settings->proxy_pac_url(), "foo.c/proxy.pa");
-  EXPECT_FALSE(omaha_settings->has_proxy_server());
-
-  EXPECT_EQ(omaha_settings->download_preference(), "cacheable");
-
-  // Chrome policies.
-  const auto& chrome_settings = omaha_settings->application_settings()[0];
-  EXPECT_EQ(chrome_settings.install(),
-            ::wireless_android_enterprise_devicemanagement::INSTALL_DISABLED);
-  EXPECT_EQ(
-      chrome_settings.update(),
-      ::wireless_android_enterprise_devicemanagement::AUTOMATIC_UPDATES_ONLY);
-  EXPECT_EQ(chrome_settings.target_version_prefix(), "3.6.55");
-  EXPECT_EQ(chrome_settings.rollback_to_target_version(),
-            ::wireless_android_enterprise_devicemanagement::
-                ROLLBACK_TO_TARGET_VERSION_ENABLED);
-
-  // Verify no policy settings once device is de-registered.
-  EXPECT_TRUE(storage->InvalidateDMToken());
-  EXPECT_TRUE(storage->IsDeviceDeregistered());
-  EXPECT_FALSE(storage->IsValidDMToken());
-  ASSERT_EQ(storage->GetOmahaPolicySettings(), nullptr);
-}
-
-}  // namespace updater
diff --git a/chrome/updater/device_management/dm_storage_win.cc b/chrome/updater/device_management/dm_storage_win.cc
deleted file mode 100644
index acf0a918..0000000
--- a/chrome/updater/device_management/dm_storage_win.cc
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/updater/device_management/dm_storage.h"
-
-#include <string>
-#include <vector>
-
-#include "base/base_paths_win.h"
-#include "base/files/file_path.h"
-#include "base/logging.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/path_service.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/win/registry.h"
-#include "chrome/updater/constants.h"
-#include "chrome/updater/updater_branding.h"
-#include "chrome/updater/util/win_util.h"
-#include "chrome/updater/win/win_constants.h"
-
-namespace updater {
-namespace {
-
-// Registry for device ID.
-constexpr wchar_t kRegKeyCryptographyKey[] =
-    L"SOFTWARE\\Microsoft\\Cryptography\\";
-constexpr wchar_t kRegValueMachineGuid[] = L"MachineGuid";
-
-bool ReadRegistryString(const std::wstring& key_path,
-                        const std::wstring& name,
-                        REGSAM reg_view,
-                        std::string& value) {
-  std::wstring data;
-  const LONG result = base::win::RegKey(HKEY_LOCAL_MACHINE, key_path.c_str(),
-                                        reg_view | KEY_READ)
-                          .ReadValue(name.c_str(), &data);
-  if (result != ERROR_SUCCESS) {
-    VLOG(1) << __func__ << ": failed to read registry: " << key_path << "@"
-            << name;
-    return false;
-  }
-  value = base::SysWideToUTF8(data);
-  return true;
-}
-
-bool DeleteRegistryValue(const std::wstring& key_path,
-                         const std::wstring& name,
-                         REGSAM reg_view) {
-  base::win::RegKey key;
-  if (const LONG result = key.Open(HKEY_LOCAL_MACHINE, key_path.c_str(),
-                                   reg_view | KEY_SET_VALUE);
-      result != ERROR_SUCCESS) {
-    return result == ERROR_FILE_NOT_FOUND;
-  }
-  if (const LONG result = key.DeleteValue(name.c_str());
-      result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
-    VLOG(1) << "Failed to delete registry: " << key_path << "@" << name;
-    return false;
-  }
-  return true;
-}
-
-// Reads a token from the registry value of string type .
-bool ReadTokenString(const std::wstring& key_path,
-                     const std::wstring& name,
-                     REGSAM reg_view,
-                     std::string& token) {
-  if (!ReadRegistryString(key_path, name, reg_view, token)) {
-    return false;
-  }
-  if (token.size() > DMStorage::kMaxDmTokenLength) {
-    token.clear();
-    VLOG(1) << __func__ << ": token [" << token << "] is too long.";
-    return false;
-  }
-  return true;
-}
-
-// Reads a token from the registry value of type REG_BINARY.
-bool ReadTokenBinary(const std::wstring& key_path,
-                     const std::wstring& name,
-                     REGSAM reg_view,
-                     std::string& token) {
-  base::win::RegKey key;
-  if (key.Open(HKEY_LOCAL_MACHINE, key_path.c_str(), reg_view | KEY_READ) !=
-      ERROR_SUCCESS) {
-    return false;
-  }
-  DWORD size = 0;
-  DWORD type = 0;
-  LONG error = key.ReadValue(name.c_str(), nullptr, &size, &type);
-  if (error != ERROR_SUCCESS) {
-    VLOG(2) << "ReadValue failed: " << error;
-    return false;
-  }
-  if (size == 0) {
-    VLOG(2) << "The token is empty.";
-    return false;
-  }
-  if (size > DMStorage::kMaxDmTokenLength) {
-    VLOG(2) << "Value is too large: " << size;
-    return false;
-  }
-  if (type != REG_BINARY) {
-    VLOG(2) << "Ignored token value with incompatible type.";
-    return false;
-  }
-  std::vector<char> value(size);
-  error = key.ReadValue(name.c_str(), &value.front(), &size, &type);
-  if (error != ERROR_SUCCESS) {
-    VLOG(2) << "ReadValue failed: " << error;
-    return false;
-  }
-  token.assign(value.begin(), value.end());
-  return true;
-}
-
-// Writes a token as a binary value to the registry.
-bool WriteTokenBinary(const std::wstring& key_path,
-                      const std::wstring& name,
-                      REGSAM reg_view,
-                      const std::string& token) {
-  if (token.size() > DMStorage::kMaxDmTokenLength) {
-    VLOG(2) << "Value is too large: " << token.size();
-    return false;
-  }
-
-  base::win::RegKey key;
-  LONG error =
-      key.Create(HKEY_LOCAL_MACHINE, key_path.c_str(), reg_view | KEY_WRITE);
-  if (error != ERROR_SUCCESS) {
-    VLOG(1) << "Failed to open " << key_path << ": " << error;
-    return false;
-  }
-
-  error = key.WriteValue(name.c_str(), token.data(), token.size(), REG_BINARY);
-  if (error != ERROR_SUCCESS) {
-    VLOG(1) << "Failed to write " << key_path << " @ " << name
-            << " (binary): " << error;
-  }
-  return error == ERROR_SUCCESS;
-}
-
-class TokenService : public TokenServiceInterface {
- public:
-  TokenService() = default;
-  ~TokenService() override = default;
-
-  // Overrides for TokenServiceInterface.
-  std::string GetDeviceID() const override;
-  bool IsEnrollmentMandatory() const override;
-  bool StoreEnrollmentToken(const std::string& enrollment_token) override;
-  bool DeleteEnrollmentToken() override;
-  std::string GetEnrollmentToken() const override;
-  bool StoreDmToken(const std::string& dm_token) override;
-  bool DeleteDmToken() override;
-  std::string GetDmToken() const override;
-};
-
-std::string TokenService::GetDeviceID() const {
-  std::string device_id;
-  if (!ReadRegistryString(kRegKeyCryptographyKey, kRegValueMachineGuid,
-                          KEY_READ | KEY_WOW64_64KEY, device_id)) {
-    return {};
-  }
-  return device_id;
-}
-
-bool TokenService::IsEnrollmentMandatory() const {
-  DWORD is_mandatory = 0;
-  base::win::RegKey key;
-  return (key.Open(HKEY_LOCAL_MACHINE, kRegKeyCompanyCloudManagement,
-                   Wow6432(KEY_READ)) == ERROR_SUCCESS &&
-          key.ReadValueDW(kRegValueEnrollmentMandatory, &is_mandatory) ==
-              ERROR_SUCCESS)
-             ? is_mandatory
-             : false;
-}
-
-bool TokenService::StoreEnrollmentToken(const std::string& token) {
-  const bool result =
-      SetRegistryKey(HKEY_LOCAL_MACHINE, kRegKeyCompanyCloudManagement,
-                     kRegValueEnrollmentToken, base::SysUTF8ToWide(token));
-  VLOG(1) << "Update enrollment token to: [" << token
-          << "], bool result=" << result;
-  return result;
-}
-
-bool TokenService::DeleteEnrollmentToken() {
-  VLOG(1) << __func__;
-  return DeleteRegistryValue(kRegKeyCompanyCloudManagement,
-                             kRegValueEnrollmentToken, KEY_WOW64_32KEY) &&
-         DeleteRegistryValue(kRegKeyCompanyLegacyCloudManagement,
-                             kRegValueCloudManagementEnrollmentToken,
-                             KEY_WOW64_32KEY);
-}
-
-std::string TokenService::GetEnrollmentToken() const {
-  std::string token;
-  if (ReadTokenString(kRegKeyCompanyCloudManagement, kRegValueEnrollmentToken,
-                      KEY_WOW64_32KEY, token)) {
-    return token;
-  }
-  for (const std::wstring& key_path :
-       {std::wstring(kRegKeyCompanyLegacyCloudManagement),
-        GetAppClientsKey(UPDATER_APPID),
-        GetAppClientsKey(kLegacyGoogleUpdateAppID)}) {
-    if (ReadTokenString(key_path, kRegValueCloudManagementEnrollmentToken,
-                        KEY_WOW64_32KEY, token)) {
-      return token;
-    }
-  }
-  return {};
-}
-
-bool TokenService::StoreDmToken(const std::string& token) {
-  VLOG(1) << __func__ << ": [" << token << "]";
-  return WriteTokenBinary(kRegKeyCompanyEnrollment, kRegValueDmToken,
-                          KEY_WOW64_32KEY, token) &&
-         WriteTokenBinary(kRegKeyCompanyLegacyEnrollment, kRegValueDmToken,
-                          KEY_WOW64_64KEY, token);
-}
-
-bool TokenService::DeleteDmToken() {
-  VLOG(1) << __func__;
-  return DeleteRegistryValue(kRegKeyCompanyEnrollment, kRegValueDmToken,
-                             KEY_WOW64_32KEY) &&
-         DeleteRegistryValue(kRegKeyCompanyLegacyEnrollment, kRegValueDmToken,
-                             KEY_WOW64_64KEY);
-}
-
-std::string TokenService::GetDmToken() const {
-  std::string token;
-  if (ReadTokenBinary(kRegKeyCompanyEnrollment, kRegValueDmToken,
-                      KEY_WOW64_32KEY, token) ||
-      ReadTokenBinary(kRegKeyCompanyLegacyEnrollment, kRegValueDmToken,
-                      KEY_WOW64_64KEY, token)) {
-    return token;
-  }
-  VLOG(1) << __func__ << ": token not found.";
-  return {};
-}
-
-}  // namespace
-
-DMStorage::DMStorage(const base::FilePath& policy_cache_root)
-    : DMStorage(policy_cache_root, std::make_unique<TokenService>()) {}
-
-scoped_refptr<DMStorage> GetDefaultDMStorage() {
-  base::FilePath program_filesx86_dir;
-  if (!base::PathService::Get(base::DIR_PROGRAM_FILESX86,
-                              &program_filesx86_dir)) {
-    return nullptr;
-  }
-
-  return base::MakeRefCounted<DMStorage>(
-      program_filesx86_dir.AppendASCII(COMPANY_SHORTNAME_STRING)
-          .AppendASCII("Policies"));
-}
-
-}  // namespace updater
diff --git a/chrome/updater/policy/dm_policy_manager.cc b/chrome/updater/policy/dm_policy_manager.cc
index e6a297d..001bf2f 100644
--- a/chrome/updater/policy/dm_policy_manager.cc
+++ b/chrome/updater/policy/dm_policy_manager.cc
@@ -10,14 +10,19 @@
 #include <vector>
 
 #include "base/enterprise_util.h"
+#include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/notreached.h"
 #include "base/strings/string_util.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
+#include "chrome/enterprise_companion/device_management_storage/dm_storage.h"
 #include "chrome/updater/constants.h"
+#include "chrome/updater/device_management/dm_message.h"
 #include "chrome/updater/policy/manager.h"
+#include "chrome/updater/protos/omaha_settings.pb.h"
+#include "device_management_backend.pb.h"
 
 namespace updater {
 
@@ -304,15 +309,34 @@
   return apps_with_policy;
 }
 
+std::optional<
+    wireless_android_enterprise_devicemanagement::OmahaSettingsClientProto>
+GetOmahaPolicySettings(
+    scoped_refptr<device_management_storage::DMStorage> dm_storage) {
+  wireless_android_enterprise_devicemanagement::OmahaSettingsClientProto
+      omaha_settings;
+  std::optional<enterprise_management::PolicyData> policy_data =
+      dm_storage->ReadPolicyData(kGoogleUpdatePolicyType);
+  if (!policy_data || !policy_data->has_policy_value()) {
+    return std::nullopt;
+  }
+  if (!omaha_settings.ParseFromString(policy_data->policy_value())) {
+    VLOG(1) << "Failed to parse OmahaSettingsClientProto";
+    return std::nullopt;
+  }
+  return omaha_settings;
+}
+
 scoped_refptr<PolicyManagerInterface> CreateDMPolicyManager(
     const std::optional<bool>& override_is_managed_device) {
-  scoped_refptr<DMStorage> default_dm_storage = GetDefaultDMStorage();
+  scoped_refptr<device_management_storage::DMStorage> default_dm_storage =
+      device_management_storage::GetDefaultDMStorage();
   if (!default_dm_storage) {
     return nullptr;
   }
-  std::unique_ptr<
+  std::optional<
       ::wireless_android_enterprise_devicemanagement::OmahaSettingsClientProto>
-      omaha_settings = default_dm_storage->GetOmahaPolicySettings();
+      omaha_settings = GetOmahaPolicySettings(default_dm_storage);
   if (!omaha_settings) {
     return nullptr;
   }
diff --git a/chrome/updater/policy/dm_policy_manager.h b/chrome/updater/policy/dm_policy_manager.h
index d8e67f1d..fcd0962 100644
--- a/chrome/updater/policy/dm_policy_manager.h
+++ b/chrome/updater/policy/dm_policy_manager.h
@@ -10,7 +10,7 @@
 #include <vector>
 
 #include "base/memory/scoped_refptr.h"
-#include "chrome/updater/device_management/dm_storage.h"
+#include "chrome/enterprise_companion/device_management_storage/dm_storage.h"
 #include "chrome/updater/policy/manager.h"
 #include "chrome/updater/protos/omaha_settings.pb.h"
 
@@ -19,7 +19,7 @@
 // The DMPolicyManager returns device management policies for managed machines.
 class DMPolicyManager : public PolicyManagerInterface {
  public:
-  DMPolicyManager(
+  explicit DMPolicyManager(
       const ::wireless_android_enterprise_devicemanagement::
           OmahaSettingsClientProto& omaha_settings,
       const std::optional<bool>& override_is_managed_device = std::nullopt);
@@ -64,6 +64,12 @@
       omaha_settings_;
 };
 
+// Read the Omaha settings from DM storage.
+std::optional<
+    wireless_android_enterprise_devicemanagement::OmahaSettingsClientProto>
+GetOmahaPolicySettings(
+    scoped_refptr<device_management_storage::DMStorage> dm_storage);
+
 // A factory method to create a DM policy manager.
 scoped_refptr<PolicyManagerInterface> CreateDMPolicyManager(
     const std::optional<bool>& override_is_managed_device);
diff --git a/chrome/updater/policy/dm_policy_manager_unittest.cc b/chrome/updater/policy/dm_policy_manager_unittest.cc
index 0604667be2..481c4e1 100644
--- a/chrome/updater/policy/dm_policy_manager_unittest.cc
+++ b/chrome/updater/policy/dm_policy_manager_unittest.cc
@@ -7,11 +7,14 @@
 #include <optional>
 
 #include "base/enterprise_util.h"
+#include "base/files/scoped_temp_dir.h"
 #include "base/memory/ref_counted.h"
 #include "build/build_config.h"
+#include "chrome/enterprise_companion/device_management_storage/dm_storage.h"
 #include "chrome/updater/constants.h"
 #include "chrome/updater/test/unit_test_util.h"
 #include "components/policy/proto/device_management_backend.pb.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace updater {
@@ -103,6 +106,82 @@
 
 #endif  // BUILDFLAG(IS_MAC)
 
+class TestTokenService
+    : public device_management_storage::TokenServiceInterface {
+ public:
+  TestTokenService()
+      : enrollment_token_("TestEnrollmentToken"), dm_token_("TestDMToken") {}
+  ~TestTokenService() override = default;
+
+  // Overrides for TokenServiceInterface.
+  std::string GetDeviceID() const override { return "TestDeviceID"; }
+
+  bool IsEnrollmentMandatory() const override { return false; }
+
+  bool StoreEnrollmentToken(const std::string& enrollment_token) override {
+    enrollment_token_ = enrollment_token;
+    return true;
+  }
+
+  bool DeleteEnrollmentToken() override { return StoreEnrollmentToken(""); }
+
+  std::string GetEnrollmentToken() const override { return enrollment_token_; }
+
+  bool StoreDmToken(const std::string& dm_token) override {
+    dm_token_ = dm_token;
+    return true;
+  }
+
+  bool DeleteDmToken() override {
+    dm_token_.clear();
+    return true;
+  }
+
+  std::string GetDmToken() const override { return dm_token_; }
+
+ private:
+  std::string enrollment_token_;
+  std::string dm_token_;
+};
+
+std::string CannedOmahaPolicyFetchResponse() {
+  ::wireless_android_enterprise_devicemanagement::OmahaSettingsClientProto
+      omaha_settings;
+
+  omaha_settings.set_auto_update_check_period_minutes(111);
+  omaha_settings.set_download_preference("cacheable");
+  omaha_settings.mutable_updates_suppressed()->set_start_hour(8);
+  omaha_settings.mutable_updates_suppressed()->set_start_minute(8);
+  omaha_settings.mutable_updates_suppressed()->set_duration_min(47);
+  omaha_settings.set_proxy_mode("proxy_pac_script");
+  omaha_settings.set_proxy_pac_url("foo.c/proxy.pa");
+  omaha_settings.set_install_default(
+      ::wireless_android_enterprise_devicemanagement::INSTALL_DEFAULT_DISABLED);
+  omaha_settings.set_update_default(
+      ::wireless_android_enterprise_devicemanagement::MANUAL_UPDATES_ONLY);
+
+  ::wireless_android_enterprise_devicemanagement::ApplicationSettings app;
+  app.set_app_guid(test::kChromeAppId);
+
+  app.set_install(
+      ::wireless_android_enterprise_devicemanagement::INSTALL_DISABLED);
+  app.set_update(
+      ::wireless_android_enterprise_devicemanagement::AUTOMATIC_UPDATES_ONLY);
+  app.set_target_version_prefix("3.6.55");
+  app.set_rollback_to_target_version(
+      ::wireless_android_enterprise_devicemanagement::
+          ROLLBACK_TO_TARGET_VERSION_ENABLED);
+
+  omaha_settings.mutable_application_settings()->Add(std::move(app));
+
+  ::enterprise_management::PolicyData policy_data;
+  policy_data.set_policy_value(omaha_settings.SerializeAsString());
+
+  ::enterprise_management::PolicyFetchResponse response;
+  response.set_policy_data(policy_data.SerializeAsString());
+  return response.SerializeAsString();
+}
+
 }  // namespace
 
 TEST(DMPolicyManager, DeviceManagementOverride) {
@@ -315,4 +394,50 @@
 
 #endif  // BUILDFLAG(IS_MAC)
 
+TEST(DMPolicyManager, GetOmahaPolicySettings) {
+  device_management_storage::DMPolicyMap policies({
+      {"google/machine-level-omaha", CannedOmahaPolicyFetchResponse()},
+  });
+  base::ScopedTempDir cache_root;
+  ASSERT_TRUE(cache_root.CreateUniqueTempDir());
+  auto storage = base::MakeRefCounted<device_management_storage::DMStorage>(
+      cache_root.GetPath(), std::make_unique<TestTokenService>());
+  EXPECT_TRUE(storage->CanPersistPolicies());
+  EXPECT_TRUE(storage->PersistPolicies(policies));
+
+  std::optional<
+      ::wireless_android_enterprise_devicemanagement::OmahaSettingsClientProto>
+      omaha_settings = GetOmahaPolicySettings(storage);
+  ASSERT_TRUE(omaha_settings);
+  EXPECT_EQ(omaha_settings->auto_update_check_period_minutes(), 111);
+
+  EXPECT_EQ(omaha_settings->updates_suppressed().start_hour(), 8);
+  EXPECT_EQ(omaha_settings->updates_suppressed().start_minute(), 8);
+  EXPECT_EQ(omaha_settings->updates_suppressed().duration_min(), 47);
+
+  EXPECT_EQ(omaha_settings->proxy_mode(), "proxy_pac_script");
+  EXPECT_EQ(omaha_settings->proxy_pac_url(), "foo.c/proxy.pa");
+  EXPECT_FALSE(omaha_settings->has_proxy_server());
+
+  EXPECT_EQ(omaha_settings->download_preference(), "cacheable");
+
+  // Chrome policies.
+  const auto& chrome_settings = omaha_settings->application_settings()[0];
+  EXPECT_EQ(chrome_settings.install(),
+            ::wireless_android_enterprise_devicemanagement::INSTALL_DISABLED);
+  EXPECT_EQ(
+      chrome_settings.update(),
+      ::wireless_android_enterprise_devicemanagement::AUTOMATIC_UPDATES_ONLY);
+  EXPECT_EQ(chrome_settings.target_version_prefix(), "3.6.55");
+  EXPECT_EQ(chrome_settings.rollback_to_target_version(),
+            ::wireless_android_enterprise_devicemanagement::
+                ROLLBACK_TO_TARGET_VERSION_ENABLED);
+
+  // Verify no policy settings once device is de-registered.
+  EXPECT_TRUE(storage->InvalidateDMToken());
+  EXPECT_TRUE(storage->IsDeviceDeregistered());
+  EXPECT_FALSE(storage->IsValidDMToken());
+  ASSERT_FALSE(GetOmahaPolicySettings(storage));
+}
+
 }  // namespace updater
diff --git a/chrome/updater/policy/policy_fetcher.cc b/chrome/updater/policy/policy_fetcher.cc
index 58929b0..a4dc52f 100644
--- a/chrome/updater/policy/policy_fetcher.cc
+++ b/chrome/updater/policy/policy_fetcher.cc
@@ -17,11 +17,11 @@
 #include "base/task/bind_post_task.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/thread_pool.h"
+#include "chrome/enterprise_companion/device_management_storage/dm_storage.h"
 #include "chrome/updater/configurator.h"
 #include "chrome/updater/constants.h"
 #include "chrome/updater/device_management/dm_client.h"
 #include "chrome/updater/device_management/dm_response_validator.h"
-#include "chrome/updater/device_management/dm_storage.h"
 #include "chrome/updater/policy/dm_policy_manager.h"
 #include "chrome/updater/policy/service.h"
 #include "chrome/updater/util/util.h"
@@ -62,7 +62,8 @@
     scoped_refptr<base::SequencedTaskRunner> main_task_runner,
     base::OnceCallback<void(bool, DMClient::RequestResult)> callback) {
   VLOG(1) << __func__;
-  scoped_refptr<DMStorage> dm_storage = GetDefaultDMStorage();
+  scoped_refptr<device_management_storage::DMStorage> dm_storage =
+      device_management_storage::GetDefaultDMStorage();
   if (!dm_storage) {
     main_task_runner->PostTask(
         FROM_HERE,
@@ -113,7 +114,7 @@
   DMClient::FetchPolicy(
       DMClient::CreateDefaultConfigurator(server_url_,
                                           policy_service_proxy_configuration_),
-      GetDefaultDMStorage(),
+      device_management_storage::GetDefaultDMStorage(),
       base::BindOnce(&PolicyFetcher::OnFetchPolicyRequestComplete, this)
           .Then(std::move(callback)));
 }
@@ -138,7 +139,7 @@
             &DMClient::ReportPolicyValidationErrors,
             DMClient::CreateDefaultConfigurator(
                 server_url_, policy_service_proxy_configuration_),
-            GetDefaultDMStorage(), validation_result,
+            device_management_storage::GetDefaultDMStorage(), validation_result,
             base::BindOnce([](DMClient::RequestResult result) {
               if (result != DMClient::RequestResult::kSuccess) {
                 LOG(WARNING)
diff --git a/chrome/updater/policy/service.cc b/chrome/updater/policy/service.cc
index 1667e8a..bf6b340 100644
--- a/chrome/updater/policy/service.cc
+++ b/chrome/updater/policy/service.cc
@@ -405,7 +405,7 @@
         "DownloadPreference",
         base::Value::Dict()
             .Set("value", download_preference.policy())
-            .Set("source", update_supressed_times.effective_policy()->source));
+            .Set("source", download_preference.effective_policy()->source));
   }
 
   const PolicyStatus<int> cache_size_limit = GetPackageCacheSizeLimitMBytes();
diff --git a/chrome/updater/policy/service_unittest.cc b/chrome/updater/policy/service_unittest.cc
index 072ab7c0..05c27dc 100644
--- a/chrome/updater/policy/service_unittest.cc
+++ b/chrome/updater/policy/service_unittest.cc
@@ -448,7 +448,7 @@
                                             .Set("source", "group_policy"))
               .Set("DownloadPreference", base::Value::Dict()
                                              .Set("value", "cacheable")
-                                             .Set("source", "group_policy"))
+                                             .Set("source", "imaginary"))
               .Set("PackageCacheSizeLimit", base::Value::Dict()
                                                 .Set("value", 1000)
                                                 .Set("source", "group_policy"))
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc
index 411ad8e..b84d609 100644
--- a/chrome/updater/test/integration_tests.cc
+++ b/chrome/updater/test/integration_tests.cc
@@ -34,11 +34,11 @@
 #include "build/branding_buildflags.h"
 #include "build/build_config.h"
 #include "build/buildflag.h"
+#include "chrome/enterprise_companion/device_management_storage/dm_storage.h"
 #include "chrome/updater/constants.h"
-#include "chrome/updater/device_management/dm_cached_policy_info.h"
 #include "chrome/updater/device_management/dm_policy_builder_for_testing.h"
-#include "chrome/updater/device_management/dm_storage.h"
 #include "chrome/updater/ipc/ipc_support.h"
+#include "chrome/updater/policy/dm_policy_manager.h"
 #include "chrome/updater/protos/omaha_settings.pb.h"
 #include "chrome/updater/registration_data.h"
 #include "chrome/updater/service_proxy_factory.h"
@@ -2579,11 +2579,12 @@
   ASSERT_NO_FATAL_FAILURE(Install());
   ASSERT_NO_FATAL_FAILURE(ExpectInstalled());
 
-  scoped_refptr<DMStorage> dm_storage = GetDefaultDMStorage();
+  scoped_refptr<device_management_storage::DMStorage> dm_storage =
+      device_management_storage::GetDefaultDMStorage();
   ASSERT_NE(dm_storage, nullptr);
-  std::unique_ptr<OmahaSettingsClientProto> omaha_policy =
-      dm_storage->GetOmahaPolicySettings();
-  ASSERT_TRUE(omaha_policy != nullptr);
+  std::optional<OmahaSettingsClientProto> omaha_policy =
+      GetOmahaPolicySettings(dm_storage);
+  ASSERT_TRUE(omaha_policy);
   EXPECT_EQ(omaha_policy->download_preference(), "not-cacheable");
   EXPECT_EQ(omaha_policy->proxy_mode(), "system");
   EXPECT_EQ(omaha_policy->proxy_server(), "test.proxy.server");
@@ -3035,14 +3036,16 @@
       ExpectNoUpdateSequence(test_server_.get(), kApp1.appid));
   ASSERT_NO_FATAL_FAILURE(RunWake(0));
   ASSERT_TRUE(WaitForUpdaterExit());
-  EXPECT_EQ(GetDefaultDMStorage()->GetDmToken(), kDMToken);
+  EXPECT_EQ(device_management_storage::GetDefaultDMStorage()->GetDmToken(),
+            kDMToken);
 
   // Run a second policy fetch and delete the DM token.
   ExpectDeviceManagementTokenDeletionRequest(test_server_.get(), kDMToken,
                                              /*invalidate_token=*/false);
   ASSERT_NO_FATAL_FAILURE(RunWake(0));
   ASSERT_TRUE(WaitForUpdaterExit());
-  EXPECT_TRUE(GetDefaultDMStorage()->GetDmToken().empty());
+  EXPECT_TRUE(
+      device_management_storage::GetDefaultDMStorage()->GetDmToken().empty());
 
   ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(test_server_.get()));
   ASSERT_NO_FATAL_FAILURE(UninstallApp(kApp1.appid));
@@ -3064,14 +3067,16 @@
       ExpectNoUpdateSequence(test_server_.get(), kApp1.appid));
   ASSERT_NO_FATAL_FAILURE(RunWake(0));
   ASSERT_TRUE(WaitForUpdaterExit());
-  EXPECT_EQ(GetDefaultDMStorage()->GetDmToken(), kDMToken);
+  EXPECT_EQ(device_management_storage::GetDefaultDMStorage()->GetDmToken(),
+            kDMToken);
 
   // Run a second policy fetch and invalidate the DM token.
   ExpectDeviceManagementTokenDeletionRequest(test_server_.get(), kDMToken,
                                              /*invalidate_token=*/true);
   ASSERT_NO_FATAL_FAILURE(RunWake(0));
   ASSERT_TRUE(WaitForUpdaterExit());
-  EXPECT_TRUE(GetDefaultDMStorage()->IsDeviceDeregistered());
+  EXPECT_TRUE(
+      device_management_storage::GetDefaultDMStorage()->IsDeviceDeregistered());
 
   ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(test_server_.get()));
   ASSERT_NO_FATAL_FAILURE(UninstallApp(kApp1.appid));
@@ -3097,8 +3102,9 @@
   ASSERT_NO_FATAL_FAILURE(RunWake(0));
   ASSERT_TRUE(WaitForUpdaterExit());
 
-  scoped_refptr<DMStorage> dm_storage = GetDefaultDMStorage();
-  std::unique_ptr<CachedPolicyInfo> cached_info =
+  scoped_refptr<device_management_storage::DMStorage> dm_storage =
+      device_management_storage::GetDefaultDMStorage();
+  std::unique_ptr<device_management_storage::CachedPolicyInfo> cached_info =
       dm_storage->GetCachedPolicyInfo();
   ASSERT_NE(cached_info, nullptr);
   int64_t initial_key_timestamp = cached_info->timestamp();
diff --git a/chrome/updater/test/integration_tests_impl.cc b/chrome/updater/test/integration_tests_impl.cc
index adf446f..250261b6 100644
--- a/chrome/updater/test/integration_tests_impl.cc
+++ b/chrome/updater/test/integration_tests_impl.cc
@@ -48,10 +48,10 @@
 #include "base/version.h"
 #include "build/build_config.h"
 #include "chrome/common/chrome_paths.h"
+#include "chrome/enterprise_companion/device_management_storage/dm_storage.h"
 #include "chrome/updater/activity.h"
 #include "chrome/updater/constants.h"
 #include "chrome/updater/device_management/dm_policy_builder_for_testing.h"
-#include "chrome/updater/device_management/dm_storage.h"
 #include "chrome/updater/external_constants_builder.h"
 #include "chrome/updater/external_constants_override.h"
 #include "chrome/updater/persisted_data.h"
@@ -323,7 +323,9 @@
           R"(agent=%s\+%s&platform=.*&deviceid=%s)",
           test_server->device_management_path().c_str(), request_type.c_str(),
           PRODUCT_FULLNAME_STRING, kUpdaterVersion,
-          GetDefaultDMStorage()->GetDeviceID().c_str())),
+          device_management_storage::GetDefaultDMStorage()
+              ->GetDeviceID()
+              .c_str())),
       request::GetUpdaterUserAgentMatcher(),
       request::GetHeaderMatcher(
           {{"Authorization",
@@ -1371,7 +1373,8 @@
 #endif  // !BUILDFLAG(IS_WIN)
 
 void DMPushEnrollmentToken(const std::string& enrollment_token) {
-  scoped_refptr<DMStorage> storage = GetDefaultDMStorage();
+  scoped_refptr<device_management_storage::DMStorage> storage =
+      device_management_storage::GetDefaultDMStorage();
   ASSERT_NE(storage, nullptr);
   EXPECT_TRUE(storage->StoreEnrollmentToken(enrollment_token));
   EXPECT_TRUE(storage->DeleteDMToken());
@@ -1381,14 +1384,16 @@
   if (!IsSystemInstall(GetUpdaterScopeForTesting())) {
     return;
   }
-  EXPECT_TRUE(GetDefaultDMStorage()->InvalidateDMToken());
+  EXPECT_TRUE(
+      device_management_storage::GetDefaultDMStorage()->InvalidateDMToken());
 }
 
 void DMCleanup(UpdaterScope scope) {
   if (!IsSystemInstall(GetUpdaterScopeForTesting())) {
     return;
   }
-  scoped_refptr<DMStorage> storage = GetDefaultDMStorage();
+  scoped_refptr<device_management_storage::DMStorage> storage =
+      device_management_storage::GetDefaultDMStorage();
   EXPECT_TRUE(storage->DeleteEnrollmentToken());
   EXPECT_TRUE(storage->DeleteDMToken());
   EXPECT_TRUE(base::DeletePathRecursively(storage->policy_cache_folder()));
@@ -1430,7 +1435,9 @@
             dm_response = GetDMResponseForOmahaPolicy(
                 first_request, rotate_public_key,
                 DMPolicyBuilderForTesting::SigningOption::kSignNormally,
-                dm_token, GetDefaultDMStorage()->GetDeviceID(), omaha_settings);
+                dm_token,
+                device_management_storage::GetDefaultDMStorage()->GetDeviceID(),
+                omaha_settings);
         return dm_response->SerializeAsString();
       }(),
       target_url);
@@ -1449,7 +1456,9 @@
                 DMPolicyBuilderForTesting::CreateInstanceWithOptions(
                     /*first_request=*/false, /*rotate_to_new_key=*/true,
                     DMPolicyBuilderForTesting::SigningOption::kSignNormally,
-                    dm_token, GetDefaultDMStorage()->GetDeviceID())
+                    dm_token,
+                    device_management_storage::GetDefaultDMStorage()
+                        ->GetDeviceID())
                     ->BuildDMResponseForPolicies(
                         {{"a-mock-policy-type-without-new-public-key",
                           omaha_settings.SerializeAsString()},
@@ -1477,7 +1486,9 @@
                 DMPolicyBuilderForTesting::CreateInstanceWithOptions(
                     /*first_request=*/false, /*rotate_to_new_key=*/false,
                     DMPolicyBuilderForTesting::SigningOption::kSignNormally,
-                    dm_token, GetDefaultDMStorage()->GetDeviceID())
+                    dm_token,
+                    device_management_storage::GetDefaultDMStorage()
+                        ->GetDeviceID())
                     ->BuildDMResponseWithError(error_detail);
         return dm_response->SerializeAsString();
       }());
diff --git a/chrome/updater/tools/BUILD.gn b/chrome/updater/tools/BUILD.gn
index 5a2b5f93..49d23a3a2 100644
--- a/chrome/updater/tools/BUILD.gn
+++ b/chrome/updater/tools/BUILD.gn
@@ -53,6 +53,7 @@
   sources = [ "updater_util.cc" ]
   deps = [
     "//base",
+    "//chrome/enterprise_companion/device_management_storage",
     "//chrome/updater:base",
     "//chrome/updater:constants_prod",
     "//chrome/updater:external_constants",
diff --git a/chrome/updater/tools/updater_util.cc b/chrome/updater/tools/updater_util.cc
index 0e20734..8775f4d0 100644
--- a/chrome/updater/tools/updater_util.cc
+++ b/chrome/updater/tools/updater_util.cc
@@ -28,13 +28,12 @@
 #include "base/task/single_thread_task_executor.h"
 #include "base/task/thread_pool.h"
 #include "base/task/thread_pool/thread_pool_instance.h"
+#include "chrome/enterprise_companion/device_management_storage/dm_storage.h"
 #include "chrome/updater/app/app.h"
 #include "chrome/updater/configurator.h"
 #include "chrome/updater/constants.h"
-#include "chrome/updater/device_management/dm_cached_policy_info.h"
 #include "chrome/updater/device_management/dm_message.h"
 #include "chrome/updater/device_management/dm_response_validator.h"
-#include "chrome/updater/device_management/dm_storage.h"
 #include "chrome/updater/external_constants_default.h"
 #include "chrome/updater/ipc/ipc_support.h"
 #include "chrome/updater/policy/service.h"
@@ -146,19 +145,23 @@
   }
 }
 
-scoped_refptr<DMStorage> GetDMStorage() {
+scoped_refptr<device_management_storage::DMStorage> GetDMStorage() {
   const base::FilePath storage_path =
       base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
           kCBCMPolicyPathSwitch);
-  return storage_path.empty() ? GetDefaultDMStorage()
-                              : base::MakeRefCounted<DMStorage>(storage_path);
+  return storage_path.empty()
+             ? device_management_storage::GetDefaultDMStorage()
+             : base::MakeRefCounted<device_management_storage::DMStorage>(
+                   storage_path);
 }
 
-std::unique_ptr<CachedPolicyInfo> GetCachedPolicyInfo(
-    scoped_refptr<DMStorage> dm_storage) {
+std::unique_ptr<device_management_storage::CachedPolicyInfo>
+GetCachedPolicyInfo(
+    scoped_refptr<device_management_storage::DMStorage> dm_storage) {
   const base::FilePath policy_info_file =
       dm_storage->policy_cache_folder().AppendASCII("CachedPolicyInfo");
-  auto cached_info = std::make_unique<CachedPolicyInfo>();
+  auto cached_info =
+      std::make_unique<device_management_storage::CachedPolicyInfo>();
   std::string policy_info_data;
   if (base::PathExists(policy_info_file) &&
       base::ReadFileToString(policy_info_file, &policy_info_data)) {
@@ -211,7 +214,7 @@
     return;
   }
 
-  scoped_refptr<DMStorage> storage = GetDMStorage();
+  scoped_refptr<device_management_storage::DMStorage> storage = GetDMStorage();
   PolicyValidationResult status;
   DMResponseValidator validator(*GetCachedPolicyInfo(storage),
                                 storage->GetDmToken(), storage->GetDeviceID());
@@ -238,7 +241,8 @@
             << std::endl;
 }
 
-void PrintCachedPolicyInfo(const CachedPolicyInfo& cached_info) {
+void PrintCachedPolicyInfo(
+    const device_management_storage::CachedPolicyInfo& cached_info) {
   constexpr size_t kPrintWidth = 16;
 
   std::cout << "Cached policy info:" << std::endl;
@@ -258,7 +262,7 @@
 }
 
 void PrintCBCMPolicies() {
-  scoped_refptr<DMStorage> storage = GetDMStorage();
+  scoped_refptr<device_management_storage::DMStorage> storage = GetDMStorage();
   if (!storage) {
     std::cerr << "Failed to instantiate DM storage instance." << std::endl;
     return;
@@ -271,7 +275,8 @@
   std::cout << "DM token: " << storage->GetDmToken() << std::endl;
   std::cout << "-------------------------------------------------" << std::endl;
 
-  std::unique_ptr<CachedPolicyInfo> cached_info = GetCachedPolicyInfo(storage);
+  std::unique_ptr<device_management_storage::CachedPolicyInfo> cached_info =
+      GetCachedPolicyInfo(storage);
   if (cached_info) {
     PrintCachedPolicyInfo(*cached_info);
     std::cout << "-------------------------------------------------"
diff --git a/chrome/utility/safe_browsing/mac/read_stream.h b/chrome/utility/safe_browsing/mac/read_stream.h
index 17b61b63..53f39a0 100644
--- a/chrome/utility/safe_browsing/mac/read_stream.h
+++ b/chrome/utility/safe_browsing/mac/read_stream.h
@@ -13,6 +13,7 @@
 
 #include "base/containers/span.h"
 #include "base/files/file.h"
+#include "base/memory/raw_span.h"
 
 namespace safe_browsing {
 namespace dmg {
@@ -81,7 +82,7 @@
   base::span<const uint8_t> byte_buf() const { return byte_buf_; }
 
  protected:
-  base::span<const uint8_t> byte_buf_;
+  base::raw_span<const uint8_t> byte_buf_;
   off_t offset_;
 };
 
diff --git a/chromeos/ash/components/login/auth/auth_performer.cc b/chromeos/ash/components/login/auth/auth_performer.cc
index c53fa8a..aabf1e4 100644
--- a/chromeos/ash/components/login/auth/auth_performer.cc
+++ b/chromeos/ash/components/login/auth/auth_performer.cc
@@ -599,6 +599,12 @@
         !cryptohome::SafeConvertFactorTypeFromProto(factor_proto.type())) {
       continue;
     }
+    // TODO(b/347292062): Implement legacy fingerprint auth factor engine so
+    // we can get rid of the the following temporary workaround.
+    if (factor_proto.type() ==
+        user_data_auth::AUTH_FACTOR_TYPE_LEGACY_FINGERPRINT) {
+      continue;
+    }
     next_factors.emplace_back(
         cryptohome::DeserializeAuthFactor(factor_proto, fallback_type));
   }
diff --git a/chromeos/ash/components/login/auth/auth_performer_unittest.cc b/chromeos/ash/components/login/auth/auth_performer_unittest.cc
index db33a42..6b4a80a9 100644
--- a/chromeos/ash/components/login/auth/auth_performer_unittest.cc
+++ b/chromeos/ash/components/login/auth/auth_performer_unittest.cc
@@ -164,6 +164,48 @@
   EXPECT_TRUE(user_context->GetAuthFactorsData().FindKioskFactor());
 }
 
+// Checks that a legacy fp factor returned by StartAuthSession() is skipped.
+TEST_F(AuthPerformerTest, StartWithLegacyFp) {
+  EXPECT_CALL(mock_client_, StartAuthSession(_, _))
+      .WillOnce([](const ::user_data_auth::StartAuthSessionRequest& request,
+                   UserDataAuthClient::StartAuthSessionCallback callback) {
+        ::user_data_auth::StartAuthSessionReply reply;
+        reply.set_auth_session_id("123");
+        reply.set_broadcast_id("broadcast");
+        reply.set_user_exists(true);
+        auto* legacy_fp_factor = reply.add_auth_factors();
+        legacy_fp_factor->set_label("");
+        legacy_fp_factor->set_type(user_data_auth::AuthFactorType::
+                                       AUTH_FACTOR_TYPE_LEGACY_FINGERPRINT);
+        auto* password_factor = reply.add_auth_factors();
+        password_factor->set_label("password");
+        password_factor->set_type(
+            user_data_auth::AuthFactorType::AUTH_FACTOR_TYPE_PASSWORD);
+        std::move(callback).Run(reply);
+      });
+  AuthPerformer performer(&mock_client_);
+
+  // Act.
+  base::test::TestFuture<bool, std::unique_ptr<UserContext>,
+                         std::optional<AuthenticationError>>
+      result;
+  performer.StartAuthSession(std::move(context_), /*ephemeral=*/false,
+                             AuthSessionIntent::kVerifyOnly,
+                             result.GetCallback());
+  auto [user_exists, user_context, cryptohome_error] = result.Take();
+
+  // Assert: no error, user context has AuthSession ID and the password factor.
+  EXPECT_TRUE(user_exists);
+  ASSERT_TRUE(user_context);
+  EXPECT_EQ(user_context->GetAuthSessionId(), "123");
+  EXPECT_EQ(user_context->GetBroadcastId(), "broadcast");
+  EXPECT_TRUE(user_context->GetAuthFactorsData().FindPasswordFactor(
+      cryptohome::KeyLabel{"password"}));
+  EXPECT_EQ(user_context->GetAuthFactorsData().FindFactorByType(
+                cryptohome::AuthFactorType::kLegacyFingerprint),
+            nullptr);
+}
+
 // Checks that AuthenticateUsingKnowledgeKey (which will be called with "gaia"
 // label after online authentication) correctly falls back to "legacy-0" label.
 TEST_F(AuthPerformerTest, KnowledgeKeyCorrectLabelFallback) {
diff --git a/chromeos/ash/components/network/network_connection_handler_impl.cc b/chromeos/ash/components/network/network_connection_handler_impl.cc
index ee5b823..525f443 100644
--- a/chromeos/ash/components/network/network_connection_handler_impl.cc
+++ b/chromeos/ash/components/network/network_connection_handler_impl.cc
@@ -1102,6 +1102,13 @@
     return;
   }
   if (NetworkState::StateIsConnected(connection_state)) {
+    if (network->type() == shill::kTypeWifi) {
+      base::Value::Dict config_properties;
+      config_properties.Set(shill::kGuidProperty, network->guid());
+      configuration_handler_->SetShillProperties(
+          service_path, config_properties, base::DoNothing(),
+          network_handler::ErrorCallback());
+    }
     if (!request->profile_path.empty()) {
       // If a profile path was specified, set it on a successful connection.
       configuration_handler_->SetNetworkProfile(
diff --git a/chromeos/ash/components/network/network_connection_handler_impl_unittest.cc b/chromeos/ash/components/network/network_connection_handler_impl_unittest.cc
index 69bdfc6..20d4f2b 100644
--- a/chromeos/ash/components/network/network_connection_handler_impl_unittest.cc
+++ b/chromeos/ash/components/network/network_connection_handler_impl_unittest.cc
@@ -651,6 +651,8 @@
   EXPECT_TRUE(network_connection_observer()->GetRequested(wifi0_service_path));
   EXPECT_EQ(kSuccessResult,
             network_connection_observer()->GetResult(wifi0_service_path));
+  EXPECT_EQ("wifi0",
+            GetServiceStringProperty(wifi0_service_path, shill::kGuidProperty));
 }
 
 TEST_F(NetworkConnectionHandlerImplTest,
diff --git a/chromeos/ash/components/network/network_metadata_store_unittest.cc b/chromeos/ash/components/network/network_metadata_store_unittest.cc
index fc4d1ea..627ee37 100644
--- a/chromeos/ash/components/network/network_metadata_store_unittest.cc
+++ b/chromeos/ash/components/network/network_metadata_store_unittest.cc
@@ -402,7 +402,7 @@
   metadata_store()->SetIsConfiguredBySync(kGuid);
   ASSERT_FALSE(metadata_store()->GetLastConnectedTimestamp(kGuid).is_zero());
   ASSERT_TRUE(metadata_store()->GetIsConfiguredBySync(kGuid));
-  ASSERT_EQ(0, metadata_observer()->GetNumberOfUpdates(kGuid));
+  ASSERT_EQ(1, metadata_observer()->GetNumberOfUpdates(kGuid));
 
   auto properties =
       base::Value::Dict()
@@ -416,7 +416,7 @@
 
   ASSERT_TRUE(metadata_store()->GetLastConnectedTimestamp(kGuid).is_zero());
   ASSERT_FALSE(metadata_store()->GetIsConfiguredBySync(kGuid));
-  ASSERT_EQ(1, metadata_observer()->GetNumberOfUpdates(kGuid));
+  ASSERT_EQ(2, metadata_observer()->GetNumberOfUpdates(kGuid));
 }
 
 TEST_F(NetworkMetadataStoreTest, SharedConfigurationUpdatedByOtherUser) {
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd
index 6c9a1d0..d19dbcf 100644
--- a/chromeos/chromeos_strings.grd
+++ b/chromeos/chromeos_strings.grd
@@ -3116,6 +3116,48 @@
         <message name="IDS_OS_SANITIZE_APP_NAME" desc="Name of the Sanitize web app" translateable="false">
           Sanitize
         </message>
+        <message name="IDS_SANITIZE_DONE_HEADING" desc="Name of the 'Safety reset done' window" translateable="false">
+          Your device is sanitized
+        </message>
+        <message name="IDS_SANITIZE_DONE_DESCRIPTION" desc="Description of the safety reset done dialog" translateable="false">
+          Your ChromeOS device was reset to safe defaults.
+        </message>
+        <message name="IDS_SANITIZE_DONE_ROLLBACK" desc="Description of how the user can roll back changes" translateable="false">
+          We made changes to make your device more secure, you can undo some of our changes below.
+        </message>
+        <message name="IDS_SANITIZE_DONE" desc="Name of the button that will close the sanitize done dialog" translateable="false">
+          Done
+        </message>
+        <message name="IDS_SANITIZE_DONE_ACCORDION_EXTENSIONS_TITLE" translateable="false">
+          Your Extensions
+        </message>
+        <message name="IDS_SANITIZE_DONE_ACCORDION_EXTENSIONS_REENABLE" translateable="false">
+          Re-enable extensions you trust
+        </message>
+        <message name="IDS_SANITIZE_DONE_ACCORDION_CHROMEOS_TITLE" translateable="false">
+          Your ChromeOS Settings
+        </message>
+        <message name="IDS_SANITIZE_DONE_ACCORDION_CHROMEOS_INPUT" translateable="false">
+          Verify your input method
+        </message>
+        <message name="IDS_SANITIZE_DONE_ACCORDION_CHROMEOS_NETWORK" translateable="false">
+          Check your current network
+        </message>
+        <message name="IDS_SANITIZE_DONE_ACCORDION_CHROME_TITLE" translateable="false">
+          Your Chrome Settings
+        </message>
+        <message name="IDS_SANITIZE_DONE_ACCORDION_CHROME_SITE_CONTENT" translateable="false">
+          Verify your site content settings
+        </message>
+        <message name="IDS_SANITZIE_DONE_ACCORDION_CHROME_STARTUP" translateable="false">
+          Check your Chrome startup preferences
+        </message>
+        <message name="IDS_SANITIZE_DONE_ACCORDION_CHROME_HOMEPAGE" translateable="false">
+          Verify the status of your homepage
+        </message>
+        <message name="IDS_SANITIZE_DONE_ACCORDION_CHROME_LANGUAGES" translateable="false">
+          Verify your language settings
+        </message>
 
         <!-- Sea Pen UI -->
         <message name="IDS_SEA_PEN_LABEL" desc="Label for the Create with AI feature.">
diff --git a/chromeos/components/kcer/cert_cache.cc b/chromeos/components/kcer/cert_cache.cc
index 33a39c6f..bf1ce08 100644
--- a/chromeos/components/kcer/cert_cache.cc
+++ b/chromeos/components/kcer/cert_cache.cc
@@ -4,11 +4,12 @@
 
 #include "chromeos/components/kcer/cert_cache.h"
 
-#include <vector>
-
 #include <stdint.h>
 
+#include <vector>
+
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "chromeos/components/kcer/kcer.h"
 #include "net/cert/x509_util.h"
 
@@ -31,7 +32,7 @@
   }
 
  private:
-  base::span<const uint8_t> data_;
+  base::raw_span<const uint8_t> data_;
 };
 
 }  // namespace
diff --git a/chromeos/crosapi/mojom/magic_boost.mojom b/chromeos/crosapi/mojom/magic_boost.mojom
index fbc1356..3ffd93a 100644
--- a/chromeos/crosapi/mojom/magic_boost.mojom
+++ b/chromeos/crosapi/mojom/magic_boost.mojom
@@ -6,6 +6,8 @@
 
 // This API is used to forward requests to conduct Magic Boost opt-in flow
 // from Lacros (Client) to the actual implementation in Ash-Chrome.
+// Next Method ID: 2
+// Next MinVersion: 2
 [Stable, Uuid="7045789d-b1df-422c-a9c2-39990e977b2b"]
 interface MagicBoostController {
   // Specifies which action to complete after the opt-in flow has been
@@ -21,4 +23,7 @@
 
   // Shows the disclaimer UI in the given `display_id`.
   ShowDisclaimerUi@0(int64 display_id, TransitionAction action);
+
+  // Closes the disclaimer UI.
+  [MinVersion=1] CloseDisclaimerUi@1();
 };
diff --git a/chromeos/strings/chromeos_strings_en-GB.xtb b/chromeos/strings/chromeos_strings_en-GB.xtb
index 74dee10..fc8b3ba 100644
--- a/chromeos/strings/chromeos_strings_en-GB.xtb
+++ b/chromeos/strings/chromeos_strings_en-GB.xtb
@@ -1255,7 +1255,7 @@
 <translation id="802154636333426148">Download failed</translation>
 <translation id="8031884997696620457">HSPAPlus</translation>
 <translation id="80398733265834479">Enable auto colour mode</translation>
-<translation id="8041089156583427627">Send Feedback</translation>
+<translation id="8041089156583427627">Send feedback</translation>
 <translation id="8045012663542226664">Microphone mute</translation>
 <translation id="8054112564438735763">beige</translation>
 <translation id="8062968459344882447"><ph name="CHARACTERS_COLOR" /> <ph name="CHARACTERS_SUBJECTS" /> on a <ph name="CHARACTERS_BACKGROUND" /> background</translation>
diff --git a/chromeos/strings/chromeos_strings_hy.xtb b/chromeos/strings/chromeos_strings_hy.xtb
index 481a8ff..33c8186 100644
--- a/chromeos/strings/chromeos_strings_hy.xtb
+++ b/chromeos/strings/chromeos_strings_hy.xtb
@@ -13,6 +13,7 @@
 <translation id="1049663189809099096">պաստելային դեղին</translation>
 <translation id="1056898198331236512">Զգուշացում</translation>
 <translation id="1059913517121127803">Չհաջողվեց սկսել սկանավորումը</translation>
+<translation id="1061864016440983342">Օգտագործել առանց տեղորոշման</translation>
 <translation id="1062823486781306604"><ph name="INDEX" />/<ph name="COUNT" />, <ph name="NAME" />։</translation>
 <translation id="1070066693520972135">WEP</translation>
 <translation id="1071587090247825784">Հայտնաբերվել է հրապատ</translation>
@@ -217,6 +218,7 @@
 <translation id="2080070583977670716">Այլ կարգավորումներ</translation>
 <translation id="2082932131694554252">Նշանակված ստեղն</translation>
 <translation id="2085089206770112532">Էկրանի պայծառության նվազեցում</translation>
+<translation id="2086091080968010660">Ժամանակի հիման վրա փոփոխությունները կարող են ճշգրիտ չլինել։ Միացրեք համակարգի տեղորոշման թույլտվությունը կարգավորումներում։</translation>
 <translation id="2102231663024125441">Տեքստի խմբագրում</translation>
 <translation id="2105810540595158374">Սարքը խաղային վահանակ է։</translation>
 <translation id="2119172414412204879"><ph name="BOARD_NAME" />, տարբերակ <ph name="MILESTONE_VERSION" /></translation>
@@ -258,6 +260,7 @@
 <translation id="2279051792571591988">Վերականգնել կանխադրված կարգավորումները</translation>
 <translation id="2286454467119466181">Պարզեցված</translation>
 <translation id="2287186687001756809">Ոչ մի պատկեր չկա։ Լուսանկարներ ավելացնելու համար անցեք <ph name="LINK" />։</translation>
+<translation id="2294577623958216786">Ընթացիկ ժամանակացույցը՝ <ph name="SUNRISE" /> – <ph name="SUNSET" />։ Արևածագի և մայրամուտի ժամանակացույցն ավտոմատ թարմացնելու համար միացրեք տեղորոշման թույլտվությունը։</translation>
 <translation id="2305172810646967500">սև</translation>
 <translation id="2307344026739914387">Օգտագործել ընթացիկ բանալիների զույգը</translation>
 <translation id="2308243864813041101">Թարմացումը շարունակելու համար անջատեք USB մալուխը <ph name="DEVICE_NAME" /> սարքից</translation>
@@ -961,6 +964,7 @@
 <translation id="6411934471898487866">ստեղնաշարի պայծառություն</translation>
 <translation id="6412715219990689313">Ներկառուցված ստեղնաշար</translation>
 <translation id="6417265370957905582">Google Օգնական</translation>
+<translation id="6419454453018688975">Միացնել համակարգի տեղորոշման թույլտվությունը</translation>
 <translation id="6423239382391657905">OpenVPN</translation>
 <translation id="6439505561246192797">Թույլ (<ph name="SIGNAL_STRENGTH" />)</translation>
 <translation id="6447630859861661624">Անցնել հաշվի կարգավորումներ</translation>
diff --git a/chromeos/strings/chromeos_strings_mr.xtb b/chromeos/strings/chromeos_strings_mr.xtb
index d69d254..1deb3cf 100644
--- a/chromeos/strings/chromeos_strings_mr.xtb
+++ b/chromeos/strings/chromeos_strings_mr.xtb
@@ -13,6 +13,7 @@
 <translation id="1049663189809099096">पेस्टल पिवळे</translation>
 <translation id="1056898198331236512">चेतावणी</translation>
 <translation id="1059913517121127803">स्कॅनिंग सुरू करता आले नाही</translation>
+<translation id="1061864016440983342">स्थानाशिवाय वापरा</translation>
 <translation id="1062823486781306604"><ph name="COUNT" /> पैकी <ph name="INDEX" />, <ph name="NAME" />.</translation>
 <translation id="1070066693520972135">WEP</translation>
 <translation id="1071587090247825784">फायरवॉल डिटेक्ट केली</translation>
@@ -217,6 +218,7 @@
 <translation id="2080070583977670716">अधिक सेटिंग्ज</translation>
 <translation id="2082932131694554252">कीबोर्डची की असाइन केली आहे</translation>
 <translation id="2085089206770112532">डिस्प्लेचा ब्राइटनेस कमी करा</translation>
+<translation id="2086091080968010660">वेळेवर आधारित बदल हे कदाचित अचूक नसू शकतात. सेटिंग्जमध्ये सिस्टीम स्थान अ‍ॅक्सेस सुरू करा.</translation>
 <translation id="2102231663024125441">मजकूर संपादन</translation>
 <translation id="2105810540595158374">डिव्हाइस हे गेम नियंत्रक आहे.</translation>
 <translation id="2119172414412204879"><ph name="BOARD_NAME" />, आवृत्ती <ph name="MILESTONE_VERSION" /></translation>
@@ -258,6 +260,7 @@
 <translation id="2279051792571591988">डीफॉल्ट रिस्टोअर करा</translation>
 <translation id="2286454467119466181">साधी</translation>
 <translation id="2287186687001756809">इमेज उपलब्ध नाही. फोटो जोडण्यासाठी, <ph name="LINK" /> वर जा</translation>
+<translation id="2294577623958216786">सद्य शेड्यूल हे <ph name="SUNRISE" />-<ph name="SUNSET" /> वर सेट केले आहे. सूर्यास्त आणि सूर्योदय शेड्यूल आपोआप अपडेट करण्यासाठी, सिस्टीम स्थान अ‍ॅक्सेस सुरू करा.</translation>
 <translation id="2305172810646967500">काळा</translation>
 <translation id="2307344026739914387">सध्याचे कीपेअर वापरा</translation>
 <translation id="2308243864813041101">अपडेट करण्याची प्रक्रिया पुढे सुरू ठेवण्यासाठी, <ph name="DEVICE_NAME" /> ची USB केबल अनप्लग करा</translation>
@@ -961,6 +964,7 @@
 <translation id="6411934471898487866">कीबोर्ड ब्राइटनेस</translation>
 <translation id="6412715219990689313">बिल्ट-इन कीबोर्ड</translation>
 <translation id="6417265370957905582">Google Assistant</translation>
+<translation id="6419454453018688975">सिस्टीम स्थान अ‍ॅक्सेस सुरू करा</translation>
 <translation id="6423239382391657905">OpenVPN</translation>
 <translation id="6439505561246192797">कमकुवत (<ph name="SIGNAL_STRENGTH" />)</translation>
 <translation id="6447630859861661624">खाते सेटिंग्ज मध्ये जा</translation>
diff --git a/chromeos/strings/chromeos_strings_ms.xtb b/chromeos/strings/chromeos_strings_ms.xtb
index 16452d4..2486ddd 100644
--- a/chromeos/strings/chromeos_strings_ms.xtb
+++ b/chromeos/strings/chromeos_strings_ms.xtb
@@ -13,6 +13,7 @@
 <translation id="1049663189809099096">kuning pastel</translation>
 <translation id="1056898198331236512">Amaran</translation>
 <translation id="1059913517121127803">Tidak dapat memulakan pengimbasan</translation>
+<translation id="1061864016440983342">Gunakan tanpa lokasi</translation>
 <translation id="1062823486781306604"><ph name="INDEX" /> daripada <ph name="COUNT" />, <ph name="NAME" />.</translation>
 <translation id="1070066693520972135">WEP</translation>
 <translation id="1071587090247825784">Tembok api dikesan</translation>
@@ -217,6 +218,7 @@
 <translation id="2080070583977670716">Lagi tetapan</translation>
 <translation id="2082932131694554252">Serahkan kunci papan kekunci</translation>
 <translation id="2085089206770112532">Kurangkan kecerahan paparan</translation>
+<translation id="2086091080968010660">Perubahan berdasarkan masa mungkin tidak tepat. Hidupkan akses lokasi sistem dalam tetapan.</translation>
 <translation id="2102231663024125441">Pengeditan teks</translation>
 <translation id="2105810540595158374">Peranti ialah pengawal permainan.</translation>
 <translation id="2119172414412204879"><ph name="BOARD_NAME" />, versi <ph name="MILESTONE_VERSION" /></translation>
@@ -258,6 +260,7 @@
 <translation id="2279051792571591988">Pulihkan lalai</translation>
 <translation id="2286454467119466181">Ringkas</translation>
 <translation id="2287186687001756809">Tiada imej tersedia. Untuk menambah foto, lawati <ph name="LINK" /></translation>
+<translation id="2294577623958216786">Jadual semasa ditetapkan kepada <ph name="SUNRISE" />-<ph name="SUNSET" />. Untuk mengemaskinikan jadual matahari terbenam dan matahari terbit secara automatik, hidupkan akses lokasi sistem.</translation>
 <translation id="2305172810646967500">hitam</translation>
 <translation id="2307344026739914387">Gunakan pasangan kunci semasa</translation>
 <translation id="2308243864813041101">Cabut kabel USB <ph name="DEVICE_NAME" /> untuk meneruskan proses kemaskinian</translation>
@@ -961,6 +964,7 @@
 <translation id="6411934471898487866">kecerahan papan kekunci</translation>
 <translation id="6412715219990689313">Papan kekunci terbina dalam</translation>
 <translation id="6417265370957905582">Google Assistant</translation>
+<translation id="6419454453018688975">Hidupkan akses lokasi sistem</translation>
 <translation id="6423239382391657905">OpenVPN</translation>
 <translation id="6439505561246192797">Lemah (<ph name="SIGNAL_STRENGTH" />)</translation>
 <translation id="6447630859861661624">Pergi ke tetapan akaun</translation>
diff --git a/chromeos/strings/chromeos_strings_nl.xtb b/chromeos/strings/chromeos_strings_nl.xtb
index b421287..ee7385a7 100644
--- a/chromeos/strings/chromeos_strings_nl.xtb
+++ b/chromeos/strings/chromeos_strings_nl.xtb
@@ -13,6 +13,7 @@
 <translation id="1049663189809099096">pastelgeel</translation>
 <translation id="1056898198331236512">Waarschuwing</translation>
 <translation id="1059913517121127803">Kan scannen niet starten</translation>
+<translation id="1061864016440983342">Gebruiken zonder locatie</translation>
 <translation id="1062823486781306604"><ph name="INDEX" /> van <ph name="COUNT" />, <ph name="NAME" />.</translation>
 <translation id="1070066693520972135">WEP</translation>
 <translation id="1071587090247825784">Firewall waargenomen</translation>
@@ -217,6 +218,7 @@
 <translation id="2080070583977670716">Meer instellingen</translation>
 <translation id="2082932131694554252">Toegewezen toetsenbordtoets</translation>
 <translation id="2085089206770112532">Helderheid van scherm verlagen</translation>
+<translation id="2086091080968010660">Tijdgebaseerde wijzigingen zijn misschien niet nauwkeurig. Zet locatietoegang voor het systeem aan in de instellingen.</translation>
 <translation id="2102231663024125441">Tekstbewerking</translation>
 <translation id="2105810540595158374">Apparaat is een gamecontroller.</translation>
 <translation id="2119172414412204879"><ph name="BOARD_NAME" />, versie <ph name="MILESTONE_VERSION" /></translation>
@@ -258,6 +260,7 @@
 <translation id="2279051792571591988">Standaardwaarden herstellen</translation>
 <translation id="2286454467119466181">Eenvoudig</translation>
 <translation id="2287186687001756809">Geen afbeelding beschikbaar. Ga naar <ph name="LINK" /> als je foto's wilt toevoegen.</translation>
+<translation id="2294577623958216786">Huidige planning is ingesteld op <ph name="SUNRISE" />-<ph name="SUNSET" />. Als je de planning voor zonsondergang en zonsopgang automatisch wilt updaten, zet je locatietoegang voor het systeem aan.</translation>
 <translation id="2305172810646967500">zwart</translation>
 <translation id="2307344026739914387">Huidig sleutelpaar gebruiken</translation>
 <translation id="2308243864813041101">Koppel de USB-kabel van je <ph name="DEVICE_NAME" /> los om door te gaan met het updateproces</translation>
@@ -961,6 +964,7 @@
 <translation id="6411934471898487866">helderheid toetsenbord</translation>
 <translation id="6412715219990689313">Geïntegreerd toetsenbord</translation>
 <translation id="6417265370957905582">Google Assistent</translation>
+<translation id="6419454453018688975">Locatietoegang voor het systeem aanzetten</translation>
 <translation id="6423239382391657905">OpenVPN</translation>
 <translation id="6439505561246192797">Zwak (<ph name="SIGNAL_STRENGTH" />)</translation>
 <translation id="6447630859861661624">Naar Accountinstellingen gaan</translation>
diff --git a/chromeos/strings/chromeos_strings_uz.xtb b/chromeos/strings/chromeos_strings_uz.xtb
index 44151514..6935b2d 100644
--- a/chromeos/strings/chromeos_strings_uz.xtb
+++ b/chromeos/strings/chromeos_strings_uz.xtb
@@ -13,6 +13,7 @@
 <translation id="1049663189809099096">pastel sariq</translation>
 <translation id="1056898198331236512">Ogohlantirish</translation>
 <translation id="1059913517121127803">Skanerlash ishga tushmadi</translation>
+<translation id="1061864016440983342">Joylashuvsiz foydalanish</translation>
 <translation id="1062823486781306604"><ph name="INDEX" />/<ph name="COUNT" />, <ph name="NAME" />.</translation>
 <translation id="1070066693520972135">WEP</translation>
 <translation id="1071587090247825784">Himoya devori aniqlandi</translation>
@@ -217,6 +218,7 @@
 <translation id="2080070583977670716">Kengaytirilgan sozlamalar</translation>
 <translation id="2082932131694554252">Tayinlangan tugma</translation>
 <translation id="2085089206770112532">Displey yorlinligini pasaytirish</translation>
+<translation id="2086091080968010660">Vaqt asosidagi oʻzgarishlar aniq boʻlmasligi mumkin. Sozlamalar orqali tizim darajasidagi joylashuv ruxsatini yoqing.</translation>
 <translation id="2102231663024125441">Matn tahrirlash</translation>
 <translation id="2105810540595158374">Qurilma — geympad</translation>
 <translation id="2119172414412204879"><ph name="BOARD_NAME" />, versiya: <ph name="MILESTONE_VERSION" /></translation>
@@ -258,6 +260,7 @@
 <translation id="2279051792571591988">Andozalarni tiklash</translation>
 <translation id="2286454467119466181">Oddiy interfeys</translation>
 <translation id="2287186687001756809">Hech qanday rasm topilmadi. Suratlar kiritish uchun <ph name="LINK" /> sahifasini oching.</translation>
+<translation id="2294577623958216786">Jadval bunday sozlangan: <ph name="SUNRISE" />-<ph name="SUNSET" />. Quyosh chiqishi va botishi rejasini avtomatik yangilash uchun tizim darajasidagi joylashuv axborotiga ruxsatni yoqing.</translation>
 <translation id="2305172810646967500">qora</translation>
 <translation id="2307344026739914387">Joriy kalitlar juftligidan foydalanish</translation>
 <translation id="2308243864813041101">Yangilashda davom etish uchun <ph name="DEVICE_NAME" /> USB kabelini uzing</translation>
@@ -961,6 +964,7 @@
 <translation id="6411934471898487866">klaviatura yorqinligi</translation>
 <translation id="6412715219990689313">Ichki klaviatura</translation>
 <translation id="6417265370957905582">Google Assistent</translation>
+<translation id="6419454453018688975">Tizim darajasidagi joylashuvga ruxsatni yoqish</translation>
 <translation id="6423239382391657905">OpenVPN</translation>
 <translation id="6439505561246192797">Zaif (<ph name="SIGNAL_STRENGTH" />)</translation>
 <translation id="6447630859861661624">Hisob sozlamalarini ochish</translation>
diff --git a/clank b/clank
index ebe9c7d..502004c 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit ebe9c7de0e204bbe1d3f11af3717aea5529d1d60
+Subproject commit 502004caf543a3bc541487ae4f4c65486f50fb5a
diff --git a/components/android_autofill/browser/android_autofill_client.cc b/components/android_autofill/browser/android_autofill_client.cc
index 8558124..633dc9ea 100644
--- a/components/android_autofill/browser/android_autofill_client.cc
+++ b/components/android_autofill/browser/android_autofill_client.cc
@@ -97,7 +97,7 @@
 }
 
 syncer::SyncService* AndroidAutofillClient::GetSyncService() {
-  // TODO(b/321949351): Move this and other stubs into AutofillClient.
+  // TODO(crbug.com/321949351): Move this and other stubs into AutofillClient.
   return nullptr;
 }
 
@@ -118,7 +118,8 @@
 }
 
 ukm::SourceId AndroidAutofillClient::GetUkmSourceId() {
-  // TODO(b/321677608): Consider UKM recording via delegate (non-WebView only).
+  // TODO(crbug.com/321677608): Consider UKM recording via delegate (non-WebView
+  // only).
   return ukm::kInvalidSourceId;
 }
 
@@ -137,7 +138,7 @@
 
 security_state::SecurityLevel
 AndroidAutofillClient::GetSecurityLevelForUmaHistograms() {
-  // TODO(b/321677908): Consider recording for non-webview.
+  // TODO(crbug.com/321677908): Consider recording for non-webview.
   // Return the count value which will not be recorded.
   return security_state::SecurityLevel::SECURITY_LEVEL_COUNT;
 }
@@ -252,7 +253,8 @@
   ssl_status = navigation_entry->GetSSL();
   // Note: As of crbug.com/701018, Chrome relies on SecurityStateTabHelper to
   // determine whether the page is secure, but WebView has no equivalent class.
-  // TODO(b/321679324): Consider injecting SecurityStateTabHelper for 3P chrome.
+  // TODO(crbug.com/321679324): Consider injecting SecurityStateTabHelper for 3P
+  // chrome.
 
   return navigation_entry->GetURL().SchemeIsCryptographic() &&
          ssl_status.certificate &&
diff --git a/components/android_autofill/browser/android_autofill_provider.cc b/components/android_autofill/browser/android_autofill_provider.cc
index b86dc60..d13080f4 100644
--- a/components/android_autofill/browser/android_autofill_provider.cc
+++ b/components/android_autofill/browser/android_autofill_provider.cc
@@ -173,12 +173,14 @@
         }
       });
 
+  current_field_ = {field.global_id(),
+                    manager->ComputeFieldTypeGroupForField(form, field),
+                    field.origin()};
+
   // Focus or field value change will also trigger the query, so it should be
   // ignored if the form is same.
   if (!IsLinkedForm(form)) {
     StartNewSession(manager, form, field);
-  } else {
-    last_focused_field_id_ = field.global_id();
   }
 
   if (field.datalist_options().empty()) {
@@ -237,9 +239,6 @@
     return;
   }
 
-  last_focused_field_id_ = field.global_id();
-  field_type_group_ = manager->ComputeFieldTypeGroupForField(form, field);
-  triggered_origin_ = field.origin();
   check_submission_ = false;
   manager_ = manager->GetWeakPtrToLeafClass();
 
@@ -308,8 +307,8 @@
   was_bottom_sheet_just_shown_ = false;
   if (manager_ && form_) {
     form_->UpdateFromJava();
-    FillOrPreviewForm(manager_.get(), form_->form(), field_type_group_,
-                      triggered_origin_);
+    FillOrPreviewForm(manager_.get(), form_->form(), current_field_.group,
+                      current_field_.origin);
   }
 }
 
@@ -317,8 +316,8 @@
     const std::u16string& value) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (manager_) {
-    RendererShouldAcceptDataListSuggestion(manager_.get(),
-                                           last_focused_field_id_, value);
+    RendererShouldAcceptDataListSuggestion(manager_.get(), current_field_.id,
+                                           value);
   }
 }
 
@@ -619,9 +618,7 @@
 void AndroidAutofillProvider::Reset() {
   manager_ = nullptr;
   form_.reset();
-  last_focused_field_id_ = {};
-  field_type_group_ = FieldTypeGroup::kNoGroup;
-  triggered_origin_ = {};
+  current_field_ = {};
   check_submission_ = false;
   was_shown_bottom_sheet_timer_.Stop();
   was_bottom_sheet_just_shown_ = false;
diff --git a/components/android_autofill/browser/android_autofill_provider.h b/components/android_autofill/browser/android_autofill_provider.h
index cd3a08d..aa9470f 100644
--- a/components/android_autofill/browser/android_autofill_provider.h
+++ b/components/android_autofill/browser/android_autofill_provider.h
@@ -283,8 +283,12 @@
 
   // Properties of the last-focused field of the current session for `form_`
   // (queried input or changed select box).
-  FieldGlobalId last_focused_field_id_;
-  FieldTypeGroup field_type_group_{FieldTypeGroup::kNoGroup};
+  struct CurrentFieldInfo {
+    FieldGlobalId id;
+    FieldTypeGroup group{FieldTypeGroup::kNoGroup};
+    url::Origin origin;
+  };
+  CurrentFieldInfo current_field_;
 
   // The frame of the field for which the last OnAskForValuesToFill() happened.
   //
@@ -297,10 +301,6 @@
   // ancestor frame of the queried field.
   content::GlobalRenderFrameHostId last_queried_field_rfh_id_;
 
-  // The origin of the field of the current session (cf.
-  // `last_focused_field_id_`). This is determines which fields are safe to be
-  // filled in cross-frame forms.
-  url::Origin triggered_origin_;
   base::WeakPtr<AndroidAutofillManager> manager_;
   bool check_submission_ = false;
   // Valid only if check_submission_ is true.
diff --git a/components/android_autofill/browser/android_autofill_provider_test_api.h b/components/android_autofill/browser/android_autofill_provider_test_api.h
index 0310a41..71f8d2c 100644
--- a/components/android_autofill/browser/android_autofill_provider_test_api.h
+++ b/components/android_autofill/browser/android_autofill_provider_test_api.h
@@ -16,7 +16,7 @@
 
   const FormDataAndroid* form() && { return provider_->form_.get(); }
   const FieldGlobalId last_focused_field_id() && {
-    return provider_->last_focused_field_id_;
+    return provider_->current_field_.id;
   }
 
  private:
diff --git a/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillProvider.java b/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillProvider.java
index 4ec60044e3..0952d37 100644
--- a/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillProvider.java
+++ b/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillProvider.java
@@ -160,14 +160,16 @@
         // We should have one of them available here, we start with AutofillRequest as it should be
         // available only if we started a session.
         FormData form;
+        short focusFieldIndex = -1;
         if (mRequest != null) {
             form = mRequest.getForm();
+            focusFieldIndex = mRequest.getFocusField().fieldIndex;
             mAutofillUMA.onVirtualStructureProvided();
         } else {
             form = mPrefillRequest.getForm();
             mStructureProvidedForPrefillRequest = true;
         }
-        form.fillViewStructure(structure);
+        form.fillViewStructure(structure, focusFieldIndex);
         if (AutofillManagerWrapper.isLoggable()) {
             AutofillManagerWrapper.log(
                     "onProvideAutoFillVirtualStructure fields:" + structure.getChildCount());
diff --git a/components/android_autofill/browser/java/src/org/chromium/components/autofill/FormData.java b/components/android_autofill/browser/java/src/org/chromium/components/autofill/FormData.java
index c42d836..76584c5dd 100644
--- a/components/android_autofill/browser/java/src/org/chromium/components/autofill/FormData.java
+++ b/components/android_autofill/browser/java/src/org/chromium/components/autofill/FormData.java
@@ -54,8 +54,9 @@
      * Translates the current form into a ViewStructure processed by Android's Autofill framework.
      *
      * @param structure out parameter, the structure passed to the framework.
+     * @param focusFieldIndex the index of the field that is currently focused. -1 if unknown.
      */
-    public void fillViewStructure(ViewStructure structure) {
+    public void fillViewStructure(ViewStructure structure, short focusFieldIndex) {
         structure.setWebDomain(mHost);
         structure.setHtmlInfo(
                 structure.newHtmlInfoBuilder("form").addAttribute("name", mName).build());
@@ -63,6 +64,9 @@
         short fieldIndex = 0;
         for (FormFieldData field : mFields) {
             ViewStructure child = structure.newChild(index++);
+            if (focusFieldIndex == fieldIndex) {
+                child.setFocused(true);
+            }
             int virtualId = toFieldVirtualId(mSessionId, fieldIndex++);
             child.setAutofillId(structure.getAutofillId(), virtualId);
             field.setAutofillId(child.getAutofillId());
diff --git a/components/android_autofill/browser/junit/src/org/chromium/components/autofill/AutofillRequestTest.java b/components/android_autofill/browser/junit/src/org/chromium/components/autofill/AutofillRequestTest.java
index 87a65f6..c349f7f2 100644
--- a/components/android_autofill/browser/junit/src/org/chromium/components/autofill/AutofillRequestTest.java
+++ b/components/android_autofill/browser/junit/src/org/chromium/components/autofill/AutofillRequestTest.java
@@ -74,7 +74,7 @@
 
     private static TestViewStructure fillStructureForRequest(AutofillRequest request) {
         TestViewStructure structure = new TestViewStructure();
-        request.getForm().fillViewStructure(structure);
+        request.getForm().fillViewStructure(structure, (short) -1);
         return structure;
     }
 
@@ -321,4 +321,14 @@
 
         assertFalse(request.autofill(valuesToFill));
     }
+
+    @Test
+    public void testFocusedField() {
+        AutofillRequest request = createSampleRequest();
+        TestViewStructure structure = new TestViewStructure();
+        request.getForm().fillViewStructure(structure, /* focusedIndex= */ (short) 1);
+
+        assertFalse(structure.getChild(0).getFocused());
+        assertTrue(structure.getChild(1).getFocused());
+    }
 }
diff --git a/components/android_autofill/browser/test_support/java/src/org/chromium/components/autofill/TestViewStructure.java b/components/android_autofill/browser/test_support/java/src/org/chromium/components/autofill/TestViewStructure.java
index 1ef9d380..ad28768 100644
--- a/components/android_autofill/browser/test_support/java/src/org/chromium/components/autofill/TestViewStructure.java
+++ b/components/android_autofill/browser/test_support/java/src/org/chromium/components/autofill/TestViewStructure.java
@@ -283,7 +283,13 @@
     public void setFocusable(boolean state) {}
 
     @Override
-    public void setFocused(boolean state) {}
+    public void setFocused(boolean state) {
+        mFocused = state;
+    }
+
+    public boolean getFocused() {
+        return mFocused;
+    }
 
     @Override
     public void setClassName(String className) {
@@ -369,6 +375,7 @@
     private CharSequence mHint;
     private String[] mAutofillHints;
     private int mId;
+    private boolean mFocused;
     private String mClassName;
     private String mWebDomain;
     private int mChildCount;
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc
index 6e074ed..5fad265a3 100644
--- a/components/autofill/content/renderer/autofill_agent.cc
+++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -113,7 +113,7 @@
   // across all use cases of JavaScript formatting a value (e.g. for
   // normalizing single-byte and double-byte encoding of digits in Japan, an
   // NKFC normalization may be appropriate).
-  // TODO(b/40947225): Internationalize this normalization.
+  // TODO(crbug.com/40947225): Internationalize this normalization.
   return old_value == new_value;
 }
 
@@ -955,13 +955,13 @@
     return;
   }
   // `password_generation_agent_` can be null in WebView.
-  // TODO(b/326213028): Clear fields previewed by `PasswordGenerationAgent`
-  // directly using `PasswordGenerationAgent`.
+  // TODO(crbug.com/326213028): Clear fields previewed by
+  // `PasswordGenerationAgent` directly using `PasswordGenerationAgent`.
   if (password_generation_agent_) {
     password_generation_agent_->ClearPreviewedForm();
   }
-  // TODO(b/326213028): Clear fields previewed by `PasswordAutofillAgent`
-  // directly using `PasswordAutofillAgent`.
+  // TODO(crbug.com/326213028): Clear fields previewed by
+  // `PasswordAutofillAgent` directly using `PasswordAutofillAgent`.
   password_autofill_agent_->ClearPreviewedForm();
 
   std::vector<std::pair<WebFormControlElement, WebAutofillState>>
@@ -1215,7 +1215,7 @@
   last_queried_element_ = FieldRef(element);
 
   // Manual fallbacks override any prioritization done based on the field type.
-  // TODO(b/333990908): Test manual fallback on different form types.
+  // TODO(crbug.com/333990908): Test manual fallback on different form types.
   if (IsAddressAutofillManuallyTriggered(trigger_source) ||
       IsPaymentsAutofillManuallyTriggered(trigger_source) ||
       IsPlusAddressesManuallyTriggered(trigger_source)) {
@@ -1763,12 +1763,12 @@
       // afterwards and we don't want to fire the same event twice.
       if (base::FeatureList::IsEnabled(
               features::kAutofillUnifyAndFixFormTracking)) {
-        // TODO(b/40281981): Figure out if this is still needed, and document
-        // the reason, otherwise remove.
+        // TODO(crbug.com/40281981): Figure out if this is still needed, and
+        // document the reason, otherwise remove.
         password_autofill_agent_->InformBrowserAboutUserInput(
             form_element, WebInputElement());
-        // TODO(b/40281981): Figure out if this is still needed, and document
-        // the reason, otherwise remove.
+        // TODO(crbug.com/40281981): Figure out if this is still needed, and
+        // document the reason, otherwise remove.
         update_submission_data_on_user_edit();
       }
       if (std::optional<FormData> form_data = form_util::ExtractFormData(
diff --git a/components/autofill/content/renderer/autofill_agent.h b/components/autofill/content/renderer/autofill_agent.h
index 8e457de..972128904 100644
--- a/components/autofill/content/renderer/autofill_agent.h
+++ b/components/autofill/content/renderer/autofill_agent.h
@@ -453,7 +453,7 @@
                : last_interacted_form_;
   }
 
-  // TODO(b/40281981): Remove.
+  // TODO(crbug.com/40281981): Remove.
   std::optional<FormData>& provisionally_saved_form() {
     return form_tracker_->provisionally_saved_form();
   }
@@ -484,7 +484,7 @@
   std::vector<std::pair<FieldRef, blink::WebAutofillState>> previewed_elements_;
 
   // Last form which was interacted with by the user.
-  // TODO(b/40281981): Remove when tracking becomes only FormTracker's
+  // TODO(crbug.com/40281981): Remove when tracking becomes only FormTracker's
   // responsibility.
   FormRef last_interacted_form_;
 
diff --git a/components/autofill/content/renderer/form_tracker.cc b/components/autofill/content/renderer/form_tracker.cc
index 38c2018f..f258ec2 100644
--- a/components/autofill/content/renderer/form_tracker.cc
+++ b/components/autofill/content/renderer/form_tracker.cc
@@ -339,8 +339,8 @@
   }
   if (base::FeatureList::IsEnabled(
           features::kAutofillUnifyAndFixFormTracking)) {
-    // TODO(b/40281981): Figure out if this is still needed, and document
-    // the reason, otherwise remove.
+    // TODO(crbug.com/40281981): Figure out if this is still needed, and
+    // document the reason, otherwise remove.
     ResetLastInteractedElements();
   }
 }
diff --git a/components/autofill/content/renderer/form_tracker.h b/components/autofill/content/renderer/form_tracker.h
index 97d8dd091..6457999 100644
--- a/components/autofill/content/renderer/form_tracker.h
+++ b/components/autofill/content/renderer/form_tracker.h
@@ -75,7 +75,7 @@
    public:
     enum class SaveFormReason {
       kTextFieldChanged,
-      // TODO(b/40281981): Remove after launching the feature
+      // TODO(crbug.com/40281981): Remove after launching the feature
       // kAutofillUnifyAndFixFormTracking.
       kWillSendSubmitEvent,
       kSelectChanged,
@@ -142,7 +142,7 @@
 
   FormRef last_interacted_form() const { return last_interacted_.form; }
 
-  // TODO(b/40281981): Remove.
+  // TODO(crbug.com/40281981): Remove.
   std::optional<FormData>& provisionally_saved_form() {
     return last_interacted_.saved_state;
   }
diff --git a/components/autofill/content/renderer/password_autofill_agent.h b/components/autofill/content/renderer/password_autofill_agent.h
index 5f955570..cb81415 100644
--- a/components/autofill/content/renderer/password_autofill_agent.h
+++ b/components/autofill/content/renderer/password_autofill_agent.h
@@ -105,7 +105,7 @@
 class PasswordGenerationAgent;
 
 // This class is responsible for filling password forms.
-// TODO(b/40281981): Remove FormTracker::Observer after launching
+// TODO(crbug.com/40281981): Remove FormTracker::Observer after launching
 // kAutofillUnifyAndFixFormTracking.
 class PasswordAutofillAgent : public content::RenderFrameObserver,
                               public FormTracker::Observer,
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index 024fdc8..ab2cf9c 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -840,7 +840,6 @@
   sources = [
     "address_data_cleaner_test_api.h",
     "address_data_manager_test_api.h",
-    "address_suggestion_generator_test_api.h",
     "autofill_form_test_utils.cc",
     "autofill_form_test_utils.h",
     "autofill_manager_test_api.h",
@@ -925,7 +924,6 @@
     "payments/test_virtual_card_enrollment_manager.h",
     "payments_data_manager_test_api.cc",
     "payments_data_manager_test_api.h",
-    "payments_suggestion_generator_test_api.h",
     "personal_data_manager_test_utils.cc",
     "personal_data_manager_test_utils.h",
     "profile_token_quality_test_api.cc",
diff --git a/components/autofill/core/browser/address_data_cleaner.cc b/components/autofill/core/browser/address_data_cleaner.cc
index b4d7ea9..2ee815c 100644
--- a/components/autofill/core/browser/address_data_cleaner.cc
+++ b/components/autofill/core/browser/address_data_cleaner.cc
@@ -178,7 +178,7 @@
   // To simplify the rollout of AutofillSilentlyRemoveQuasiDuplicates, this
   // condition is relaxed to twice per milestone (but still limited to at most
   // once per startup).
-  // TODO(b/325450676): Revert to once per milestone after the rollout.
+  // TODO(crbug.com/325450676): Revert to once per milestone after the rollout.
   if (pref_service_->GetInteger(prefs::kAutofillLastVersionDeduped) <
       CHROME_VERSION_MAJOR) {
     pref_service_->SetInteger(prefs::kAutofillLastVersionDeduped,
diff --git a/components/autofill/core/browser/address_suggestion_generator.cc b/components/autofill/core/browser/address_suggestion_generator.cc
index c0d3147..42d940a8 100644
--- a/components/autofill/core/browser/address_suggestion_generator.cc
+++ b/components/autofill/core/browser/address_suggestion_generator.cc
@@ -73,7 +73,8 @@
 #if BUILDFLAG(IS_IOS)
   std::u16string value =
       l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM);
-  // TODO(b/40266549): iOS still uses Clear Form logic, replace with Undo.
+  // TODO(crbug.com/40266549): iOS still uses Clear Form logic, replace with
+  // Undo.
   Suggestion suggestion(value, SuggestionType::kUndoOrClear);
   suggestion.icon = Suggestion::Icon::kClear;
 #else
@@ -84,7 +85,7 @@
   Suggestion suggestion(value, SuggestionType::kUndoOrClear);
   suggestion.icon = Suggestion::Icon::kUndo;
 #endif
-  // TODO(b/40266549): update "Clear Form" a11y announcement to "Undo"
+  // TODO(crbug.com/40266549): update "Clear Form" a11y announcement to "Undo"
   suggestion.acceptance_a11y_announcement =
       l10n_util::GetStringUTF16(IDS_AUTOFILL_A11Y_ANNOUNCE_CLEARED_FORM);
   return suggestion;
@@ -982,78 +983,11 @@
   if (is_autofilled) {
     footer_suggestions.push_back(CreateUndoOrClearFormSuggestion());
   }
-  footer_suggestions.push_back(
-      AddressSuggestionGenerator::CreateManageAddressesEntry());
+  footer_suggestions.push_back(CreateManageAddressesSuggestion());
   return footer_suggestions;
 }
 
-}  // namespace
-
-AddressSuggestionGenerator::AddressSuggestionGenerator() = default;
-
-AddressSuggestionGenerator::~AddressSuggestionGenerator() = default;
-
-std::vector<Suggestion> AddressSuggestionGenerator::GetSuggestionsForProfiles(
-    const AutofillClient& client,
-    const FieldTypeSet& field_types,
-    const FormFieldData& trigger_field,
-    FieldType trigger_field_type,
-    SuggestionType suggestion_type,
-    AutofillSuggestionTriggerSource trigger_source) {
-  std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-      profiles_to_suggest = GetProfilesToSuggest(
-          client.GetPersonalDataManager()->address_data_manager(),
-          trigger_field_type, trigger_field.value(),
-          trigger_field.is_autofilled(), field_types,
-          GetProfilesToSuggestOptions(trigger_field_type, trigger_field.value(),
-                                      trigger_field.is_autofilled(),
-                                      trigger_source));
-  // If autofill for addresses is triggered from the context menu on an address
-  // field and no suggestions can be shown (i.e. if a user has only addresses
-  // without emails and then triggers autofill from the context menu on an email
-  // field), then default to the same behaviour as if the user triggers autofill
-  // on a non-address field. This is done to avoid a situation when the user
-  // would trigger autofill from the context menu, and then no suggestions
-  // appear.
-  // The "if condition" is satisfied only if `trigger_field_type` is an address
-  // field. Then, `GetSuggestionsForProfiles()` is called with `UNKOWN_TYPE` for
-  // the `trigger_field_type`. This guarantees no infinite recursion occurs.
-  if (profiles_to_suggest.empty() && IsAddressType(trigger_field_type) &&
-      trigger_source ==
-          AutofillSuggestionTriggerSource::kManualFallbackAddress &&
-      base::FeatureList::IsEnabled(
-          features::kAutofillForUnclassifiedFieldsAvailable)) {
-    return GetSuggestionsForProfiles(client, {UNKNOWN_TYPE}, trigger_field,
-                                     UNKNOWN_TYPE, suggestion_type,
-                                     trigger_source);
-  }
-  std::vector<Suggestion> suggestions = CreateSuggestionsFromProfiles(
-      profiles_to_suggest, field_types, suggestion_type, trigger_field_type,
-      trigger_field.max_length(), client.IsOffTheRecord(),
-      client.GetPersonalDataManager()->address_data_manager().app_locale());
-
-  // Add devtools test addresses suggestion if it exists. A suggestion will
-  // exist if devtools is open and therefore test addresses were set.
-  if (IsAddressType(trigger_field_type)) {
-    if (std::optional<Suggestion> test_addresses_suggestion =
-            GetSuggestionForTestAddresses(client.GetTestAddresses(),
-                                          client.GetPersonalDataManager()
-                                              ->address_data_manager()
-                                              .app_locale())) {
-      suggestions.insert(suggestions.begin(),
-                         std::move(*test_addresses_suggestion));
-    }
-  }
-  if (suggestions.empty()) {
-    return suggestions;
-  }
-  base::ranges::move(GetAddressFooterSuggestions(trigger_field.is_autofilled()),
-                     std::back_inserter(suggestions));
-  return suggestions;
-}
-
-AddressSuggestionGenerator::ProfilesToSuggestOptions
-AddressSuggestionGenerator::GetProfilesToSuggestOptions(
+ProfilesToSuggestOptions GetProfilesToSuggestOptions(
     FieldType trigger_field_type,
     const std::u16string& trigger_field_contents,
     bool trigger_field_is_autofilled,
@@ -1101,14 +1035,19 @@
       .deduplicate_suggestions = should_deduplicate_suggestions};
 }
 
+// Returns a list of profiles that will be displayed as suggestions to the user,
+// sorted by their relevance. This involves many steps from fetching the
+// profiles to matching with `field_contents`, and deduplicating based on
+// `field_types`, which are the relevant types for the current suggestion.
+// `options` defines what strategies to follow by the function in order to
+// filter the list or returned profiles.
 std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-AddressSuggestionGenerator::GetProfilesToSuggest(
-    const AddressDataManager& address_data,
-    FieldType trigger_field_type,
-    const std::u16string& field_contents,
-    bool field_is_autofilled,
-    const FieldTypeSet& field_types,
-    ProfilesToSuggestOptions options) {
+GetProfilesToSuggest(const AddressDataManager& address_data,
+                     FieldType trigger_field_type,
+                     const std::u16string& field_contents,
+                     bool field_is_autofilled,
+                     const FieldTypeSet& field_types,
+                     ProfilesToSuggestOptions options) {
   // Get the profiles to suggest, which are already sorted.
   std::vector<const AutofillProfile*> sorted_profiles =
       address_data.GetProfilesToSuggest();
@@ -1146,8 +1085,12 @@
   return profiles_to_suggest;
 }
 
-std::vector<Suggestion>
-AddressSuggestionGenerator::CreateSuggestionsFromProfiles(
+// Returns a list of Suggestion objects, each representing an element in
+// `profiles`.
+// `field_types` holds the type of fields relevant for the current suggestion.
+// The profiles passed to this function should already have been matched on
+// `trigger_field_contents_canon` and deduplicated.
+std::vector<Suggestion> CreateSuggestionsFromProfiles(
     const std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>&
         profiles,
     const FieldTypeSet& field_types,
@@ -1167,9 +1110,9 @@
           profiles, field_types, suggestion_type, trigger_field_type,
           app_locale);
   // This will be used to check if suggestions should be supported with icons.
-  // TODO(b/40285811): Consider simplifying this to be any address field. This
-  // will allow to add icons for every full form filling and manual fallback
-  // case.
+  // TODO(crbug.com/40285811): Consider simplifying this to be any address
+  // field. This will allow to add icons for every full form filling and manual
+  // fallback case.
   const bool contains_profile_related_fields =
       base::ranges::count_if(field_types, [](FieldType field_type) {
         FieldTypeGroup field_type_group = GroupTypeOfFieldType(field_type);
@@ -1258,12 +1201,71 @@
                                                 is_off_the_record, app_locale);
     }
   }
-
   return suggestions;
 }
 
-// static
-Suggestion AddressSuggestionGenerator::CreateManageAddressesEntry() {
+}  // namespace
+
+std::vector<Suggestion> GetSuggestionsForProfiles(
+    const AutofillClient& client,
+    const FieldTypeSet& field_types,
+    const FormFieldData& trigger_field,
+    FieldType trigger_field_type,
+    SuggestionType suggestion_type,
+    AutofillSuggestionTriggerSource trigger_source) {
+  std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
+      profiles_to_suggest = GetProfilesToSuggest(
+          client.GetPersonalDataManager()->address_data_manager(),
+          trigger_field_type, trigger_field.value(),
+          trigger_field.is_autofilled(), field_types,
+          GetProfilesToSuggestOptions(trigger_field_type, trigger_field.value(),
+                                      trigger_field.is_autofilled(),
+                                      trigger_source));
+  // If autofill for addresses is triggered from the context menu on an address
+  // field and no suggestions can be shown (i.e. if a user has only addresses
+  // without emails and then triggers autofill from the context menu on an email
+  // field), then default to the same behaviour as if the user triggers autofill
+  // on a non-address field. This is done to avoid a situation when the user
+  // would trigger autofill from the context menu, and then no suggestions
+  // appear.
+  // The "if condition" is satisfied only if `trigger_field_type` is an address
+  // field. Then, `GetSuggestionsForProfiles()` is called with `UNKOWN_TYPE` for
+  // the `trigger_field_type`. This guarantees no infinite recursion occurs.
+  if (profiles_to_suggest.empty() && IsAddressType(trigger_field_type) &&
+      trigger_source ==
+          AutofillSuggestionTriggerSource::kManualFallbackAddress &&
+      base::FeatureList::IsEnabled(
+          features::kAutofillForUnclassifiedFieldsAvailable)) {
+    return GetSuggestionsForProfiles(client, {UNKNOWN_TYPE}, trigger_field,
+                                     UNKNOWN_TYPE, suggestion_type,
+                                     trigger_source);
+  }
+  std::vector<Suggestion> suggestions = CreateSuggestionsFromProfiles(
+      profiles_to_suggest, field_types, suggestion_type, trigger_field_type,
+      trigger_field.max_length(), client.IsOffTheRecord(),
+      client.GetPersonalDataManager()->address_data_manager().app_locale());
+
+  // Add devtools test addresses suggestion if it exists. A suggestion will
+  // exist if devtools is open and therefore test addresses were set.
+  if (IsAddressType(trigger_field_type)) {
+    if (std::optional<Suggestion> test_addresses_suggestion =
+            GetSuggestionForTestAddresses(client.GetTestAddresses(),
+                                          client.GetPersonalDataManager()
+                                              ->address_data_manager()
+                                              .app_locale())) {
+      suggestions.insert(suggestions.begin(),
+                         std::move(*test_addresses_suggestion));
+    }
+  }
+  if (suggestions.empty()) {
+    return suggestions;
+  }
+  base::ranges::move(GetAddressFooterSuggestions(trigger_field.is_autofilled()),
+                     std::back_inserter(suggestions));
+  return suggestions;
+}
+
+Suggestion CreateManageAddressesSuggestion() {
   Suggestion suggestion(
       l10n_util::GetStringUTF16(IDS_AUTOFILL_MANAGE_ADDRESSES),
       SuggestionType::kManageAddress);
@@ -1271,4 +1273,32 @@
   return suggestion;
 }
 
+std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
+GetProfilesToSuggestForTest(const AddressDataManager& address_data,
+                            FieldType trigger_field_type,
+                            const std::u16string& field_contents,
+                            bool field_is_autofilled,
+                            const FieldTypeSet& field_types,
+                            AutofillSuggestionTriggerSource trigger_source) {
+  return GetProfilesToSuggest(
+      address_data, trigger_field_type, field_contents, field_is_autofilled,
+      field_types,
+      GetProfilesToSuggestOptions(trigger_field_type, field_contents,
+                                  field_is_autofilled, trigger_source));
+}
+
+std::vector<Suggestion> CreateSuggestionsFromProfilesForTest(
+    const std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>&
+        profiles,
+    const FieldTypeSet& field_types,
+    SuggestionType suggestion_type,
+    FieldType trigger_field_type,
+    uint64_t trigger_field_max_length,
+    bool is_off_the_record,
+    const std::string& app_locale) {
+  return CreateSuggestionsFromProfiles(
+      profiles, field_types, suggestion_type, trigger_field_type,
+      trigger_field_max_length, is_off_the_record, app_locale);
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/browser/address_suggestion_generator.h b/components/autofill/core/browser/address_suggestion_generator.h
index 9099bde2..c61b3390 100644
--- a/components/autofill/core/browser/address_suggestion_generator.h
+++ b/components/autofill/core/browser/address_suggestion_generator.h
@@ -25,78 +25,51 @@
 class AutofillClient;
 class FormFieldData;
 
-// Helper class to generate Autofill suggestions, such as for credit card and
-// address profile Autofill.
-class AddressSuggestionGenerator {
- public:
-  AddressSuggestionGenerator();
-  ~AddressSuggestionGenerator();
-  AddressSuggestionGenerator(const AddressSuggestionGenerator&) = delete;
-  AddressSuggestionGenerator& operator=(const AddressSuggestionGenerator&) =
-      delete;
-
-  // Generates suggestions for a form containing the given `field_types`. It
-  // considers all available profiles, deduplicates them based on the types and
-  // returns one suggestion per remaining profile.
-  // `field_types` are the relevant types for the current suggestions.
-  std::vector<Suggestion> GetSuggestionsForProfiles(
-      const AutofillClient& client,
-      const FieldTypeSet& field_types,
-      const FormFieldData& trigger_field,
-      FieldType trigger_field_type,
-      SuggestionType suggestion_type,
-      AutofillSuggestionTriggerSource trigger_source);
-
-  // Generates a footer suggestion "Manage addresses..." menu item which will
-  // redirect to Chrome address settings page.
-  static Suggestion CreateManageAddressesEntry();
-
- private:
-  friend class AddressSuggestionGeneratorTestApi;
-
-  struct ProfilesToSuggestOptions {
-    const bool exclude_disused_addresses;
-    const bool require_non_empty_value_on_trigger_field;
-    const bool prefix_match_suggestions;
-    const bool deduplicate_suggestions;
-  };
-
-  ProfilesToSuggestOptions GetProfilesToSuggestOptions(
-      FieldType trigger_field_type,
-      const std::u16string& trigger_field_contents,
-      bool trigger_field_is_autofilled,
-      AutofillSuggestionTriggerSource trigger_source);
-
-  // Returns a list of profiles that will be displayed as suggestions to the
-  // user, sorted by their relevance. This involves many steps from fetching the
-  // profiles to matching with `field_contents`, and deduplicating based on
-  // `field_types`, which are the relevant types for the current suggestion.
-  // `options` defines what strategies to follow by the function in order to
-  // filter the list or returned profiles.
-  std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-  GetProfilesToSuggest(const AddressDataManager& address_data,
-                       FieldType trigger_field_type,
-                       const std::u16string& field_contents,
-                       bool field_is_autofilled,
-                       const FieldTypeSet& field_types,
-                       ProfilesToSuggestOptions options);
-
-  // Returns a list of Suggestion objects, each representing an element in
-  // `profiles`.
-  // `field_types` holds the type of fields relevant for the current suggestion.
-  // The profiles passed to this function should already have been matched on
-  // `trigger_field_contents_canon` and deduplicated.
-  std::vector<Suggestion> CreateSuggestionsFromProfiles(
-      const std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>&
-          profiles,
-      const FieldTypeSet& field_types,
-      SuggestionType suggestion_type,
-      FieldType trigger_field_type,
-      uint64_t trigger_field_max_length,
-      bool is_off_the_record,
-      const std::string& app_locale);
+struct ProfilesToSuggestOptions {
+  const bool exclude_disused_addresses = true;
+  const bool require_non_empty_value_on_trigger_field = true;
+  const bool prefix_match_suggestions = true;
+  const bool deduplicate_suggestions = true;
 };
 
+// Generates suggestions for a form containing the given `field_types`. It
+// considers all available profiles, deduplicates them based on the types and
+// returns one suggestion per remaining profile.
+// `field_types` are the relevant types for the current suggestions.
+std::vector<Suggestion> GetSuggestionsForProfiles(
+    const AutofillClient& client,
+    const FieldTypeSet& field_types,
+    const FormFieldData& trigger_field,
+    FieldType trigger_field_type,
+    SuggestionType suggestion_type,
+    AutofillSuggestionTriggerSource trigger_source);
+
+// Generates a footer suggestion "Manage addresses..." menu item which will
+// redirect to Chrome address settings page.
+Suggestion CreateManageAddressesSuggestion();
+
+// Exposes `GetProfilesToSuggest` in tests.
+std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
+GetProfilesToSuggestForTest(
+    const AddressDataManager& address_data,
+    FieldType trigger_field_type,
+    const std::u16string& field_contents,
+    bool field_is_autofilled,
+    const FieldTypeSet& field_types,
+    AutofillSuggestionTriggerSource trigger_source =
+        AutofillSuggestionTriggerSource::kFormControlElementClicked);
+
+// Exposes `CreateSuggestionsFromProfiles` in tests.
+std::vector<Suggestion> CreateSuggestionsFromProfilesForTest(
+    const std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>&
+        profiles,
+    const FieldTypeSet& field_types,
+    SuggestionType suggestion_type,
+    FieldType trigger_field_type,
+    uint64_t trigger_field_max_length,
+    bool is_off_the_record = false,
+    const std::string& app_locale = "en-US");
+
 }  // namespace autofill
 
 #endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_SUGGESTION_GENERATOR_H_
diff --git a/components/autofill/core/browser/address_suggestion_generator_test_api.h b/components/autofill/core/browser/address_suggestion_generator_test_api.h
deleted file mode 100644
index b3d72f85..0000000
--- a/components/autofill/core/browser/address_suggestion_generator_test_api.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2024 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_SUGGESTION_GENERATOR_TEST_API_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_SUGGESTION_GENERATOR_TEST_API_H_
-
-#include "components/autofill/core/browser/address_suggestion_generator.h"
-#include "components/autofill/core/browser/field_types.h"
-#include "components/autofill/core/browser/metrics/payments/card_metadata_metrics.h"
-#include "components/autofill/core/common/aliases.h"
-#include "components/autofill/core/common/form_field_data.h"
-
-namespace autofill {
-
-// Exposes some testing operations for BrowserAutofillManager.
-class AddressSuggestionGeneratorTestApi {
- public:
-  explicit AddressSuggestionGeneratorTestApi(
-      AddressSuggestionGenerator& suggestion_generator)
-      : suggestion_generator_(suggestion_generator) {}
-
-  std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-  GetProfilesToSuggest(
-      const AddressDataManager& address_data,
-      FieldType trigger_field_type,
-      const std::u16string& field_contents,
-      bool field_is_autofilled,
-      const FieldTypeSet& field_types,
-      AutofillSuggestionTriggerSource trigger_source =
-          AutofillSuggestionTriggerSource::kFormControlElementClicked) {
-    return suggestion_generator_->GetProfilesToSuggest(
-        address_data, trigger_field_type, field_contents, field_is_autofilled,
-        field_types,
-        suggestion_generator_->GetProfilesToSuggestOptions(
-            trigger_field_type, field_contents, field_is_autofilled,
-            trigger_source));
-  }
-
-  std::vector<Suggestion> CreateSuggestionsFromProfiles(
-      const std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>&
-          profiles,
-      const FieldTypeSet& field_types,
-      SuggestionType suggestion_type,
-      FieldType trigger_field_type,
-      uint64_t trigger_field_max_length,
-      bool is_off_the_record = false,
-      const std::string& app_locale = "en-US") {
-    return suggestion_generator_->CreateSuggestionsFromProfiles(
-        profiles, field_types, suggestion_type, trigger_field_type,
-        trigger_field_max_length, is_off_the_record, app_locale);
-  }
-
- private:
-  raw_ref<AddressSuggestionGenerator> suggestion_generator_;
-};
-
-inline AddressSuggestionGeneratorTestApi test_api(
-    AddressSuggestionGenerator& suggestion_generator) {
-  return AddressSuggestionGeneratorTestApi(suggestion_generator);
-}
-
-}  // namespace autofill
-
-#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_SUGGESTION_GENERATOR_TEST_API_H_
diff --git a/components/autofill/core/browser/address_suggestion_generator_unittest.cc b/components/autofill/core/browser/address_suggestion_generator_unittest.cc
index e7f40a6..0c1b18eb 100644
--- a/components/autofill/core/browser/address_suggestion_generator_unittest.cc
+++ b/components/autofill/core/browser/address_suggestion_generator_unittest.cc
@@ -15,7 +15,6 @@
 #include "base/time/time.h"
 #include "base/uuid.h"
 #include "components/autofill/core/browser/address_data_manager.h"
-#include "components/autofill/core/browser/address_suggestion_generator_test_api.h"
 #include "components/autofill/core/browser/autofill_granular_filling_utils.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/data_model/autofill_profile.h"
@@ -126,11 +125,6 @@
     autofill_client_.SetPrefs(test::PrefServiceForTesting());
     address_data().SetPrefService(autofill_client_.GetPrefs());
     address_data().SetSyncServiceForTest(&sync_service_);
-    suggestion_generator_ = std::make_unique<AddressSuggestionGenerator>();
-  }
-
-  AddressSuggestionGenerator& suggestion_generator() {
-    return *suggestion_generator_.get();
   }
 
   TestAddressDataManager& address_data() {
@@ -148,7 +142,6 @@
   test::AutofillUnitTestEnvironment autofill_test_environment_;
   TestAutofillClient autofill_client_;
   syncer::TestSyncService sync_service_;
-  std::unique_ptr<AddressSuggestionGenerator> suggestion_generator_;
 };
 
 // Tests that special characters will be used while prefix matching the user's
@@ -164,9 +157,8 @@
   ASSERT_EQ(address_data().GetProfilesToSuggest().size(), 2u);
 
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>> profiles =
-      test_api(suggestion_generator())
-          .GetProfilesToSuggest(address_data(), EMAIL_ADDRESS, u"Test@", false,
-                                {});
+      GetProfilesToSuggestForTest(address_data(), EMAIL_ADDRESS, u"Test@",
+                                  false, {});
 
   ASSERT_EQ(profiles.size(), 1u);
   EXPECT_EQ(*profiles[0], profile_1);
@@ -204,9 +196,8 @@
   // Simulate a form with street address, city and state.
   FieldTypeSet types = {ADDRESS_HOME_CITY, ADDRESS_HOME_STATE};
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>> profiles =
-      test_api(suggestion_generator())
-          .GetProfilesToSuggest(address_data(), ADDRESS_HOME_STREET_ADDRESS,
-                                u"123", false, types);
+      GetProfilesToSuggestForTest(address_data(), ADDRESS_HOME_STREET_ADDRESS,
+                                  u"123", false, types);
   ASSERT_EQ(2U, profiles.size());
   EXPECT_EQ(profiles[0]->GetRawInfo(ADDRESS_HOME_STATE), u"CA");
   EXPECT_EQ(profiles[1]->GetRawInfo(ADDRESS_HOME_STATE), u"TX");
@@ -227,9 +218,8 @@
   }
 
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-      suggested_profiles = test_api(suggestion_generator())
-                               .GetProfilesToSuggest(address_data(), NAME_FIRST,
-                                                     u"Ma", false, {});
+      suggested_profiles = GetProfilesToSuggestForTest(
+          address_data(), NAME_FIRST, u"Ma", false, {});
 
   ASSERT_EQ(2 * kMaxDeduplicatedProfilesForSuggestion,
             address_data().GetProfiles().size());
@@ -269,9 +259,8 @@
   address_data().AddProfile(profile);
 
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-      suggested_profiles = test_api(suggestion_generator())
-                               .GetProfilesToSuggest(address_data(), NAME_FIRST,
-                                                     u"Ma", false, {});
+      suggested_profiles = GetProfilesToSuggestForTest(
+          address_data(), NAME_FIRST, u"Ma", false, {});
 
   ASSERT_EQ(kMaxPrefixMatchedProfilesForSuggestion + 1,
             address_data().GetProfiles().size());
@@ -313,9 +302,8 @@
   address_data().AddProfile(profile2);
 
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-      suggested_profiles = test_api(suggestion_generator())
-                               .GetProfilesToSuggest(address_data(), NAME_FIRST,
-                                                     u"Ma", false, {});
+      suggested_profiles = GetProfilesToSuggestForTest(
+          address_data(), NAME_FIRST, u"Ma", false, {});
   ASSERT_EQ(3U, suggested_profiles.size());
   EXPECT_EQ(suggested_profiles[0]->GetRawInfo(NAME_FIRST), u"Marion1");
   EXPECT_EQ(suggested_profiles[1]->GetRawInfo(NAME_FIRST), u"Marion2");
@@ -349,10 +337,8 @@
 
   // Verify that all the profiles are suggested.
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-      suggested_profiles =
-          test_api(suggestion_generator())
-              .GetProfilesToSuggest(address_data(), NAME_FIRST,
-                                    std::u16string(), false, {});
+      suggested_profiles = GetProfilesToSuggestForTest(
+          address_data(), NAME_FIRST, std::u16string(), false, {});
   EXPECT_EQ(3U, suggested_profiles.size());
 }
 
@@ -372,40 +358,31 @@
 
   {
     std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-        suggested_profiles =
-            test_api(suggestion_generator())
-                .GetProfilesToSuggest(address_data(), NAME_FULL,
-                                      std::u16string(), false,
-                                      {NAME_FULL, PHONE_HOME_WHOLE_NUMBER});
+        suggested_profiles = GetProfilesToSuggestForTest(
+            address_data(), NAME_FULL, std::u16string(), false,
+            {NAME_FULL, PHONE_HOME_WHOLE_NUMBER});
     EXPECT_EQ(2U, suggested_profiles.size());
   }
   {
     std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-        suggested_profiles =
-            test_api(suggestion_generator())
-                .GetProfilesToSuggest(address_data(), NAME_FULL,
-                                      std::u16string(), false,
-                                      {NAME_FULL, PHONE_HOME_COUNTRY_CODE,
-                                       PHONE_HOME_CITY_AND_NUMBER});
+        suggested_profiles = GetProfilesToSuggestForTest(
+            address_data(), NAME_FULL, std::u16string(), false,
+            {NAME_FULL, PHONE_HOME_COUNTRY_CODE, PHONE_HOME_CITY_AND_NUMBER});
     EXPECT_EQ(2U, suggested_profiles.size());
   }
   {
     std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-        suggested_profiles =
-            test_api(suggestion_generator())
-                .GetProfilesToSuggest(
-                    address_data(), NAME_FULL, std::u16string(), false,
-                    {NAME_FULL, PHONE_HOME_COUNTRY_CODE, PHONE_HOME_CITY_CODE,
-                     PHONE_HOME_NUMBER});
+        suggested_profiles = GetProfilesToSuggestForTest(
+            address_data(), NAME_FULL, std::u16string(), false,
+            {NAME_FULL, PHONE_HOME_COUNTRY_CODE, PHONE_HOME_CITY_CODE,
+             PHONE_HOME_NUMBER});
     EXPECT_EQ(2U, suggested_profiles.size());
   }
   {
     std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-        suggested_profiles =
-            test_api(suggestion_generator())
-                .GetProfilesToSuggest(
-                    address_data(), NAME_FULL, std::u16string(), false,
-                    {NAME_FULL, PHONE_HOME_COUNTRY_CODE, PHONE_HOME_CITY_CODE});
+        suggested_profiles = GetProfilesToSuggestForTest(
+            address_data(), NAME_FULL, std::u16string(), false,
+            {NAME_FULL, PHONE_HOME_COUNTRY_CODE, PHONE_HOME_CITY_CODE});
     EXPECT_EQ(1U, suggested_profiles.size());
   }
 }
@@ -434,33 +411,25 @@
   // Query with empty string only returns profile2.
   {
     std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-        suggested_profiles =
-            test_api(suggestion_generator())
-                .GetProfilesToSuggest(address_data(),
-                                      ADDRESS_HOME_STREET_ADDRESS,
-                                      std::u16string(), false, {});
+        suggested_profiles = GetProfilesToSuggestForTest(
+            address_data(), ADDRESS_HOME_STREET_ADDRESS, std::u16string(),
+            false, {});
     EXPECT_EQ(1U, suggested_profiles.size());
   }
 
   // Query with non-alpha-numeric string only returns profile2.
   {
     std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-        suggested_profiles =
-            test_api(suggestion_generator())
-                .GetProfilesToSuggest(address_data(),
-                                      ADDRESS_HOME_STREET_ADDRESS, u"--", false,
-                                      {});
+        suggested_profiles = GetProfilesToSuggestForTest(
+            address_data(), ADDRESS_HOME_STREET_ADDRESS, u"--", false, {});
     EXPECT_EQ(1U, suggested_profiles.size());
   }
 
   // Query with prefix for profile1 returns profile1.
   {
     std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-        suggested_profiles =
-            test_api(suggestion_generator())
-                .GetProfilesToSuggest(address_data(),
-                                      ADDRESS_HOME_STREET_ADDRESS, u"123",
-                                      false, {});
+        suggested_profiles = GetProfilesToSuggestForTest(
+            address_data(), ADDRESS_HOME_STREET_ADDRESS, u"123", false, {});
     ASSERT_EQ(1U, suggested_profiles.size());
     EXPECT_EQ(u"Marion1", suggested_profiles[0]->GetRawInfo(NAME_FIRST));
   }
@@ -468,11 +437,8 @@
   // Query with prefix for profile2 returns profile2.
   {
     std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-        suggested_profiles =
-            test_api(suggestion_generator())
-                .GetProfilesToSuggest(address_data(),
-                                      ADDRESS_HOME_STREET_ADDRESS, u"456",
-                                      false, {});
+        suggested_profiles = GetProfilesToSuggestForTest(
+            address_data(), ADDRESS_HOME_STREET_ADDRESS, u"456", false, {});
     EXPECT_EQ(1U, suggested_profiles.size());
     EXPECT_EQ(u"Marion2", suggested_profiles[0]->GetRawInfo(NAME_FIRST));
   }
@@ -489,9 +455,8 @@
 
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
       profiles_to_suggest =
-          test_api(suggestion_generator())
-              .GetProfilesToSuggest(address_data(), NAME_FIRST, u"",
-                                    /*field_is_autofilled=*/false, {});
+          GetProfilesToSuggestForTest(address_data(), NAME_FIRST, u"",
+                                      /*field_is_autofilled=*/false, {});
 
   ASSERT_EQ(1U, profiles_to_suggest.size());
 }
@@ -516,11 +481,9 @@
   address_data().AddProfile(profiles[2]);
 
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-      profiles_to_suggest =
-          test_api(suggestion_generator())
-              .GetProfilesToSuggest(address_data(), NAME_FIRST, u"",
-                                    /*field_is_autofilled=*/false,
-                                    {NAME_FIRST, NAME_LAST});
+      profiles_to_suggest = GetProfilesToSuggestForTest(
+          address_data(), NAME_FIRST, u"",
+          /*field_is_autofilled=*/false, {NAME_FIRST, NAME_LAST});
 
   EXPECT_EQ(3U, profiles_to_suggest.size());
 }
@@ -538,10 +501,9 @@
   }
 
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-      profiles_to_suggest =
-          test_api(suggestion_generator())
-              .GetProfilesToSuggest(address_data(), NAME_FULL, u"",
-                                    /*field_is_autofilled=*/false, {NAME_FULL});
+      profiles_to_suggest = GetProfilesToSuggestForTest(
+          address_data(), NAME_FULL, u"",
+          /*field_is_autofilled=*/false, {NAME_FULL});
 
   ASSERT_EQ(kMaxDeduplicatedProfilesForSuggestion, profiles_to_suggest.size());
 
@@ -553,9 +515,8 @@
 
 TEST_F(AddressSuggestionGeneratorTest,
        GetProfilesToSuggest_EmptyMatchingProfiles) {
-  ASSERT_EQ(0U, test_api(suggestion_generator())
-                    .GetProfilesToSuggest(address_data(), NAME_FIRST, u"",
-                                          /*field_is_autofilled=*/false, {})
+  ASSERT_EQ(0U, GetProfilesToSuggestForTest(address_data(), NAME_FIRST, u"",
+                                            /*field_is_autofilled=*/false, {})
                     .size());
 }
 
@@ -578,10 +539,9 @@
   address_data().AddProfile(profile_2);
 
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-      profiles_to_suggest =
-          test_api(suggestion_generator())
-              .GetProfilesToSuggest(address_data(), NAME_FULL, u"",
-                                    /*field_is_autofilled=*/false, {NAME_FULL});
+      profiles_to_suggest = GetProfilesToSuggestForTest(
+          address_data(), NAME_FULL, u"",
+          /*field_is_autofilled=*/false, {NAME_FULL});
 
   ASSERT_EQ(1u, profiles_to_suggest.size());
   EXPECT_EQ(profile_1.guid(), profiles_to_suggest[0]->guid());
@@ -603,9 +563,8 @@
 
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
       profiles_to_suggest =
-          test_api(suggestion_generator())
-              .GetProfilesToSuggest(address_data(), NAME_FIRST, u"Mar",
-                                    /*field_is_autofilled=*/false, {});
+          GetProfilesToSuggestForTest(address_data(), NAME_FIRST, u"Mar",
+                                      /*field_is_autofilled=*/false, {});
 
   ASSERT_EQ(1U, profiles_to_suggest.size());
   EXPECT_EQ(marion_profile.guid(), profiles_to_suggest[0]->guid());
@@ -619,9 +578,8 @@
 
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
       profiles_to_suggest =
-          test_api(suggestion_generator())
-              .GetProfilesToSuggest(address_data(), NAME_FIRST, u"Mar",
-                                    /*field_is_autofilled=*/false, {});
+          GetProfilesToSuggestForTest(address_data(), NAME_FIRST, u"Mar",
+                                      /*field_is_autofilled=*/false, {});
 
   ASSERT_TRUE(profiles_to_suggest.empty());
 }
@@ -630,9 +588,8 @@
        GetProfilesToSuggest_EmptyProfilesInput) {
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
       profiles_to_suggest =
-          test_api(suggestion_generator())
-              .GetProfilesToSuggest(address_data(), NAME_FIRST, u"Mar",
-                                    /*field_is_autofilled=*/false, {});
+          GetProfilesToSuggestForTest(address_data(), NAME_FIRST, u"Mar",
+                                      /*field_is_autofilled=*/false, {});
 
   ASSERT_TRUE(profiles_to_suggest.empty());
 }
@@ -663,10 +620,9 @@
 
   base::HistogramTester histogram_tester;
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-      profiles_to_suggest =
-          test_api(suggestion_generator())
-              .GetProfilesToSuggest(address_data(), NAME_FULL, u"",
-                                    /*field_is_autofilled=*/false, {NAME_FULL});
+      profiles_to_suggest = GetProfilesToSuggestForTest(
+          address_data(), NAME_FULL, u"",
+          /*field_is_autofilled=*/false, {NAME_FULL});
 
   ASSERT_EQ(kNbSuggestions, profiles_to_suggest.size());
   for (size_t i = 0; i < kNbSuggestions; ++i) {
@@ -700,10 +656,9 @@
 
   base::HistogramTester histogram_tester;
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-      profiles_to_suggest =
-          test_api(suggestion_generator())
-              .GetProfilesToSuggest(address_data(), NAME_FULL, u"",
-                                    /*field_is_autofilled=*/false, {NAME_FULL});
+      profiles_to_suggest = GetProfilesToSuggestForTest(
+          address_data(), NAME_FULL, u"",
+          /*field_is_autofilled=*/false, {NAME_FULL});
 
   ASSERT_EQ(profiles_to_suggest.size(), 1u);
   EXPECT_EQ(profiles_to_suggest.front()->guid(), profile_1.guid());
@@ -717,12 +672,10 @@
                        "123 Zoo St.\nSecond Line\nThird line", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
 
-  std::vector<Suggestion> suggestions =
-      test_api(suggestion_generator())
-          .CreateSuggestionsFromProfiles(
-              {&profile}, {ADDRESS_HOME_STREET_ADDRESS},
-              SuggestionType::kAddressEntry, ADDRESS_HOME_STREET_ADDRESS,
-              /*trigger_field_max_length=*/0);
+  std::vector<Suggestion> suggestions = CreateSuggestionsFromProfilesForTest(
+      {&profile}, {ADDRESS_HOME_STREET_ADDRESS}, SuggestionType::kAddressEntry,
+      ADDRESS_HOME_STREET_ADDRESS,
+      /*trigger_field_max_length=*/0);
   ASSERT_FALSE(suggestions.empty());
   EXPECT_EQ(u"123 Zoo St., Second Line, Third line, unit 5",
             suggestions[0].main_text.value);
@@ -736,12 +689,10 @@
                        "123 Zoo St.\nSecond Line\nThird line", "unit 5",
                        "Hollywood", "CA", "91601", "US", "12345678910");
 
-  std::vector<Suggestion> suggestions =
-      test_api(suggestion_generator())
-          .CreateSuggestionsFromProfiles({&profile}, {PHONE_HOME_WHOLE_NUMBER},
-                                         SuggestionType::kAddressEntry,
-                                         PHONE_HOME_WHOLE_NUMBER,
-                                         /*trigger_field_max_length=*/0);
+  std::vector<Suggestion> suggestions = CreateSuggestionsFromProfilesForTest(
+      {&profile}, {PHONE_HOME_WHOLE_NUMBER}, SuggestionType::kAddressEntry,
+      PHONE_HOME_WHOLE_NUMBER,
+      /*trigger_field_max_length=*/0);
   ASSERT_FALSE(suggestions.empty());
   EXPECT_EQ(u"+1 234-567-8910", suggestions[0].main_text.value);
 }
@@ -753,11 +704,10 @@
   AutofillProfile profile = test::GetFullProfile();
 
   EXPECT_THAT(
-      test_api(suggestion_generator())
-          .CreateSuggestionsFromProfiles({&profile}, {NAME_FIRST, NAME_LAST},
-                                         SuggestionType::kAddressEntry,
-                                         NAME_FIRST,
-                                         /*trigger_field_max_length=*/0),
+      CreateSuggestionsFromProfilesForTest({&profile}, {NAME_FIRST, NAME_LAST},
+                                           SuggestionType::kAddressEntry,
+                                           NAME_FIRST,
+                                           /*trigger_field_max_length=*/0),
       SuggestionVectorMainTextsAre(Suggestion::Text(
           profile.GetRawInfo(NAME_FULL), Suggestion::Text::IsPrimary(true))));
 }
@@ -807,14 +757,12 @@
   const std::u16string full_form_filling_label =
       GetFullFormFillingLabel(profile);
 
-  EXPECT_THAT(
-      test_api(suggestion_generator())
-          .CreateSuggestionsFromProfiles(
-              {&profile},
-              {NAME_FULL, ADDRESS_HOME_STREET_ADDRESS, ADDRESS_HOME_ZIP},
-              SuggestionType::kAddressEntry, triggering_field_type,
-              /*trigger_field_max_length=*/0),
-      ElementsAre(AllOf(EqualLabels({{full_form_filling_label}}))));
+  EXPECT_THAT(CreateSuggestionsFromProfilesForTest(
+                  {&profile},
+                  {NAME_FULL, ADDRESS_HOME_STREET_ADDRESS, ADDRESS_HOME_ZIP},
+                  SuggestionType::kAddressEntry, triggering_field_type,
+                  /*trigger_field_max_length=*/0),
+              ElementsAre(AllOf(EqualLabels({{full_form_filling_label}}))));
 }
 
 TEST_P(
@@ -833,11 +781,10 @@
       l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR);
 
   EXPECT_THAT(
-      test_api(suggestion_generator())
-          .CreateSuggestionsFromProfiles(
-              {&profile1, &profile2}, {NAME_FULL, ADDRESS_HOME_STREET_ADDRESS},
-              SuggestionType::kAddressEntry, triggering_field_type,
-              /*trigger_field_max_length=*/0),
+      CreateSuggestionsFromProfilesForTest(
+          {&profile1, &profile2}, {NAME_FULL, ADDRESS_HOME_STREET_ADDRESS},
+          SuggestionType::kAddressEntry, triggering_field_type,
+          /*trigger_field_max_length=*/0),
       ElementsAre(
           AllOf(EqualLabels({{full_form_filling_label + u"hoa@gmail.com"}})),
           AllOf(EqualLabels({{full_form_filling_label + u"pham@gmail.com"}}))));
@@ -861,11 +808,10 @@
       l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR);
 
   EXPECT_THAT(
-      test_api(suggestion_generator())
-          .CreateSuggestionsFromProfiles(
-              {&profile1, &profile2}, {NAME_FULL, ADDRESS_HOME_STREET_ADDRESS},
-              SuggestionType::kAddressEntry, triggering_field_type,
-              /*trigger_field_max_length=*/0),
+      CreateSuggestionsFromProfilesForTest(
+          {&profile1, &profile2}, {NAME_FULL, ADDRESS_HOME_STREET_ADDRESS},
+          SuggestionType::kAddressEntry, triggering_field_type,
+          /*trigger_field_max_length=*/0),
       ElementsAre(
           AllOf(EqualLabels({{full_form_filling_label + u"United States"}})),
           AllOf(EqualLabels({{full_form_filling_label + u"Switzerland"}}))));
@@ -879,11 +825,9 @@
       SuggestionType suggestion_type,
       FieldType trigger_field_type,
       const FieldTypeSet& field_types) {
-    return test_api(suggestion_generator())
-        .CreateSuggestionsFromProfiles({&profile}, field_types, suggestion_type,
-                                       trigger_field_type,
-                                       /*trigger_field_max_length=*/0,
-                                       autofill_client()->IsOffTheRecord());
+    return CreateSuggestionsFromProfilesForTest(
+        {&profile}, field_types, suggestion_type, trigger_field_type,
+        /*trigger_field_max_length=*/0, autofill_client()->IsOffTheRecord());
   }
 
   std::vector<Suggestion> CreateSuggestionWithChildrenFromProfile(
@@ -947,13 +891,10 @@
 
   // `profile_1` and `profile_2` have the same `ADDRESS_HOME_LINE1`, which
   // will lead to the necessity of a differentiating label (`NAME_FULL`).
-  std::vector<Suggestion> suggestions =
-      test_api(suggestion_generator())
-          .CreateSuggestionsFromProfiles(
-              {&profile_1, &profile_2},
-              {ADDRESS_HOME_LINE1, ADDRESS_HOME_LINE2},
-              SuggestionType::kFillFullAddress, ADDRESS_HOME_LINE1,
-              /*trigger_field_max_length=*/0);
+  std::vector<Suggestion> suggestions = CreateSuggestionsFromProfilesForTest(
+      {&profile_1, &profile_2}, {ADDRESS_HOME_LINE1, ADDRESS_HOME_LINE2},
+      SuggestionType::kFillFullAddress, ADDRESS_HOME_LINE1,
+      /*trigger_field_max_length=*/0);
 
   ASSERT_EQ(suggestions.size(), 2u);
   EXPECT_EQ(suggestions[0].labels,
@@ -977,13 +918,11 @@
   // `profile_1` and `profile_2` have the same `ADDRESS_HOME_ZIP`, which
   // will lead to the necessity of a differentiating label
   // (`ADDRESS_HOME_CITY`).
-  std::vector<Suggestion> suggestions =
-      test_api(suggestion_generator())
-          .CreateSuggestionsFromProfiles(
-              {&profile_1, &profile_2},
-              {ADDRESS_HOME_LINE1, ADDRESS_HOME_ZIP, ADDRESS_HOME_CITY},
-              SuggestionType::kFillFullAddress, ADDRESS_HOME_ZIP,
-              /*trigger_field_max_length=*/0);
+  std::vector<Suggestion> suggestions = CreateSuggestionsFromProfilesForTest(
+      {&profile_1, &profile_2},
+      {ADDRESS_HOME_LINE1, ADDRESS_HOME_ZIP, ADDRESS_HOME_CITY},
+      SuggestionType::kFillFullAddress, ADDRESS_HOME_ZIP,
+      /*trigger_field_max_length=*/0);
 
   ASSERT_EQ(suggestions.size(), 2u);
   EXPECT_EQ(suggestions[0].labels,
@@ -1016,11 +955,9 @@
     CreateSuggestionsFromProfiles_GroupFillingLabels_SingleFieldFillingHasNoLabels) {
   AutofillProfile profile = test::GetFullProfile();
 
-  std::vector<Suggestion> suggestions =
-      test_api(suggestion_generator())
-          .CreateSuggestionsFromProfiles(
-              {&profile}, {NAME_FULL}, SuggestionType::kFillFullName, NAME_FULL,
-              /*trigger_field_max_length=*/0);
+  std::vector<Suggestion> suggestions = CreateSuggestionsFromProfilesForTest(
+      {&profile}, {NAME_FULL}, SuggestionType::kFillFullName, NAME_FULL,
+      /*trigger_field_max_length=*/0);
 
   ASSERT_EQ(suggestions.size(), 1u);
   EXPECT_EQ(suggestions[0].labels,
@@ -1600,11 +1537,10 @@
 
   FormFieldData triggering_field;
 
-  std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForProfiles(
-          *autofill_client(), {UNKNOWN_TYPE}, triggering_field, UNKNOWN_TYPE,
-          SuggestionType::kAddressEntry,
-          AutofillSuggestionTriggerSource::kManualFallbackAddress);
+  std::vector<Suggestion> suggestions = GetSuggestionsForProfiles(
+      *autofill_client(), {UNKNOWN_TYPE}, triggering_field, UNKNOWN_TYPE,
+      SuggestionType::kAddressEntry,
+      AutofillSuggestionTriggerSource::kManualFallbackAddress);
   EXPECT_EQ(suggestions.size(), 4ul);
   EXPECT_THAT(suggestions[0], EqualsSuggestion(SuggestionType::kAddressEntry));
   EXPECT_THAT(suggestions[1], EqualsSuggestion(SuggestionType::kAddressEntry));
@@ -1630,13 +1566,10 @@
   profiles[3].SetRawInfo(EMAIL_ADDRESS, u"munich@gmail.com");
   profiles[4].SetRawInfo(EMAIL_ADDRESS, u"other@gmail.com");
 
-  std::vector<Suggestion> suggestions =
-      test_api(suggestion_generator())
-          .CreateSuggestionsFromProfiles(
-              {&profiles[0], &profiles[1], &profiles[2], &profiles[3],
-               &profiles[4]},
-              {UNKNOWN_TYPE}, SuggestionType::kAddressEntry, UNKNOWN_TYPE,
-              /*trigger_field_max_length=*/0);
+  std::vector<Suggestion> suggestions = CreateSuggestionsFromProfilesForTest(
+      {&profiles[0], &profiles[1], &profiles[2], &profiles[3], &profiles[4]},
+      {UNKNOWN_TYPE}, SuggestionType::kAddressEntry, UNKNOWN_TYPE,
+      /*trigger_field_max_length=*/0);
 
   ASSERT_EQ(5u, suggestions.size());
   EXPECT_THAT(
@@ -1690,12 +1623,9 @@
   profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, u"港区六本木ヒルズ森タワー");
   profile.set_language_code("ja");
 
-  std::vector<Suggestion> suggestions =
-      test_api(suggestion_generator())
-          .CreateSuggestionsFromProfiles({&profile}, {UNKNOWN_TYPE},
-                                         SuggestionType::kAddressEntry,
-                                         UNKNOWN_TYPE,
-                                         /*trigger_field_max_length=*/0);
+  std::vector<Suggestion> suggestions = CreateSuggestionsFromProfilesForTest(
+      {&profile}, {UNKNOWN_TYPE}, SuggestionType::kAddressEntry, UNKNOWN_TYPE,
+      /*trigger_field_max_length=*/0);
   EXPECT_THAT(suggestions,
               ElementsAre(AllOf(
                   Field(&Suggestion::main_text,
@@ -1717,12 +1647,9 @@
   profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, u"الملكي");
   profile.set_language_code("ar");
 
-  std::vector<Suggestion> suggestions =
-      test_api(suggestion_generator())
-          .CreateSuggestionsFromProfiles({&profile}, {UNKNOWN_TYPE},
-                                         SuggestionType::kAddressEntry,
-                                         UNKNOWN_TYPE,
-                                         /*trigger_field_max_length=*/0);
+  std::vector<Suggestion> suggestions = CreateSuggestionsFromProfilesForTest(
+      {&profile}, {UNKNOWN_TYPE}, SuggestionType::kAddressEntry, UNKNOWN_TYPE,
+      /*trigger_field_max_length=*/0);
   EXPECT_THAT(
       suggestions,
       ElementsAre(AllOf(
@@ -1743,12 +1670,9 @@
   profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, u"57 ปาร์คเวนเชอร์");
   profile.set_language_code("th");
 
-  std::vector<Suggestion> suggestions =
-      test_api(suggestion_generator())
-          .CreateSuggestionsFromProfiles({&profile}, {UNKNOWN_TYPE},
-                                         SuggestionType::kAddressEntry,
-                                         UNKNOWN_TYPE,
-                                         /*trigger_field_max_length=*/0);
+  std::vector<Suggestion> suggestions = CreateSuggestionsFromProfilesForTest(
+      {&profile}, {UNKNOWN_TYPE}, SuggestionType::kAddressEntry, UNKNOWN_TYPE,
+      /*trigger_field_max_length=*/0);
   EXPECT_THAT(suggestions,
               ElementsAre(AllOf(
                   Field(&Suggestion::main_text,
@@ -1853,13 +1777,11 @@
   ASSERT_FALSE(profile.HasRawInfo(PHONE_HOME_WHOLE_NUMBER));
   address_data().AddProfile(profile);
 
-  std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForProfiles(
-          *autofill_client(),
-          {NAME_FULL, ADDRESS_HOME_STREET_ADDRESS, PHONE_HOME_WHOLE_NUMBER},
-          FormFieldData(), PHONE_HOME_WHOLE_NUMBER,
-          SuggestionType::kAddressEntry,
-          AutofillSuggestionTriggerSource::kManualFallbackAddress);
+  std::vector<Suggestion> suggestions = GetSuggestionsForProfiles(
+      *autofill_client(),
+      {NAME_FULL, ADDRESS_HOME_STREET_ADDRESS, PHONE_HOME_WHOLE_NUMBER},
+      FormFieldData(), PHONE_HOME_WHOLE_NUMBER, SuggestionType::kAddressEntry,
+      AutofillSuggestionTriggerSource::kManualFallbackAddress);
   ASSERT_EQ(3u, suggestions.size());
   EXPECT_EQ(suggestions[0].type, SuggestionType::kAddressEntry);
   // This is the check which actually verifies that the suggestion looks the
@@ -1885,17 +1807,16 @@
                    .starts_with(profile1.GetRawInfo(NAME_FIRST)));
 
   // Expect that regular suggestions filter.
-  std::vector<Suggestion> address_suggestions =
-      suggestion_generator().GetSuggestionsForProfiles(
-          *autofill_client(), {NAME_FIRST}, triggering_field, NAME_FIRST,
-          SuggestionType::kAddressEntry,
-          AutofillSuggestionTriggerSource::kFormControlElementClicked);
+  std::vector<Suggestion> address_suggestions = GetSuggestionsForProfiles(
+      *autofill_client(), {NAME_FIRST}, triggering_field, NAME_FIRST,
+      SuggestionType::kAddressEntry,
+      AutofillSuggestionTriggerSource::kFormControlElementClicked);
   EXPECT_EQ(address_suggestions.size(), 3ul);
   EXPECT_THAT(address_suggestions, ContainsAddressFooterSuggestions());
 
   // But manual fallback suggestions do not.
   std::vector<Suggestion> manual_fallback_suggestions =
-      suggestion_generator().GetSuggestionsForProfiles(
+      GetSuggestionsForProfiles(
           *autofill_client(), {NAME_FIRST}, triggering_field, NAME_FIRST,
           SuggestionType::kAddressEntry,
           AutofillSuggestionTriggerSource::kManualFallbackAddress);
@@ -1915,22 +1836,18 @@
   address_data().AddProfile(profile2);
 
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-      profiles_to_suggest =
-          test_api(suggestion_generator())
-              .GetProfilesToSuggest(
-                  address_data(), NAME_FIRST, /*field_contents=*/u"",
-                  /*field_is_autofilled=*/false, {NAME_FIRST},
-                  AutofillSuggestionTriggerSource::kFormControlElementClicked);
+      profiles_to_suggest = GetProfilesToSuggestForTest(
+          address_data(), NAME_FIRST, /*field_contents=*/u"",
+          /*field_is_autofilled=*/false, {NAME_FIRST},
+          AutofillSuggestionTriggerSource::kFormControlElementClicked);
   // Expect that left click (or regular triggering) filters profiles.
   EXPECT_EQ(profiles_to_suggest.size(), 1u);
 
   std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>
-      profiles_to_suggest_from_manual_fallback =
-          test_api(suggestion_generator())
-              .GetProfilesToSuggest(
-                  address_data(), NAME_FIRST, /*field_contents=*/u"",
-                  /*field_is_autofilled=*/false, {NAME_FIRST},
-                  AutofillSuggestionTriggerSource::kManualFallbackAddress);
+      profiles_to_suggest_from_manual_fallback = GetProfilesToSuggestForTest(
+          address_data(), NAME_FIRST, /*field_contents=*/u"",
+          /*field_is_autofilled=*/false, {NAME_FIRST},
+          AutofillSuggestionTriggerSource::kManualFallbackAddress);
   // But manual fallback triggering does not.
   EXPECT_EQ(profiles_to_suggest_from_manual_fallback.size(), 2u);
 }
@@ -1940,10 +1857,9 @@
   address_data().AddProfile(test::GetFullProfile());
   FormFieldData field;
   field.set_is_autofilled(true);
-  std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForProfiles(
-          *autofill_client(), {NAME_FIRST}, field, NAME_FIRST,
-          SuggestionType::kAddressEntry, kDefaultTriggerSource);
+  std::vector<Suggestion> suggestions = GetSuggestionsForProfiles(
+      *autofill_client(), {NAME_FIRST}, field, NAME_FIRST,
+      SuggestionType::kAddressEntry, kDefaultTriggerSource);
   EXPECT_THAT(suggestions,
               ElementsAre(EqualsSuggestion(SuggestionType::kAddressEntry),
                           EqualsSuggestion(SuggestionType::kSeparator),
@@ -1956,11 +1872,10 @@
        TestAddressSuggestion_AddressField_ReturnSuggestion) {
   AutofillProfile profile = test::GetFullProfile();
   autofill_client()->set_test_addresses({profile});
-  std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForProfiles(
-          *autofill_client(), /*field_types=*/{NAME_FIRST}, FormFieldData(),
-          NAME_FIRST, SuggestionType::kAddressEntry,
-          AutofillSuggestionTriggerSource::kManualFallbackAddress);
+  std::vector<Suggestion> suggestions = GetSuggestionsForProfiles(
+      *autofill_client(), /*field_types=*/{NAME_FIRST}, FormFieldData(),
+      NAME_FIRST, SuggestionType::kAddressEntry,
+      AutofillSuggestionTriggerSource::kManualFallbackAddress);
 
   // There should be one `SuggestionType::kDevtoolsTestAddresses`, one
   // `SuggestionType::kSeparator` and one `SuggestionType::kManageAddress`.
@@ -1987,11 +1902,10 @@
       features::kAutofillForUnclassifiedFieldsAvailable);
   AutofillProfile profile = test::GetFullProfile();
   autofill_client()->set_test_addresses({profile});
-  std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForProfiles(
-          *autofill_client(), /*field_types=*/{CREDIT_CARD_NUMBER},
-          FormFieldData(), CREDIT_CARD_NUMBER, SuggestionType::kAddressEntry,
-          AutofillSuggestionTriggerSource::kManualFallbackAddress);
+  std::vector<Suggestion> suggestions = GetSuggestionsForProfiles(
+      *autofill_client(), /*field_types=*/{CREDIT_CARD_NUMBER}, FormFieldData(),
+      CREDIT_CARD_NUMBER, SuggestionType::kAddressEntry,
+      AutofillSuggestionTriggerSource::kManualFallbackAddress);
 
   EXPECT_THAT(suggestions, IsEmpty());
 }
diff --git a/components/autofill/core/browser/autofill_client.h b/components/autofill/core/browser/autofill_client.h
index 10f90a6..3ce1993 100644
--- a/components/autofill/core/browser/autofill_client.h
+++ b/components/autofill/core/browser/autofill_client.h
@@ -242,9 +242,9 @@
     CardSaveType card_save_type = CardSaveType::kCardSaveOnly;
   };
 
-  // TODO(b/325440757): Remove after the save-update controller splitting is
-  // done or remove this TODO if a new option is added.
-  // Used for options of save (and update) address profile prompt.
+  // TODO(crbug.com/325440757): Remove after the save-update controller
+  // splitting is done or remove this TODO if a new option is added. Used for
+  // options of save (and update) address profile prompt.
   struct SaveAddressProfilePromptOptions {
     // Whether the prompt suggests migration into the user's account.
     bool is_migration_to_account = false;
@@ -264,8 +264,9 @@
     PopupOpenArgs& operator=(const PopupOpenArgs&);
     PopupOpenArgs& operator=(PopupOpenArgs&&);
     ~PopupOpenArgs();
-    // TODO(b/340817507): Update this member name since bounds can now refer to
-    // the caret bounds and elements gives the idea of HTML elements only.
+    // TODO(crbug.com/340817507): Update this member name since bounds can now
+    // refer to the caret bounds and elements gives the idea of HTML elements
+    // only.
     gfx::RectF element_bounds;
     base::i18n::TextDirection text_direction =
         base::i18n::TextDirection::UNKNOWN_DIRECTION;
diff --git a/components/autofill/core/browser/autofill_data_util.cc b/components/autofill/core/browser/autofill_data_util.cc
index 7b97ac14..0480c35 100644
--- a/components/autofill/core/browser/autofill_data_util.cc
+++ b/components/autofill/core/browser/autofill_data_util.cc
@@ -112,23 +112,23 @@
 
 // The common and non-ambiguous CJK surnames (last names) that have more than
 // one character.
-constexpr auto kCommonCjkMultiCharSurnames = std::to_array<std::string_view>(
+constexpr auto kCommonCjkMultiCharSurnames = std::to_array<std::u16string_view>(
     {// Korean, taken from the list of surnames:
      // https://ko.wikipedia.org/wiki/%ED%95%9C%EA%B5%AD%EC%9D%98_%EC%84%B1%EC%94%A8_%EB%AA%A9%EB%A1%9D
-     "남궁", "사공", "서문", "선우", "제갈", "황보", "독고", "망절",
+     u"남궁", u"사공", u"서문", u"선우", u"제갈", u"황보", u"독고", u"망절",
      // Chinese, taken from the top 10 Chinese 2-character surnames:
      // https://zh.wikipedia.org/wiki/%E8%A4%87%E5%A7%93#.E5.B8.B8.E8.A6.8B.E7.9A.84.E8.A4.87.E5.A7.93
      // Simplified Chinese (mostly mainland China)
-     "欧阳", "令狐", "皇甫", "上官", "司徒", "诸葛", "司马", "宇文", "呼延",
-     "端木",
+     u"欧阳", u"令狐", u"皇甫", u"上官", u"司徒", u"诸葛", u"司马", u"宇文",
+     u"呼延", u"端木",
      // Traditional Chinese (mostly Taiwan)
-     "張簡", "歐陽", "諸葛", "申屠", "尉遲", "司馬", "軒轅", "夏侯"});
+     u"張簡", u"歐陽", u"諸葛", u"申屠", u"尉遲", u"司馬", u"軒轅", u"夏侯"});
 
 // All Korean surnames that have more than one character, even the
 // rare/ambiguous ones.
-constexpr auto kKoreanMultiCharSurnames = std::to_array<std::string_view>(
-    {"강전", "남궁", "독고", "동방", "망절", "사공", "서문", "선우", "소봉",
-     "어금", "장곡", "제갈", "황목", "황보"});
+constexpr auto kKoreanMultiCharSurnames = std::to_array<std::u16string_view>(
+    {u"강전", u"남궁", u"독고", u"동방", u"망절", u"사공", u"서문", u"선우",
+     u"소봉", u"어금", u"장곡", u"제갈", u"황목", u"황보"});
 
 // Returns true if `set` contains `element`, modulo a final period.
 bool ContainsString(base::span<const std::string_view> set,
@@ -173,11 +173,10 @@
 // `prefixes`. The returned value is the length of the prefix found, or 0 if
 // none is found.
 size_t StartsWithAny(std::u16string_view name,
-                     base::span<const std::string_view> prefixes) {
-  for (std::string_view prefix : prefixes) {
-    std::u16string buffer = base::UTF8ToUTF16(prefix);
-    if (name.starts_with(buffer)) {
-      return buffer.size();
+                     base::span<const std::u16string_view> prefixes) {
+  for (std::u16string_view prefix : prefixes) {
+    if (name.starts_with(prefix)) {
+      return prefix.size();
     }
   }
   return 0;
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc
index 442bcd9..5d107db 100644
--- a/components/autofill/core/browser/autofill_external_delegate.cc
+++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -258,7 +258,7 @@
   // Hide warnings as appropriate.
   PossiblyRemoveAutofillWarnings(&suggestions);
 
-  // TODO(b/320126773): consider moving these metrics to a better place.
+  // TODO(crbug.com/320126773): consider moving these metrics to a better place.
   if (base::ranges::any_of(suggestions, [](const Suggestion& suggestion) {
         return suggestion.type == SuggestionType::kShowAccountCards;
       })) {
@@ -402,7 +402,8 @@
   } else {
     // We send autocomplete availability event even though there might be no
     // autocomplete suggestions shown.
-    // TODO(b/315748930): Provide AX event only for autocomplete entries.
+    // TODO(crbug.com/315748930): Provide AX event only for autocomplete
+    // entries.
     OnAutofillAvailabilityEvent(
         mojom::AutofillSuggestionAvailability::kAutocompleteAvailable);
     if (base::Contains(shown_suggestion_types_,
diff --git a/components/autofill/core/browser/autofill_plus_address_delegate.h b/components/autofill/core/browser/autofill_plus_address_delegate.h
index 6998124..9235956a 100644
--- a/components/autofill/core/browser/autofill_plus_address_delegate.h
+++ b/components/autofill/core/browser/autofill_plus_address_delegate.h
@@ -67,7 +67,8 @@
 
   // Returns the "Manage plus addresses..." suggestion which redirects the user
   // to the plus address management page.
-  // TODO(b/342330801): Remove `std::optional` when the UI redesign is launched.
+  // TODO(crbug.com/342330801): Remove `std::optional` when the UI redesign is
+  // launched.
   virtual std::optional<Suggestion> GetManagePlusAddressSuggestion() const = 0;
 
   // Logs Autofill suggestion events related to plus addresses.
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc
index 123b8311..aff443c 100644
--- a/components/autofill/core/browser/browser_autofill_manager.cc
+++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -2,16 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO: crbug.com/347137620 - Remove this and spanify to fix the errors.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "components/autofill/core/browser/browser_autofill_manager.h"
 
 #include <stddef.h>
 #include <stdint.h>
 
+#include <array>
 #include <iterator>
 #include <limits>
 #include <map>
@@ -287,7 +283,7 @@
 // a plus address suggestion.
 // It only logs these metrics for users that are signed in and tabs that are not
 // in incognito mode.
-// TODO(b/327328460): Clean up once the metric is has been evaluated.
+// TODO(crbug.com/327328460): Clean up once the metric is has been evaluated.
 void MaybeLogAutocompleteSuppressionByPlusAddresses(
     AutofillClient& client,
     base::span<const Suggestion> suggestions,
@@ -529,7 +525,7 @@
   if (context.filling_product == FillingProduct::kCreditCard) {
     AutofillMetrics::LogIsQueriedCreditCardFormSecure(
         context.is_context_secure);
-    // TODO(b/41484171): Move to PaymentsSuggestionGenerator.
+    // TODO(crbug.com/41484171): Move to payments_suggestion_generator.cc.
     autofill_metrics::LogSuggestionsCount(
         base::ranges::count_if(suggestions,
                                [](const Suggestion& suggestion) {
@@ -540,7 +536,7 @@
         FillingProduct::kCreditCard);
   }
   if (context.filling_product == FillingProduct::kAddress) {
-    // TODO(b/41484171): Move to AddressSuggestionGenerator.
+    // TODO(crbug.com/41484171): Move to address_suggestion_generator.cc.
     autofill_metrics::LogSuggestionsCount(
         base::ranges::count_if(suggestions,
                                [](const Suggestion& suggestion) {
@@ -625,10 +621,6 @@
     : AutofillManager(driver),
       external_delegate_(std::make_unique<AutofillExternalDelegate>(this)),
       app_locale_(app_locale),
-      address_suggestion_generator_(
-          std::make_unique<AddressSuggestionGenerator>()),
-      payments_suggestion_generator_(
-          std::make_unique<PaymentsSuggestionGenerator>()),
       form_filler_(
           std::make_unique<FormFiller>(*this, log_manager(), app_locale)) {
   address_form_event_logger_ =
@@ -1420,7 +1412,7 @@
     }
   }
 
-  // TODO(b/340494671): Move ShouldOfferSingleFieldFormFill out of
+  // TODO(crbug.com/340494671): Move ShouldOfferSingleFieldFormFill out of
   // OnAskForValuesToFillImpl.
   auto ShouldOfferSingleFieldFormFill = [&] {
     if (!suggestions.empty() || !should_offer_other_suggestions) {
@@ -1646,26 +1638,24 @@
                                    form_structure, autofill_field, value, type,
                                    field_type_used);
   if (action_persistence == mojom::ActionPersistence::kFill) {
-    const FormFieldData* const_field = &field;
-    const AutofillField* const_autofill_field = autofill_field;
     if (type == SuggestionType::kAddressFieldByFieldFilling) {
       address_form_event_logger_->OnFilledByFieldByFieldFilling(type);
       address_form_event_logger_->RecordFillingOperation(
-          form.global_id(), base::make_span(&const_field, 1u),
-          base::make_span(&const_autofill_field, 1u));
+          form.global_id(), std::to_array<const FormFieldData*>({&field}),
+          std::to_array<const AutofillField*>({autofill_field}));
     } else if (type == SuggestionType::kCreditCardFieldByFieldFilling) {
       credit_card_form_event_logger_->OnFilledByFieldByFieldFilling(type);
       credit_card_form_event_logger_->RecordFillingOperation(
-          form.global_id(), base::make_span(&const_field, 1u),
-          base::make_span(&const_autofill_field, 1u));
+          form.global_id(), std::to_array<const FormFieldData*>({&field}),
+          std::to_array<const AutofillField*>({autofill_field}));
     }
 
     const bool is_address_manual_fallback_on_non_address_field =
-        IsAddressAutofillManuallyTriggeredOnNonAddressField(
-            type, const_autofill_field);
+        IsAddressAutofillManuallyTriggeredOnNonAddressField(type,
+                                                            autofill_field);
     const bool is_payments_manual_fallback_on_non_payments_field =
         IsCreditCardAutofillManuallyTriggeredOnNonCreditCardField(
-            type, const_autofill_field);
+            type, autofill_field);
     if (is_address_manual_fallback_on_non_address_field ||
         is_payments_manual_fallback_on_non_payments_field) {
       manual_fallback_logger_->OnDidFillSuggestion(
@@ -2152,7 +2142,7 @@
     const std::vector<Suggestion>& suggestions) {
   MaybeLogAutocompleteSuppressionByPlusAddresses(client(), suggestions,
                                                  focused_field_type_group);
-  // TODO(b/309163415): Replace parameter of FormFieldData in
+  // TODO(crbug.com/309163415): Replace parameter of FormFieldData in
   // `TryToShowTouchToFill` by FieldGlobalId.
   if (const FormFieldData& field =
           CHECK_DEREF(form.FindFieldByGlobalId(field_id));
@@ -2667,9 +2657,9 @@
     return field_types;
   }();
 
-  return address_suggestion_generator_->GetSuggestionsForProfiles(
-      client(), field_types, trigger_field, trigger_field_type,
-      current_suggestion_type, trigger_source);
+  return GetSuggestionsForProfiles(client(), field_types, trigger_field,
+                                   trigger_field_type, current_suggestion_type,
+                                   trigger_source);
 }
 
 std::vector<Suggestion> BrowserAutofillManager::GetCreditCardSuggestions(
@@ -2681,7 +2671,7 @@
       trigger_field, signin_state_for_metrics_);
 
   std::vector<Suggestion> suggestions;
-  PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
+  CreditCardSuggestionSummary summary;
   bool is_virtual_card_standalone_cvc_field = false;
 
   // If credit card number field is not empty and is not autofilled, do not
@@ -2715,21 +2705,17 @@
               GetVirtualCreditCardsForStandaloneCvcField(
                   trigger_field.origin());
       if (!virtual_card_guid_to_last_four_map.empty()) {
-        suggestions =
-            payments_suggestion_generator_
-                ->GetSuggestionsForVirtualCardStandaloneCvc(
-                    client(), trigger_field, summary.metadata_logging_context,
-                    virtual_card_guid_to_last_four_map);
+        suggestions = GetSuggestionsForVirtualCardStandaloneCvc(
+            client(), trigger_field, summary.metadata_logging_context,
+            virtual_card_guid_to_last_four_map);
         is_virtual_card_standalone_cvc_field = true;
       }
     } else {
-      suggestions =
-          payments_suggestion_generator_->GetSuggestionsForCreditCards(
-              client(), trigger_field, trigger_field_type, trigger_source,
-              ShouldShowScanCreditCard(form, trigger_field),
-              ShouldShowCardsFromAccountOption(form, trigger_field,
-                                               trigger_source),
-              summary);
+      suggestions = GetSuggestionsForCreditCards(
+          client(), trigger_field, trigger_field_type, trigger_source,
+          ShouldShowScanCreditCard(form, trigger_field),
+          ShouldShowCardsFromAccountOption(form, trigger_field, trigger_source),
+          summary);
     }
   }
 
diff --git a/components/autofill/core/browser/browser_autofill_manager.h b/components/autofill/core/browser/browser_autofill_manager.h
index f7ae118d..d88e9a89 100644
--- a/components/autofill/core/browser/browser_autofill_manager.h
+++ b/components/autofill/core/browser/browser_autofill_manager.h
@@ -61,13 +61,11 @@
 
 namespace autofill {
 
-class AddressSuggestionGenerator;
 class AutofillField;
 class AutofillClient;
 class AutofillProfile;
 class CreditCard;
 class CreditCardAccessManager;
-class PaymentsSuggestionGenerator;
 
 class FormData;
 class FormFieldData;
@@ -111,7 +109,7 @@
 // plus address suggestion.
 // These values are persisted to logs. Entries should not be renumbered and
 // numeric values should never be reused.
-// TODO(b/327328460): Clean up once the metric is has been evaluated.
+// TODO(crbug.com/327328460): Clean up once the metric is has been evaluated.
 enum class AutocompleteSuppressionByPlusAddress {
   // The Autocomplete suggestions would not have been suppressed.
   kNotSuppressed = 0,
@@ -184,7 +182,8 @@
   // Logs metrics when the user accepts address form filling suggestion. This
   // happens only for already parsed forms (`FormStructure` and `AutofillField`
   // are defined).
-  // TODO(b/40227071): Remove when field-filling and form-filling are merged
+  // TODO(crbug.com/40227071): Remove when field-filling and form-filling are
+  // merged
   virtual void OnDidFillAddressFormFillingSuggestion(
       const AutofillProfile& profile,
       const FormData& form,
@@ -528,8 +527,8 @@
   // modification. `cleared_value` is true if JS wiped the previous value, and
   // `formatting_only` is true if JS only modified whitespaces, symbols and
   // capitalization.
-  // TODO(b/40227496): Remove `cleared_value` when `field` starts containing
-  // the actual current value of the field.
+  // TODO(crbug.com/40227496): Remove `cleared_value` when `field` starts
+  // containing the actual current value of the field.
   void AnalyzeJavaScriptChangedAutofilledValue(const FormStructure& form,
                                                AutofillField& field,
                                                bool cleared_value,
@@ -546,8 +545,8 @@
   // the `form` are filled depends on the `trigger_source`. `context` could
   // contain additional information about the suggestions, such as ablation
   // study related fields.
-  // TODO(b/340494671): Move ablation study fields out of the function and make
-  // the context a const ref.
+  // TODO(crbug.com/340494671): Move ablation study fields out of the function
+  // and make the context a const ref.
   std::vector<Suggestion> GetAvailableAddressAndCreditCardSuggestions(
       const FormData& form,
       const FormFieldData& field,
@@ -576,7 +575,7 @@
   // `GenerateSuggestionsAndMaybeShowUI` and displays them if `show_suggestions`
   // is true (via the `external_delegate_`). It also logs whether there is a
   // suggestion for the user and whether the suggestion is shown.
-  // TODO(b/340494671): Move to the unnamed namespace.
+  // TODO(crbug.com/340494671): Move to the unnamed namespace.
   void OnGenerateSuggestionsComplete(
       const FormData& form,
       const FormFieldData& field,
@@ -694,10 +693,6 @@
   // Lazily initialized: access only through GetCreditCardAccessManager().
   std::unique_ptr<CreditCardAccessManager> credit_card_access_manager_;
 
-  // TODO(b/41484171): Remove.
-  std::unique_ptr<AddressSuggestionGenerator> address_suggestion_generator_;
-  std::unique_ptr<PaymentsSuggestionGenerator> payments_suggestion_generator_;
-
   // Helper class to autofill forms and fields. Do not use directly, use
   // form_filler() instead.
   std::unique_ptr<FormFiller> form_filler_;
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
index fa1e8b8..bf6038c9 100644
--- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO: crbug.com/347137620 - Remove this and spanify to fix the errors.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "components/autofill/core/browser/browser_autofill_manager.h"
 
 #include <stddef.h>
@@ -166,7 +161,7 @@
 
 const std::string kArbitraryNickname = "Grocery Card";
 const std::u16string kArbitraryNickname16 = u"Grocery Card";
-Suggestion::Icon kAddressEntryIcon = Suggestion::Icon::kAccount;
+constexpr Suggestion::Icon kAddressEntryIcon = Suggestion::Icon::kAccount;
 
 // Action `SaveArgElementsTo<k>(pointer)` saves the value pointed to by the
 // `k`th (0-based) argument of the mock function by moving it to `*pointer`.
@@ -183,8 +178,8 @@
 }
 
 bool ShouldSplitCardNameAndLastFourDigitsForMetadata() {
-  // Splitting card name and last four logic does not apply to iOS because the
-  // PaymentsSuggestionGenerator on iOS doesn't currently support it.
+  // Splitting card name and last four logic does not apply to iOS because iOS
+  // doesn't currently support it.
 #if BUILDFLAG(IS_IOS)
   return false;
 #else
@@ -761,7 +756,8 @@
 #if BUILDFLAG(IS_IOS)
   std::u16string value =
       l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM);
-  // TODO(b/40266549): iOS still uses Clear Form logic, replace with Undo.
+  // TODO(crbug.com/40266549): iOS still uses Clear Form logic, replace with
+  // Undo.
   Suggestion suggestion(value, SuggestionType::kUndoOrClear);
   suggestion.icon = Suggestion::Icon::kClear;
 #else
@@ -772,7 +768,7 @@
   Suggestion suggestion(value, SuggestionType::kUndoOrClear);
   suggestion.icon = Suggestion::Icon::kUndo;
 #endif
-  // TODO(b/40266549): update "Clear Form" a11y announcement to "Undo"
+  // TODO(crbug.com/40266549): update "Clear Form" a11y announcement to "Undo"
   suggestion.acceptance_a11y_announcement =
       l10n_util::GetStringUTF16(IDS_AUTOFILL_A11Y_ANNOUNCE_CLEARED_FORM);
   return suggestion;
@@ -1889,8 +1885,7 @@
                   Suggestion::Icon::kNoIcon, SuggestionType::kAddressEntry),
        Suggestion("Elvis", std::vector<std::vector<Suggestion::Text>>{},
                   Suggestion::Icon::kNoIcon, SuggestionType::kAddressEntry),
-       CreateSeparator(),
-       AddressSuggestionGenerator::CreateManageAddressesEntry()});
+       CreateSeparator(), CreateManageAddressesSuggestion()});
 
   // Check that there are no suggestions for the field without the autocomplete
   // attribute.
@@ -1923,8 +1918,7 @@
                   SuggestionType::kAddressEntry),
        Suggestion("Elvis", "Elvis Aaron Presley", kAddressEntryIcon,
                   SuggestionType::kAddressEntry),
-       CreateSeparator(),
-       AddressSuggestionGenerator::CreateManageAddressesEntry()});
+       CreateSeparator(), CreateManageAddressesSuggestion()});
 
   GetAutofillSuggestions(form, form.fields()[1]);
   external_delegate()->CheckSuggestions(
@@ -1933,8 +1927,7 @@
                   SuggestionType::kAddressEntry),
        Suggestion("Presley", "Elvis Aaron Presley", kAddressEntryIcon,
                   SuggestionType::kAddressEntry),
-       CreateSeparator(),
-       AddressSuggestionGenerator::CreateManageAddressesEntry()});
+       CreateSeparator(), CreateManageAddressesSuggestion()});
 }
 
 // Tests that BrowserAutofillManager correctly returns virtual cards with usage
@@ -1990,8 +1983,7 @@
                   SuggestionType::kAddressEntry),
        Suggestion("Elvis", "3734 Elvis Presley Blvd.", kAddressEntryIcon,
                   SuggestionType::kAddressEntry),
-       CreateSeparator(),
-       AddressSuggestionGenerator::CreateManageAddressesEntry()});
+       CreateSeparator(), CreateManageAddressesSuggestion()});
 }
 
 // Test that we return only matching address profile suggestions when the
@@ -2010,8 +2002,7 @@
       field.global_id(),
       {Suggestion("Elvis", "3734 Elvis Presley Blvd.", kAddressEntryIcon,
                   SuggestionType::kAddressEntry),
-       CreateSeparator(),
-       AddressSuggestionGenerator::CreateManageAddressesEntry()});
+       CreateSeparator(), CreateManageAddressesSuggestion()});
 }
 
 // Tests that we return address profile suggestions values when the section
@@ -2062,8 +2053,7 @@
                   SuggestionType::kAddressEntry),
        Suggestion("Grimes", "1234 Smith Blvd.", kAddressEntryIcon,
                   SuggestionType::kAddressEntry),
-       CreateSeparator(),
-       AddressSuggestionGenerator::CreateManageAddressesEntry()});
+       CreateSeparator(), CreateManageAddressesSuggestion()});
 }
 
 // Tests that we return address profile suggestions values when the section
@@ -2087,8 +2077,7 @@
       field.global_id(),
       {Suggestion("Elvis", "3734 Elvis Presley Blvd.", kAddressEntryIcon,
                   SuggestionType::kAddressEntry),
-       CreateSeparator(),
-       AddressSuggestionGenerator::CreateManageAddressesEntry()});
+       CreateSeparator(), CreateManageAddressesSuggestion()});
 }
 
 // Test that we return no suggestions when the form has no relevant fields.
@@ -2253,8 +2242,7 @@
                   SuggestionType::kAddressEntry),
        Suggestion("Elvis", "3734 Elvis Presley Blvd.", kAddressEntryIcon,
                   SuggestionType::kAddressEntry),
-       CreateSeparator(),
-       AddressSuggestionGenerator::CreateManageAddressesEntry()});
+       CreateSeparator(), CreateManageAddressesSuggestion()});
 }
 
 // Test that we return no suggestions when autofill is disabled.
@@ -2514,7 +2502,7 @@
       form.fields()[1].global_id(),
       {GetCardSuggestion(kVisaCard), GetCardSuggestion(kMasterCard),
        CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+       CreateManageCreditCardsSuggestion(
            /*with_gpay_logo=*/false)});
 }
 
@@ -2533,11 +2521,10 @@
 
   // Test that we sent the right values to the external delegate.
   external_delegate()->CheckSuggestions(
-      field.global_id(),
-      {GetCardSuggestion(kVisaCard), GetCardSuggestion(kMasterCard),
-       CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
-           /*with_gpay_logo=*/false)});
+      field.global_id(), {GetCardSuggestion(kVisaCard),
+                          GetCardSuggestion(kMasterCard), CreateSeparator(),
+                          CreateManageCreditCardsSuggestion(
+                              /*with_gpay_logo=*/false)});
 }
 
 // Test that we return all credit card profile suggestions when the triggering
@@ -2554,11 +2541,10 @@
   GetAutofillSuggestions(form, field);
   // Test that we sent the right values to the external delegate.
   external_delegate()->CheckSuggestions(
-      field.global_id(),
-      {GetCardSuggestion(kVisaCard), GetCardSuggestion(kMasterCard),
-       CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
-           /*with_gpay_logo=*/false)});
+      field.global_id(), {GetCardSuggestion(kVisaCard),
+                          GetCardSuggestion(kMasterCard), CreateSeparator(),
+                          CreateManageCreditCardsSuggestion(
+                              /*with_gpay_logo=*/false)});
 }
 
 // Test that we return all credit card profile suggestions when the triggering
@@ -2576,11 +2562,10 @@
 
   // Test that we sent the right values to the external delegate.
   external_delegate()->CheckSuggestions(
-      field.global_id(),
-      {GetCardSuggestion(kVisaCard), GetCardSuggestion(kMasterCard),
-       CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
-           /*with_gpay_logo=*/false)});
+      field.global_id(), {GetCardSuggestion(kVisaCard),
+                          GetCardSuggestion(kMasterCard), CreateSeparator(),
+                          CreateManageCreditCardsSuggestion(
+                              /*with_gpay_logo=*/false)});
 }
 
 // Test that we return all credit card profile suggestions when the triggering
@@ -2606,10 +2591,9 @@
 
   // Test that we sent the right value to the external delegate.
   external_delegate()->CheckSuggestions(
-      field.global_id(),
-      {GetCardSuggestion(kMasterCard), CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
-           /*with_gpay_logo=*/false)});
+      field.global_id(), {GetCardSuggestion(kMasterCard), CreateSeparator(),
+                          CreateManageCreditCardsSuggestion(
+                              /*with_gpay_logo=*/false)});
 }
 
 // Test that we return only matching credit card profile suggestions when the
@@ -2628,10 +2612,9 @@
 
   // Test that we sent the right values to the external delegate.
   external_delegate()->CheckSuggestions(
-      field.global_id(),
-      {GetCardSuggestion(kVisaCard), CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
-           /*with_gpay_logo=*/false)});
+      field.global_id(), {GetCardSuggestion(kVisaCard), CreateSeparator(),
+                          CreateManageCreditCardsSuggestion(
+                              /*with_gpay_logo=*/false)});
 }
 
 // Test that we return credit card profile suggestions when the selected form
@@ -2675,7 +2658,7 @@
                   Suggestion::Icon::kCardMasterCard,
                   SuggestionType::kCreditCardEntry),
        CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+       CreateManageCreditCardsSuggestion(
            /*with_gpay_logo=*/false)});
 }
 
@@ -2730,7 +2713,7 @@
                   Suggestion::Icon::kCardMasterCard,
                   SuggestionType::kCreditCardEntry),
        CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+       CreateManageCreditCardsSuggestion(
            /*with_gpay_logo=*/false)});
 }
 
@@ -2783,7 +2766,7 @@
       form.fields()[1].global_id(),
       {GetCardSuggestion(kVisaCard), GetCardSuggestion(kMasterCard),
        CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+       CreateManageCreditCardsSuggestion(
            /*with_gpay_logo=*/false)});
 }
 
@@ -2805,7 +2788,7 @@
       form.fields()[1].global_id(),
       {GetCardSuggestion(kVisaCard), GetCardSuggestion(kMasterCard),
        CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+       CreateManageCreditCardsSuggestion(
            /*with_gpay_logo=*/false)});
 }
 
@@ -2835,7 +2818,7 @@
       form.fields()[1].global_id(),
       {GetCardSuggestion(kVisaCard), GetCardSuggestion(kMasterCard),
        GetCardSuggestion(kMasterCard), CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+       CreateManageCreditCardsSuggestion(
            /*with_gpay_logo=*/false)});
 }
 
@@ -2920,12 +2903,11 @@
   Suggestion mastercard_suggestion = GetCardSuggestion(kMasterCard);
 
   // Test that we sent the credit card suggestions to the external delegate.
-  external_delegate()->CheckSuggestions(
-      form.fields()[1].global_id(),
-      {mastercard_suggestion, amex_suggestion, visa_suggestion,
-       CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
-           /*with_gpay_logo=*/false)});
+  external_delegate()->CheckSuggestions(form.fields()[1].global_id(),
+                                        {mastercard_suggestion, amex_suggestion,
+                                         visa_suggestion, CreateSeparator(),
+                                         CreateManageCreditCardsSuggestion(
+                                             /*with_gpay_logo=*/false)});
 }
 
 // Test cards that are expired AND disused are suppressed when suppression is
@@ -2982,7 +2964,7 @@
                     Suggestion::Icon::kCardVisa,
                     SuggestionType::kCreditCardEntry),
          CreateSeparator(),
-         PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+         CreateManageCreditCardsSuggestion(
              /*with_gpay_logo=*/false)});
   }
 
@@ -2998,7 +2980,7 @@
                     Suggestion::Icon::kCardMasterCard,
                     SuggestionType::kCreditCardEntry),
          CreateSeparator(),
-         PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+         CreateManageCreditCardsSuggestion(
              /*with_gpay_logo=*/false)});
   }
 
@@ -3014,7 +2996,7 @@
                     Suggestion::Icon::kCardVisa,
                     SuggestionType::kCreditCardEntry),
          CreateSeparator(),
-         PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+         CreateManageCreditCardsSuggestion(
              /*with_gpay_logo=*/false)});
   }
 
@@ -3031,7 +3013,7 @@
                     Suggestion::Icon::kCardAmericanExpress,
                     SuggestionType::kCreditCardEntry),
          CreateSeparator(),
-         PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+         CreateManageCreditCardsSuggestion(
              /*with_gpay_logo=*/false)});
   }
 }
@@ -3079,7 +3061,7 @@
   external_delegate()->CheckSuggestions(
       form.fields()[1].global_id(),
       {GetCardSuggestion(kAmericanExpressCard), CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+       CreateManageCreditCardsSuggestion(
            /*with_gpay_logo=*/false)});
 
   // Query by cardholder name field.
@@ -3093,7 +3075,7 @@
                   Suggestion::Icon::kCardAmericanExpress,
                   SuggestionType::kCreditCardEntry),
        CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+       CreateManageCreditCardsSuggestion(
            /*with_gpay_logo=*/false)});
 }
 
@@ -3113,8 +3095,7 @@
                   SuggestionType::kAddressEntry),
        Suggestion("Elvis", "3734 Elvis Presley Blvd.", kAddressEntryIcon,
                   SuggestionType::kAddressEntry),
-       CreateSeparator(),
-       AddressSuggestionGenerator::CreateManageAddressesEntry()});
+       CreateSeparator(), CreateManageAddressesSuggestion()});
 
   FormFieldData& field = test_api(form).fields()[first_credit_card_field + 1];
   field = CreateTestFormField("Card Number", "cardnumber", "",
@@ -3123,11 +3104,10 @@
 
   // Test that we sent the credit card suggestions to the external delegate.
   external_delegate()->CheckSuggestions(
-      field.global_id(),
-      {GetCardSuggestion(kVisaCard), GetCardSuggestion(kMasterCard),
-       CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
-           /*with_gpay_logo=*/false)});
+      field.global_id(), {GetCardSuggestion(kVisaCard),
+                          GetCardSuggestion(kMasterCard), CreateSeparator(),
+                          CreateManageCreditCardsSuggestion(
+                              /*with_gpay_logo=*/false)});
 }
 
 // Test that for non-https forms with both address and credit card fields, we
@@ -3601,11 +3581,10 @@
                   SuggestionType::kAddressEntry),
        Suggestion("Elvis", "3734 Elvis Presley Blvd.", kAddressEntryIcon,
                   SuggestionType::kAddressEntry),
-       CreateSeparator(),
-       AddressSuggestionGenerator::CreateManageAddressesEntry()});
+       CreateSeparator(), CreateManageAddressesSuggestion()});
 }
 
-// The method `AddressSuggestionGenerator::GetPrefixMatchedProfiles` prevents
+// The method `GetPrefixMatchedProfiles` prevents
 // that Android users see values that would override already filled fields
 // due to the narrow surface and a missing preview.
 #if !BUILDFLAG(IS_ANDROID)
@@ -3633,7 +3612,7 @@
       {Suggestion("Elvis", "3734 Elvis Presley Blvd.", kAddressEntryIcon,
                   SuggestionType::kAddressEntry),
        CreateSeparator(), CreateUndoOrClearFormSuggestion(),
-       AddressSuggestionGenerator::CreateManageAddressesEntry()});
+       CreateManageAddressesSuggestion()});
 }
 #endif
 
@@ -3680,8 +3659,7 @@
       form.fields()[2].global_id(),
       {Suggestion("test@example.com", "Natty Bumppo", Suggestion::Icon::kEmail,
                   SuggestionType::kAddressEntry),
-       CreateSeparator(),
-       AddressSuggestionGenerator::CreateManageAddressesEntry()});
+       CreateSeparator(), CreateManageAddressesSuggestion()});
 }
 
 // Tests that when focusing on an autofilled field, the user gets field-by-field
@@ -3713,7 +3691,7 @@
                   Suggestion::Icon::kNoIcon,
                   SuggestionType::kAddressFieldByFieldFilling),
        CreateSeparator(), CreateUndoOrClearFormSuggestion(),
-       AddressSuggestionGenerator::CreateManageAddressesEntry()});
+       CreateManageAddressesSuggestion()});
 }
 
 // Tests that fields with unrecognized autocomplete attribute don't contribute
@@ -5823,7 +5801,7 @@
   external_delegate()->CheckSuggestions(
       form.fields()[3].global_id(),
       {GetCardSuggestion(kVisaCard), CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+       CreateManageCreditCardsSuggestion(
            /*with_gpay_logo=*/false)});
 }
 
@@ -5839,16 +5817,19 @@
   form.set_url(GURL("https://myform.com/form.html"));
   form.set_action(GURL("https://myform.com/submit.html"));
 
-  struct {
+  struct TestField {
     const char* label;
     const char* name;
     const char* value;
     FieldType expected_field_type;
-  } test_fields[] = {
-      {"Card number", "1", "4234-5678-9012-3456", CREDIT_CARD_NUMBER},
-      {"Card verification code", "2", "123", CREDIT_CARD_VERIFICATION_CODE},
-      {"expiration date", "3", "04/2020", CREDIT_CARD_EXP_4_DIGIT_YEAR},
   };
+  constexpr auto test_fields = std::to_array<TestField>({
+      TestField{"Card number", "1", "4234-5678-9012-3456", CREDIT_CARD_NUMBER},
+      TestField{"Card verification code", "2", "123",
+                CREDIT_CARD_VERIFICATION_CODE},
+      TestField{"expiration date", "3", "04/2020",
+                CREDIT_CARD_EXP_4_DIGIT_YEAR},
+  });
 
   for (const auto& test_field : test_fields) {
     test_api(form).fields().push_back(
@@ -5860,8 +5841,8 @@
   FormSubmitted(form);
 
   EXPECT_EQ(form.fields().size(), form_seen_by_ahm.fields().size());
-  ASSERT_EQ(std::size(test_fields), form_seen_by_ahm.fields().size());
-  for (size_t i = 0; i < std::size(test_fields); ++i) {
+  ASSERT_EQ(test_fields.size(), form_seen_by_ahm.fields().size());
+  for (size_t i = 0; i < test_fields.size(); ++i) {
     EXPECT_EQ(
         form_seen_by_ahm.fields()[i].should_autocomplete(),
         test_fields[i].expected_field_type != CREDIT_CARD_VERIFICATION_CODE);
@@ -6157,7 +6138,7 @@
       form.fields()[1].global_id(),
       {expected_virtual_card_number_suggestion,
        expected_credit_card_number_suggestion, CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+       CreateManageCreditCardsSuggestion(
            /*with_gpay_logo=*/true)});
 
   // Non card number field (cardholder name field).
@@ -6173,7 +6154,7 @@
       form.fields()[0].global_id(),
       {expected_virtual_card_name_suggestion,
        expected_credit_card_name_suggestion, CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+       CreateManageCreditCardsSuggestion(
            /*with_gpay_logo=*/true)});
 }
 
@@ -6216,7 +6197,7 @@
       form.fields()[1].global_id(),
       {virtual_card_number_suggestion, credit_card_number_suggestion,
        CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+       CreateManageCreditCardsSuggestion(
            /*with_gpay_logo=*/true)});
 
   // Non card number field (cardholder name field).
@@ -6232,7 +6213,7 @@
       form.fields()[0].global_id(),
       {virtual_card_name_suggestion, credit_card_name_suggestion,
        CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+       CreateManageCreditCardsSuggestion(
            /*with_gpay_logo=*/true)});
 }
 
@@ -7015,7 +6996,8 @@
 // submission.
 TEST_F(BrowserAutofillManagerTest, AutocompleteMetrics) {
   // `kAutocompleteValues` corresponds to empty, valid, garbage and off.
-  constexpr const char* kAutocompleteValues[]{"", "name", "asdf", "off"};
+  constexpr auto kAutocompleteValues =
+      std::to_array<const char*>({"", "name", "asdf", "off"});
   // The 4 possible combinations of heuristic and server type status:
   // - Neither a fillable heuristic type nor a fillable server type.
   // - Only a fillable server type.
@@ -7023,10 +7005,11 @@
   // - Both a fillable heuristic type and a fillable server type.
   // NO_SERVER_DATA and UNKNOWN_TYPE are both unfillable types, but
   // NO_SERVER_DATA is ignored in the PredictionCollisionType metric.
-  constexpr FieldType kTypeClasses[][2]{{UNKNOWN_TYPE, NO_SERVER_DATA},
-                                        {UNKNOWN_TYPE, EMAIL_ADDRESS},
-                                        {ADDRESS_HOME_COUNTRY, UNKNOWN_TYPE},
-                                        {ADDRESS_HOME_COUNTRY, EMAIL_ADDRESS}};
+  constexpr auto kTypeClasses = std::to_array<std::array<FieldType, 2>>(
+      {{UNKNOWN_TYPE, NO_SERVER_DATA},
+       {UNKNOWN_TYPE, EMAIL_ADDRESS},
+       {ADDRESS_HOME_COUNTRY, UNKNOWN_TYPE},
+       {ADDRESS_HOME_COUNTRY, EMAIL_ADDRESS}});
 
   // Create a form with one field per kAutofillValue x kTypeClass combination.
   FormData form;
@@ -7380,8 +7363,7 @@
        Suggestion("3734 Elvis Presley Blvd., Apt. 10",
                   "3734 Elvis Presley Blvd.", kAddressEntryIcon,
                   SuggestionType::kAddressEntry),
-       CreateSeparator(),
-       AddressSuggestionGenerator::CreateManageAddressesEntry()});
+       CreateSeparator(), CreateManageAddressesSuggestion()});
 }
 
 // Tests that Compose suggestions are queried if the trigger source indicates
@@ -7694,7 +7676,7 @@
       form.fields()[1].global_id(),
       {GetCardSuggestion(kAmericanExpressCard, expected_nickname_),
        CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+       CreateManageCreditCardsSuggestion(
            /*with_gpay_logo=*/true)});
 }
 
@@ -7728,7 +7710,7 @@
       {GetCardSuggestion(kAmericanExpressCard, local_nickname_),
        GetCardSuggestion(kAmericanExpressCard, server_nickname_),
        CreateSeparator(),
-       PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
+       CreateManageCreditCardsSuggestion(
            /*with_gpay_logo=*/false)});
 }
 
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc
index a11cf87..193f11372 100644
--- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc
+++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc
@@ -2,6 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#ifdef UNSAFE_BUFFERS_BUILD
+// TODO(crbug.com/341324165): Fix and remove.
+#pragma allow_unsafe_buffers
+#endif
+
 #include "components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.h"
 
 #include <algorithm>
diff --git a/components/autofill/core/browser/data_model/autofill_profile.cc b/components/autofill/core/browser/data_model/autofill_profile.cc
index 10b0f36..9d21cc3 100644
--- a/components/autofill/core/browser/data_model/autofill_profile.cc
+++ b/components/autofill/core/browser/data_model/autofill_profile.cc
@@ -263,8 +263,8 @@
   // `NAME_FULL` or `PHONE_HOME_WHOLE_NUMBER` in the list of distinguishing
   // fields as a last-ditch fallback. This allows us to distinguish between
   // profiles that are identical except for the name or phone number.
-  // TODO(b/320475288): Clean up this special case. It might be possible to just
-  // append `PHONE_HOME_WHOLE_NUMBER` at the end.
+  // TODO(crbug.com/320475288): Clean up this special case. It might be possible
+  // to just append `PHONE_HOME_WHOLE_NUMBER` at the end.
   for (FieldType excluded_field : excluded_fields) {
     FieldType effective_excluded_type =
         GetStorableTypeCollapsingGroupsForPartialType(excluded_field);
diff --git a/components/autofill/core/browser/data_model/autofill_profile.h b/components/autofill/core/browser/data_model/autofill_profile.h
index 6afb379..7412b9f 100644
--- a/components/autofill/core/browser/data_model/autofill_profile.h
+++ b/components/autofill/core/browser/data_model/autofill_profile.h
@@ -56,8 +56,8 @@
   // list of profile labels. Note that the call to generate labels can specify a
   // custom set of fields, in which case such set would be used instead of this
   // one.
-  // TODO(b/40285811): Change this into a FieldTypeSet once the priority is not
-  // decided by the order of these entries anymore.
+  // TODO(crbug.com/40285811): Change this into a FieldTypeSet once the priority
+  // is not decided by the order of these entries anymore.
   static constexpr auto kDefaultDistinguishingFieldsForLabels =
       std::to_array<FieldType>(
           {NAME_FULL, ADDRESS_HOME_LINE1, ADDRESS_HOME_LINE2,
@@ -215,7 +215,7 @@
   // from it minus those in `excluded_fields`. Otherwise, the label fields are
   // drawn from a default set. Each label includes at least
   // `minimal_fields_shown` fields, if possible.
-  // TODO(b/40285811): Make `suggested_fields` non-optional.
+  // TODO(crbug.com/40285811): Make `suggested_fields` non-optional.
   static void CreateInferredLabels(
       const std::vector<raw_ptr<const AutofillProfile, VectorExperimental>>&
           profiles,
diff --git a/components/autofill/core/browser/data_model/autofill_profile_comparator.h b/components/autofill/core/browser/data_model/autofill_profile_comparator.h
index 818bd6d..f333cd8 100644
--- a/components/autofill/core/browser/data_model/autofill_profile_comparator.h
+++ b/components/autofill/core/browser/data_model/autofill_profile_comparator.h
@@ -32,7 +32,7 @@
 // The values corresponding to those types are visible in the settings.
 // TODO(crbug.com/40266693): Landmark, between-street and admin-level2 are in
 // progress to be included in the settings.
-// TODO(b/40275657): This should depend on the country.
+// TODO(crbug.com/40275657): This should depend on the country.
 FieldTypeSet GetUserVisibleTypes();
 
 // A utility class to assist in the comparison of AutofillProfile data.
diff --git a/components/autofill/core/browser/field_filling_payments_util.cc b/components/autofill/core/browser/field_filling_payments_util.cc
index 72293e5..7a8ee38 100644
--- a/components/autofill/core/browser/field_filling_payments_util.cc
+++ b/components/autofill/core/browser/field_filling_payments_util.cc
@@ -514,8 +514,8 @@
         // case as only finding 1 fillable credit card field is needed.
         base::flat_map<FieldType, size_t> type_count;
 
-        // TODO(b/328478565): Cover cases where filling is skipped due to the
-        // iframe security policy.
+        // TODO(crbug.com/328478565): Cover cases where filling is skipped due
+        // to the iframe security policy.
         return FormFiller::GetFieldFillingSkipReason(
                    *field, autofill_field, trigger_autofill_field, type_count,
                    std::nullopt) == FieldFillingSkipReason::kNotSkipped;
diff --git a/components/autofill/core/browser/field_types.h b/components/autofill/core/browser/field_types.h
index 0054bdc..13f8b08 100644
--- a/components/autofill/core/browser/field_types.h
+++ b/components/autofill/core/browser/field_types.h
@@ -444,7 +444,8 @@
   // fields between single username and password forms.
   // Will be used to rollout new predictions based on new votes of Username
   // First Flow with intermediate values.
-  // TODO(b/294195764): Deprecate after fully rolling out new predictions.
+  // TODO(crbug.com/294195764): Deprecate after fully rolling out new
+  // predictions.
   SINGLE_USERNAME_WITH_INTERMEDIATE_VALUES = 160,
 
   // SERVER_RESPONSE_PENDING is not exposed as an enum value to prevent
diff --git a/components/autofill/core/browser/form_filler.cc b/components/autofill/core/browser/form_filler.cc
index b1d482d..0ae78f3 100644
--- a/components/autofill/core/browser/form_filler.cc
+++ b/components/autofill/core/browser/form_filler.cc
@@ -183,8 +183,8 @@
   // is empty and its initial value (= cached value) was empty as well. A
   // similar check is done in ForEachMatchingFormFieldCommon(), which
   // frequently has false negatives.
-  // TODO(b/40227496): 'autofill_field.value' should be the initial value of
-  // the field. `form_field.value` should be the current value.
+  // TODO(crbug.com/40227496): 'autofill_field.value' should be the initial
+  // value of the field. `form_field.value` should be the current value.
   if ((field.properties_mask() & kUserTyped) &&
       (!field.value().empty() || !autofill_field.value().empty()) &&
       !is_trigger_field) {
@@ -248,8 +248,8 @@
   // that this check happens after the `kFieldTypeUnrelated` check.
 
   // Don't fill meaningfully pre-filled fields but overwrite placeholders.
-  // TODO(b/40227496): 'autofill_field.value' should be the initial value of
-  // the field.
+  // TODO(crbug.com/40227496): 'autofill_field.value' should be the initial
+  // value of the field.
   if (!is_trigger_field && !autofill_field.IsSelectOrSelectListElement() &&
       !autofill_field.value().empty() &&
       (IsNotAPlaceholder(autofill_field) ||
diff --git a/components/autofill/core/browser/form_filler.h b/components/autofill/core/browser/form_filler.h
index 2ceac74..e48b378a 100644
--- a/components/autofill/core/browser/form_filler.h
+++ b/components/autofill/core/browser/form_filler.h
@@ -241,7 +241,7 @@
     DenseSet<FieldTypeGroup> type_groups_originally_filled;
     // If populated, this map determines which values will be filled into a
     // field (it does not matter whether the field already contains a value).
-    // TODO(b/40947225): Investigate removing when
+    // TODO(crbug.com/40947225): Investigate removing when
     // `AutofillFixCachingOnJavaScriptChanges` launches.
     std::map<FieldGlobalId, std::u16string> forced_fill_values;
     // The form filled in the first attempt for filling. Used to check whether
diff --git a/components/autofill/core/browser/form_filler_unittest.cc b/components/autofill/core/browser/form_filler_unittest.cc
index a1760618..25d8821d 100644
--- a/components/autofill/core/browser/form_filler_unittest.cc
+++ b/components/autofill/core/browser/form_filler_unittest.cc
@@ -293,7 +293,7 @@
   test::AutofillUnitTestEnvironment autofill_test_environment_;
   NiceMock<MockAutofillClient> autofill_client_;
   NiceMock<MockAutofillDriver> autofill_driver_{&autofill_client_};
-  // TODO(b/41490871): Replace with FormFiller.
+  // TODO(crbug.com/41490871): Replace with FormFiller.
   std::unique_ptr<TestBrowserAutofillManager> browser_autofill_manager_;
 };
 
@@ -995,7 +995,7 @@
   std::vector<FormFieldData> filled_fields =
       FillAutofillFormData(form, form.fields()[0], &profile).fields();
   ASSERT_EQ(filled_fields.size(), 5u);
-  // TODO(b/40264633): Replace with GetInfo.
+  // TODO(crbug.com/40264633): Replace with GetInfo.
   EXPECT_THAT(filled_fields[0],
               AutofilledWith(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)));
   EXPECT_FALSE(filled_fields[1].is_autofilled());
@@ -1630,7 +1630,7 @@
               AutofilledWith(profile.GetInfo(ADDRESS_HOME_LINE1, kAppLocale)));
   EXPECT_THAT(later_filled_fields[2],
               AutofilledWith(profile2.GetInfo(ADDRESS_HOME_ZIP, kAppLocale)));
-  // TODO(b/40264633): Replace with GetInfo.
+  // TODO(crbug.com/40264633): Replace with GetInfo.
   EXPECT_THAT(later_filled_fields[3],
               AutofilledWith(profile2.GetRawInfo(ADDRESS_HOME_COUNTRY)));
 }
diff --git a/components/autofill/core/browser/form_parsing/address_field_parser.cc b/components/autofill/core/browser/form_parsing/address_field_parser.cc
index 6ff9527..059c9fa 100644
--- a/components/autofill/core/browser/form_parsing/address_field_parser.cc
+++ b/components/autofill/core/browser/form_parsing/address_field_parser.cc
@@ -143,10 +143,8 @@
     // Ignore "Address Lookup" field. http://crbug.com/427622
     if (ParseField(context, scanner, kAddressLookupRe, address_patterns,
                    nullptr, "kAddressLookupRe") ||
-        // This pattern fully migrated to the MatchPattern mechanism. There
-        // is no regular expression in autofill_regex_constants.h anymore.
-        ParseField(context, scanner, kNoLegacyPattern, address_ignore_patterns,
-                   nullptr, "kAddressNameIgnoreRe")) {
+        ParseField(context, scanner, u"", address_ignore_patterns, nullptr,
+                   "kAddressNameIgnoreRe")) {
       continue;
       // Ignore email addresses.
     } else if (ParseFieldSpecifics(
diff --git a/components/autofill/core/browser/form_parsing/form_field_parser.cc b/components/autofill/core/browser/form_parsing/form_field_parser.cc
index bfe3294c..2efecd46 100644
--- a/components/autofill/core/browser/form_parsing/form_field_parser.cc
+++ b/components/autofill/core/browser/form_parsing/form_field_parser.cc
@@ -486,16 +486,8 @@
     raw_ptr<AutofillField>* match,
     const char* regex_name,
     MatchParams (*match_pattern_projection)(const MatchParams&)) {
-  return (base::FeatureList::IsEnabled(
-              features::kAutofillParsingPatternProvider) ||
-          // Some patterns may not exist as an old-school regex because they
-          // require negative matching.
-          pattern == kNoLegacyPattern)
-             ? ParseFieldSpecificsWithNewPatterns(context, scanner, patterns,
-                                                  match, regex_name,
-                                                  match_pattern_projection)
-             : ParseFieldSpecificsWithLegacyPattern(
-                   context, scanner, pattern, match_type, match, regex_name);
+  return ParseFieldSpecificsWithNewPatterns(
+      context, scanner, patterns, match, regex_name, match_pattern_projection);
 }
 
 // static
diff --git a/components/autofill/core/browser/form_parsing/form_field_parser.h b/components/autofill/core/browser/form_parsing/form_field_parser.h
index 962f08f..d2c8645 100644
--- a/components/autofill/core/browser/form_parsing/form_field_parser.h
+++ b/components/autofill/core/browser/form_parsing/form_field_parser.h
@@ -33,11 +33,6 @@
 class AutofillScanner;
 class LogManager;
 
-// When kNoLegacyPattern is passed to ParseField/ParseFieldSpecifics as the
-// pattern, the functions always default to the MatchPatternRefs, regardless
-// of the status of features::kAutofillParsingPatternProvider.
-inline constexpr std::u16string_view kNoLegacyPattern = u"no-legacy-pattern";
-
 // LRU cache to prevent the repetitive evaluation of identical regular
 // expressions (`pattern`) on identical `input` strings.
 class RegexMatchesCache {
@@ -235,9 +230,7 @@
 
   // Attempts to parse a form field with the given pattern.  Returns true on
   // success and fills `match` with a pointer to the field.
-  // When `kNoLegacyPattern` is passed as the `pattern`, the functions always
-  // default to `patterns`, regardless of the status of
-  // `features::kAutofillParsingPatternProvider`.
+  // TODO(crbug.com/40280853): The `pattern` parameter is unused. Remove.
   static bool ParseField(ParsingContext& context,
                          AutofillScanner* scanner,
                          std::u16string_view pattern,
@@ -245,12 +238,11 @@
                          raw_ptr<AutofillField>* match,
                          const char* regex_name = "");
 
-  // When `kNoLegacyPattern` is passed as the `pattern`, the functions always
-  // default to `patterns`, regardless of the status of
-  // `features::kAutofillParsingPatternProvider`.
   // If a `match_pattern_projection` is defined, it is applied to the pattern's
   // MatchParams after dereferencing the `MatchPatternRef`s. Note that this is
   // only relevant with pattern provider.
+  // TODO(crbug.com/40280853): The `pattern` and `match_type` parameters are
+  // unused. Remove them.
   static bool ParseFieldSpecifics(
       ParsingContext& context,
       AutofillScanner* scanner,
diff --git a/components/autofill/core/browser/form_parsing/internal_resources b/components/autofill/core/browser/form_parsing/internal_resources
index d26e0d57..5da272c 160000
--- a/components/autofill/core/browser/form_parsing/internal_resources
+++ b/components/autofill/core/browser/form_parsing/internal_resources
@@ -1 +1 @@
-Subproject commit d26e0d57f43c90fc762e58aef8f879fb02f28a68
+Subproject commit 5da272c05cbe43d762d7c4523e23f4e532564b8c
diff --git a/components/autofill/core/browser/form_parsing/name_field_parser.cc b/components/autofill/core/browser/form_parsing/name_field_parser.cc
index 4daff66..126f0ef 100644
--- a/components/autofill/core/browser/form_parsing/name_field_parser.cc
+++ b/components/autofill/core/browser/form_parsing/name_field_parser.cc
@@ -162,10 +162,7 @@
       ParseFieldSpecifics(context, scanner, kNameIgnoredRe,
                           kNameIgnoredMatchParams, name_ignored_patterns,
                           nullptr, "kNameIgnoredRe") ||
-      // This pattern fully migrated to the MatchPattern mechanism. There
-      // is no regular expression in autofill_regex_constants.h anymore.
-      ParseField(context, scanner, kNoLegacyPattern,
-                 address_name_ignored_patterns, nullptr,
+      ParseField(context, scanner, u"", address_name_ignored_patterns, nullptr,
                  "kAddressNameIgnoredRe");
   scanner->Rewind();
   if (should_ignore) {
@@ -229,11 +226,8 @@
   while (!scanner->IsEnd()) {
     // Skip over address label fields, which can have misleading names
     // e.g. "title" or "name".
-    // This pattern fully migrated to the MatchPattern mechanism. There is no
-    // regular expression in autofill_regex_constants.h anymore.
-    if (ParseField(context, scanner, kNoLegacyPattern,
-                   address_name_ignored_patterns, nullptr,
-                   "kAddressNameIgnoredRe")) {
+    if (ParseField(context, scanner, u"", address_name_ignored_patterns,
+                   nullptr, "kAddressNameIgnoredRe")) {
       continue;
     }
 
@@ -334,10 +328,7 @@
       ParseFieldSpecifics(context, scanner, kNameIgnoredRe,
                           kNameIgnoredMatchParams, name_ignored_patterns,
                           nullptr, "kNameIgnoredRe") ||
-      // This pattern fully migrated to the MatchPattern mechanism. There is no
-      // regular expression in autofill_regex_constants.h anymore.
-      ParseField(context, scanner, kNoLegacyPattern,
-                 address_name_ignored_patterns, nullptr,
+      ParseField(context, scanner, u"", address_name_ignored_patterns, nullptr,
                  "kAddressNameIgnoredRe");
   scanner->Rewind();
 
@@ -430,11 +421,8 @@
   while (!scanner->IsEnd()) {
     // Skip over address label fields, which can have misleading names
     // e.g. "title" or "name".
-    // This pattern fully migrated to the MatchPattern mechanism. There is no
-    // regular expression in autofill_regex_constants.h anymore.
-    if (ParseField(context, scanner, kNoLegacyPattern,
-                   address_name_ignored_patterns, nullptr,
-                   "kAddressNameIgnoredRe")) {
+    if (ParseField(context, scanner, u"", address_name_ignored_patterns,
+                   nullptr, "kAddressNameIgnoredRe")) {
       continue;
     }
 
diff --git a/components/autofill/core/browser/form_parsing/parsing_test_utils.cc b/components/autofill/core/browser/form_parsing/parsing_test_utils.cc
index 2583f3ec7..dcca57f4 100644
--- a/components/autofill/core/browser/form_parsing/parsing_test_utils.cc
+++ b/components/autofill/core/browser/form_parsing/parsing_test_utils.cc
@@ -18,34 +18,27 @@
 
 std::vector<PatternProviderFeatureState> PatternProviderFeatureState::All() {
   return {
-    {.enable = false, .active_source = nullptr},
 #if BUILDFLAG(USE_INTERNAL_AUTOFILL_PATTERNS)
-        {.enable = true, .active_source = "default"},
-        {.enable = true, .active_source = "experimental"},
-        {.enable = true, .active_source = "nextgen"},
+      {.active_source = "default"},
+      {.active_source = "experimental"},
+      {.active_source = "nextgen"},
 #else
       // Builds without Autofill internal patterns default to the legacy
       // patterns. The `active_source` feature parameter is in fact not read
       // in this case.
-      {.enable = true, .active_source = "legacy"},
+      {.active_source = "legacy"},
 #endif
   };
 }
 
 FormFieldParserTestBase::FormFieldParserTestBase(
     PatternProviderFeatureState pattern_provider_feature_state) {
-  std::vector<base::test::FeatureRefAndParams> enabled;
-  std::vector<base::test::FeatureRef> disabled;
-  if (pattern_provider_feature_state.enable) {
-    enabled.emplace_back(
-        features::kAutofillParsingPatternProvider,
-        base::FieldTrialParams{
-            {features::kAutofillParsingPatternActiveSource.name,
-             pattern_provider_feature_state.active_source}});
-  } else {
-    disabled.push_back(features::kAutofillParsingPatternProvider);
-  }
-  scoped_feature_list_.InitWithFeaturesAndParameters(enabled, disabled);
+  CHECK_NE(pattern_provider_feature_state.active_source, nullptr);
+  scoped_feature_list_.InitAndEnableFeatureWithParameters(
+      features::kAutofillParsingPatternProvider,
+      base::FieldTrialParams{
+          {features::kAutofillParsingPatternActiveSource.name,
+           pattern_provider_feature_state.active_source}});
 }
 
 FormFieldParserTestBase::~FormFieldParserTestBase() = default;
diff --git a/components/autofill/core/browser/form_parsing/parsing_test_utils.h b/components/autofill/core/browser/form_parsing/parsing_test_utils.h
index 2af6106..1ff085120 100644
--- a/components/autofill/core/browser/form_parsing/parsing_test_utils.h
+++ b/components/autofill/core/browser/form_parsing/parsing_test_utils.h
@@ -30,14 +30,12 @@
   kMaxValue = kNotParsed
 };
 
-// Represents the intended state of features::kAutofillParsingPatternProvider.
+// Represents the intended state of
+// features::kAutofillParsingPatternActiveSource.
 struct PatternProviderFeatureState {
   // A list of all available configurations, depending on the build config.
   static std::vector<PatternProviderFeatureState> All();
 
-  // Whether features::kAutofillParsingPatternProvider should be enabled.
-  bool enable = false;
-  // The desired value of features::kAutofillParsingPatternActiveSource.
   const char* active_source = nullptr;
 };
 
diff --git a/components/autofill/core/browser/form_parsing/phone_field_parser_unittest.cc b/components/autofill/core/browser/form_parsing/phone_field_parser_unittest.cc
index 54cbc91..53f36dce 100644
--- a/components/autofill/core/browser/form_parsing/phone_field_parser_unittest.cc
+++ b/components/autofill/core/browser/form_parsing/phone_field_parser_unittest.cc
@@ -39,18 +39,11 @@
     : public testing::TestWithParam<PatternProviderFeatureState> {
  public:
   PhoneFieldParserTest() {
-    std::vector<base::test::FeatureRefAndParams> enabled;
-    std::vector<base::test::FeatureRef> disabled;
-    if (GetParam().enable) {
-      enabled.emplace_back(
-          features::kAutofillParsingPatternProvider,
-          base::FieldTrialParams{
-              {features::kAutofillParsingPatternActiveSource.name,
-               GetParam().active_source}});
-    } else {
-      disabled.push_back(features::kAutofillParsingPatternProvider);
-    }
-    scoped_feature_list_.InitWithFeaturesAndParameters(enabled, disabled);
+    scoped_feature_list_.InitAndEnableFeatureWithParameters(
+        features::kAutofillParsingPatternProvider,
+        base::FieldTrialParams{
+            {features::kAutofillParsingPatternActiveSource.name,
+             GetParam().active_source}});
   }
 
   PhoneFieldParserTest(const PhoneFieldParserTest&) = delete;
diff --git a/components/autofill/core/browser/form_parsing/resources/legacy_regex_patterns.json b/components/autofill/core/browser/form_parsing/resources/legacy_regex_patterns.json
index 8f982f64..b5a2eb8 100644
--- a/components/autofill/core/browser/form_parsing/resources/legacy_regex_patterns.json
+++ b/components/autofill/core/browser/form_parsing/resources/legacy_regex_patterns.json
@@ -853,6 +853,15 @@
         "form_control_types": ["INPUT_TEXT", "SELECT_ONE", "SELECT_LIST", "INPUT_SEARCH"]
       }
     ],
+    "it": [
+      {
+        "positive_pattern": "\\bpaese\\b|\\bnazione\\b",
+        "positive_score": 1.1,
+        "negative_pattern": null,
+        "match_field_attributes": ["LABEL", "NAME"],
+        "form_control_types": ["INPUT_TEXT", "SELECT_ONE", "SELECT_LIST", "INPUT_SEARCH"]
+      }
+    ],
     "pl": [
       {
         // "(?<!o)" exists to prevent "okrajov" and "okraj" from matching.
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index a3f72bff..fa29fb7 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -260,7 +260,8 @@
     } else {
       // Run heuristics.
       context.pattern_source = *pattern_source;
-      ParseFieldTypesWithPatterns(context);
+      AssignBestFieldTypes(ParseFieldTypesWithPatterns(context),
+                           *pattern_source);
     }
   }
 }
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h
index 69705b4..7fc0829 100644
--- a/components/autofill/core/browser/form_structure.h
+++ b/components/autofill/core/browser/form_structure.h
@@ -387,7 +387,8 @@
   // Classifies each field using the regular expressions. The classifications
   // are returned, but not assigned to the `fields_` yet. Use
   // `AssignBestFieldTypes()` to do so.
-  FieldCandidatesMap ParseFieldTypesWithPatterns(ParsingContext& context) const;
+  [[nodiscard]] FieldCandidatesMap ParseFieldTypesWithPatterns(
+      ParsingContext& context) const;
 
   // Assigns the best heuristic types from the `field_type_map` to the heuristic
   // types of the corresponding fields for the `pattern_source`.
diff --git a/components/autofill/core/browser/form_structure_rationalization_engine.cc b/components/autofill/core/browser/form_structure_rationalization_engine.cc
index 3432e5ac..b17e292 100644
--- a/components/autofill/core/browser/form_structure_rationalization_engine.cc
+++ b/components/autofill/core/browser/form_structure_rationalization_engine.cc
@@ -351,7 +351,6 @@
                     .SetCountryList({GeoIpCountryCode("DE")})
                     .SetFeature(&features::kAutofillUseDEAddressModel)
                     .Build())
-
             .SetTriggerField(FieldCondition{
                 .possible_overall_types = FieldTypeSet{ADDRESS_HOME_OVERFLOW}})
             .SetOtherFieldConditions({
@@ -380,7 +379,6 @@
                     .SetCountryList({GeoIpCountryCode("PL")})
                     .SetFeature(&features::kAutofillUsePLAddressModel)
                     .Build())
-
             .SetTriggerField(
                 FieldCondition{.possible_overall_types =
                                    FieldTypeSet{ADDRESS_HOME_HOUSE_NUMBER}})
@@ -414,7 +412,6 @@
                     .SetCountryList({GeoIpCountryCode("PL")})
                     .SetFeature(&features::kAutofillUsePLAddressModel)
                     .Build())
-
             .SetTriggerField(FieldCondition{
                 .possible_overall_types = FieldTypeSet{ADDRESS_HOME_LINE1}})
             .SetFieldsWithConditionsDoNotExist({
@@ -429,6 +426,51 @@
                 },
             })
             .Build(),
+        RationalizationRuleBuilder()
+            .SetRuleName("Fix consecutive ADDRESS_HOME_LINE1 for IT")
+            .SetEnvironmentCondition(
+                EnvironmentConditionBuilder()
+                    .SetCountryList({GeoIpCountryCode("IT")})
+                    .SetFeature(&features::kAutofillUseITAddressModel)
+                    .Build())
+            .SetTriggerField(FieldCondition{
+                .possible_overall_types = FieldTypeSet{ADDRESS_HOME_LINE1}})
+            .SetOtherFieldConditions({
+                FieldCondition{
+                    .location = FieldLocation::kNextClassifiedSuccessor,
+                    .possible_overall_types = FieldTypeSet{ADDRESS_HOME_LINE1},
+                },
+            })
+            .SetActions({
+                SetTypeAction{
+                    .target = FieldLocation::kNextClassifiedSuccessor,
+                    .set_overall_type = ADDRESS_HOME_LINE2,
+                },
+            })
+            .Build(),
+        RationalizationRuleBuilder()
+            .SetRuleName("Fix ADDRESS_HOME_LINE1 without following "
+                         "ADDRESS_HOME_LINE2 for IT")
+            .SetEnvironmentCondition(
+                EnvironmentConditionBuilder()
+                    .SetCountryList({GeoIpCountryCode("IT")})
+                    .SetFeature(&features::kAutofillUseITAddressModel)
+                    .Build())
+            .SetTriggerField(FieldCondition{
+                .possible_overall_types = FieldTypeSet{ADDRESS_HOME_LINE1}})
+            .SetFieldsWithConditionsDoNotExist({
+                FieldCondition{
+                    .location = FieldLocation::kNextClassifiedSuccessor,
+                    .possible_overall_types =
+                        FieldTypeSet{UNKNOWN_TYPE, ADDRESS_HOME_LINE2}},
+            })
+            .SetActions({
+                SetTypeAction{
+                    .target = FieldLocation::kTriggerField,
+                    .set_overall_type = ADDRESS_HOME_STREET_ADDRESS,
+                },
+            })
+            .Build(),
     });
   };
   static const base::NoDestructor<decltype(create_rules())>
diff --git a/components/autofill/core/browser/form_structure_rationalization_engine_unittest.cc b/components/autofill/core/browser/form_structure_rationalization_engine_unittest.cc
index 474a7f5..c87c105 100644
--- a/components/autofill/core/browser/form_structure_rationalization_engine_unittest.cc
+++ b/components/autofill/core/browser/form_structure_rationalization_engine_unittest.cc
@@ -558,5 +558,59 @@
                           /*changed*/ ADDRESS_HOME_ZIP));
 }
 
+// Verifies that fields classified as ADDRESS_HOME_LINE1 with a following
+// repeated ADDRESS_HOME_LINE1 are reclassified as ADDRESS_HOME_LINE1 and
+// ADDRESS_HOME_LINE2 for IT forms.
+TEST(FormStructureRationalizationEngine, TestITAddressLine1WithAL1Next) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      {kTestFeatureForFormStructureRationalizationEngine,
+       features::kAutofillUseITAddressModel},
+      {});
+
+  std::vector<std::unique_ptr<AutofillField>> fields = CreateFields({
+      {u"Nome", u"nome", NAME_FIRST},
+      {u"Cognome", u"cognome", NAME_LAST},
+      {u"Indirizzo", u"indirizzo", ADDRESS_HOME_LINE1},
+      {u"Indirizzo", u"indirizzo", ADDRESS_HOME_LINE1},
+      {u"Codice postale", u"codice postale", ADDRESS_HOME_ZIP},
+  });
+
+  GeoIpCountryCode kIT = GeoIpCountryCode("IT");
+  ParsingContext kITContext(kIT, LanguageCode("it"), PatternSource::kLegacy);
+  ApplyRationalizationEngineRules(kITContext, fields, nullptr);
+
+  EXPECT_THAT(GetTypes(fields),
+              ElementsAre(NAME_FIRST, NAME_LAST, ADDRESS_HOME_LINE1,
+                          /*changed*/ ADDRESS_HOME_LINE2, ADDRESS_HOME_ZIP));
+}
+
+// Verifies that fields classified as ADDRESS_HOME_LINE1 without a following
+// ADDRESS_HOME_LINE2 are reclassified as ADDRESS_HOME_STREET_ADDRESS for IT
+// forms.
+TEST(FormStructureRationalizationEngine, TestITAddressLine1WithNoNext) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      {kTestFeatureForFormStructureRationalizationEngine,
+       features::kAutofillUseITAddressModel},
+      {});
+
+  std::vector<std::unique_ptr<AutofillField>> fields = CreateFields({
+      {u"Nome", u"nome", NAME_FIRST},
+      {u"Cognome", u"cognome", NAME_LAST},
+      {u"Indirizzo", u"indirizzo", ADDRESS_HOME_LINE1},
+      {u"Codice postale", u"codice postale", ADDRESS_HOME_ZIP},
+  });
+
+  GeoIpCountryCode kIT = GeoIpCountryCode("IT");
+  ParsingContext kITContext(kIT, LanguageCode("it"), PatternSource::kLegacy);
+  ApplyRationalizationEngineRules(kITContext, fields, nullptr);
+
+  EXPECT_THAT(
+      GetTypes(fields),
+      ElementsAre(NAME_FIRST, NAME_LAST,
+                  /*changed*/ ADDRESS_HOME_STREET_ADDRESS, ADDRESS_HOME_ZIP));
+}
+
 }  // namespace
 }  // namespace autofill::rationalization
diff --git a/components/autofill/core/browser/form_structure_sectioning_util.cc b/components/autofill/core/browser/form_structure_sectioning_util.cc
index fc59e776..49df818 100644
--- a/components/autofill/core/browser/form_structure_sectioning_util.cc
+++ b/components/autofill/core/browser/form_structure_sectioning_util.cc
@@ -2,6 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#ifdef UNSAFE_BUFFERS_BUILD
+// TODO(crbug.com/341324165): Fix and remove.
+#pragma allow_unsafe_buffers
+#endif
+
 #include "components/autofill/core/browser/form_structure_sectioning_util.h"
 
 #include <iterator>
diff --git a/components/autofill/core/browser/geo/address_rewriter.cc b/components/autofill/core/browser/geo/address_rewriter.cc
index 96cf98f..c4fe77dd 100644
--- a/components/autofill/core/browser/geo/address_rewriter.cc
+++ b/components/autofill/core/browser/geo/address_rewriter.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO: crbug.com/347137620 - Remove this and spanify to fix the errors.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "components/autofill/core/browser/geo/address_rewriter.h"
 
 #include <memory>
@@ -41,10 +36,13 @@
   int resource_id = 0;
   std::string resource_key = GetMapKey(region);
   for (size_t i = 0; i < kAutofillAddressRewriterResourcesSize; ++i) {
-    if (kAutofillAddressRewriterResources[i].path == resource_key) {
-      resource_id = kAutofillAddressRewriterResources[i].id;
-      break;
-    }
+    // TODO: crbug.com/347651465: GRIT should define std::arrays instead of
+    // c-style arrays.
+    UNSAFE_BUFFERS(
+        if (kAutofillAddressRewriterResources[i].path == resource_key) {
+          resource_id = kAutofillAddressRewriterResources[i].id;
+          break;
+        })
   }
 
   if (!resource_id) {
diff --git a/components/autofill/core/browser/geo/country_data.cc b/components/autofill/core/browser/geo/country_data.cc
index eaa4a46..36dc5f4 100644
--- a/components/autofill/core/browser/geo/country_data.cc
+++ b/components/autofill/core/browser/geo/country_data.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO: crbug.com/347137620 - Remove this and spanify to fix the errors.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "components/autofill/core/browser/geo/country_data.h"
 
 #include <utility>
@@ -32,268 +27,268 @@
 };
 
 // Alias definitions.
-const StaticCountryCodeAliasData kCountryCodeAliases[] = {{"UK", "GB"}};
+constexpr auto kCountryCodeAliases =
+    std::to_array<StaticCountryCodeAliasData>({{"UK", "GB"}});
 
 // Maps country codes to address import requirements. Keep this sorted
 // by country code.
 // This list is comprized of countries appearing in both
 // //third_party/icu/source/data/region/en.txt and
 // //third_party/libaddressinput/src/cpp/src/region_data_constants.cc.
-const StaticCountryAddressImportRequirementsData
-    kCountryAddressImportRequirementsData[] = {
-        {"AC", ADDRESS_REQUIRES_LINE1_CITY},
-        {"AD", ADDRESS_REQUIRES_LINE1},
-        {"AE", ADDRESS_REQUIRES_LINE1_STATE},
-        {"AF", ADDRESS_REQUIRES_LINE1_CITY},
-        {"AG", ADDRESS_REQUIRES_LINE1},
-        {"AI", ADDRESS_REQUIRES_LINE1_CITY},
-        {"AL", ADDRESS_REQUIRES_LINE1_CITY},
-        {"AM", ADDRESS_REQUIRES_LINE1_CITY},
-        {"AO", ADDRESS_REQUIRES_LINE1_CITY},
-        {"AQ", ADDRESS_REQUIRES_LINE1_CITY},
-        {"AR", ADDRESS_REQUIRES_LINE1_CITY},
-        {"AS", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"AT", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"AU", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"AW", ADDRESS_REQUIRES_LINE1_CITY},
-        {"AX", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"AZ", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BA", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BB", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BD", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BE", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"BF", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BG", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BH", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BI", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BJ", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BL", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"BM", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BN", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BO", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BQ", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BR", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"BS", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BT", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BV", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BW", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BY", ADDRESS_REQUIRES_LINE1_CITY},
-        {"BZ", ADDRESS_REQUIRES_LINE1_CITY},
-        {"CA", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"CC", ADDRESS_REQUIRES_LINE1_CITY},
-        {"CD", ADDRESS_REQUIRES_LINE1_CITY},
-        {"CF", ADDRESS_REQUIRES_LINE1_CITY},
-        {"CG", ADDRESS_REQUIRES_LINE1_CITY},
-        {"CH", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"CI", ADDRESS_REQUIRES_LINE1_CITY},
-        {"CK", ADDRESS_REQUIRES_LINE1_CITY},
-        {"CL", ADDRESS_REQUIRES_LINE1_CITY},
-        {"CM", ADDRESS_REQUIRES_LINE1_CITY},
-        {"CN", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"CO", ADDRESS_REQUIRES_LINE1_STATE},
-        {"CR", ADDRESS_REQUIRES_LINE1_STATE},
-        {"CU", ADDRESS_REQUIRES_LINE1_CITY},
-        {"CV", ADDRESS_REQUIRES_LINE1_CITY},
-        {"CW", ADDRESS_REQUIRES_LINE1_CITY},
-        {"CX", ADDRESS_REQUIRES_LINE1_CITY},
-        {"CY", ADDRESS_REQUIRES_LINE1_CITY},
-        {"CZ", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"DE", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"DJ", ADDRESS_REQUIRES_LINE1_CITY},
-        {"DK", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"DM", ADDRESS_REQUIRES_LINE1_CITY},
-        {"DO", ADDRESS_REQUIRES_LINE1_CITY},
-        {"DZ", ADDRESS_REQUIRES_LINE1_CITY},
-        {"EC", ADDRESS_REQUIRES_LINE1_CITY},
-        {"EE", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"EG", ADDRESS_REQUIRES_LINE1_CITY},
-        {"EH", ADDRESS_REQUIRES_LINE1_CITY},
-        {"ER", ADDRESS_REQUIRES_LINE1_CITY},
-        {"ES", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"ET", ADDRESS_REQUIRES_LINE1_CITY},
-        {"FI", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"FJ", ADDRESS_REQUIRES_LINE1_CITY},
-        {"FK", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"FM", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"FO", ADDRESS_REQUIRES_LINE1_CITY},
-        {"FR", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"GA", ADDRESS_REQUIRES_LINE1_CITY},
-        {"GB", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"GD", ADDRESS_REQUIRES_LINE1_CITY},
-        {"GE", ADDRESS_REQUIRES_LINE1_CITY},
-        {"GF", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"GG", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"GH", ADDRESS_REQUIRES_LINE1_CITY},
-        {"GI", ADDRESS_REQUIRES_LINE1},
-        {"GL", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"GM", ADDRESS_REQUIRES_LINE1_CITY},
-        {"GN", ADDRESS_REQUIRES_LINE1_CITY},
-        {"GP", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"GQ", ADDRESS_REQUIRES_LINE1_CITY},
-        {"GR", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"GS", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"GT", ADDRESS_REQUIRES_LINE1_CITY},
-        {"GU", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"GW", ADDRESS_REQUIRES_LINE1_CITY},
-        {"GY", ADDRESS_REQUIRES_LINE1_CITY},
-        {"HK", ADDRESS_REQUIRES_LINE1_STATE},
-        {"HM", ADDRESS_REQUIRES_LINE1_CITY},
-        {"HN", ADDRESS_REQUIRES_LINE1_CITY_STATE},
-        {"HR", ADDRESS_REQUIRES_LINE1_CITY},
-        {"HT", ADDRESS_REQUIRES_LINE1_CITY},
-        {"HU", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"ID", ADDRESS_REQUIRES_LINE1_STATE},
-        {"IE", ADDRESS_REQUIRES_LINE1_CITY},
-        {"IL", ADDRESS_REQUIRES_LINE1_CITY},
-        {"IM", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"IN", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"IO", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"IQ", ADDRESS_REQUIRES_LINE1_CITY_STATE},
-        {"IR", ADDRESS_REQUIRES_LINE1_CITY},
-        {"IS", ADDRESS_REQUIRES_LINE1_CITY},
-        {"IT", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"JE", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"JM", ADDRESS_REQUIRES_LINE1_CITY_STATE},
-        {"JO", ADDRESS_REQUIRES_LINE1_CITY},
-        {"JP", ADDRESS_REQUIRES_LINE1_STATE_ZIP},
-        {"KE", ADDRESS_REQUIRES_LINE1_CITY},
-        {"KG", ADDRESS_REQUIRES_LINE1_CITY},
-        {"KH", ADDRESS_REQUIRES_LINE1_CITY},
-        {"KI", ADDRESS_REQUIRES_LINE1_CITY},
-        {"KM", ADDRESS_REQUIRES_LINE1_CITY},
-        {"KN", ADDRESS_REQUIRES_LINE1_CITY_STATE},
-        {"KP", ADDRESS_REQUIRES_LINE1_CITY},
-        {"KR", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"KW", ADDRESS_REQUIRES_LINE1_CITY},
-        {"KY", ADDRESS_REQUIRES_LINE1_STATE},
-        {"KZ", ADDRESS_REQUIRES_LINE1_CITY},
-        {"LA", ADDRESS_REQUIRES_LINE1_CITY},
-        {"LB", ADDRESS_REQUIRES_LINE1_CITY},
-        {"LC", ADDRESS_REQUIRES_LINE1_CITY},
-        {"LI", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"LK", ADDRESS_REQUIRES_LINE1_CITY},
-        {"LR", ADDRESS_REQUIRES_LINE1_CITY},
-        {"LS", ADDRESS_REQUIRES_LINE1_CITY},
-        {"LT", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"LU", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"LV", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"LY", ADDRESS_REQUIRES_LINE1_CITY},
-        {"MA", ADDRESS_REQUIRES_LINE1_CITY},
-        {"MC", ADDRESS_REQUIRES_LINE1_CITY},
-        {"MD", ADDRESS_REQUIRES_LINE1_CITY},
-        {"ME", ADDRESS_REQUIRES_LINE1_CITY},
-        {"MF", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"MG", ADDRESS_REQUIRES_LINE1_CITY},
-        {"MH", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"MK", ADDRESS_REQUIRES_LINE1_CITY},
-        {"ML", ADDRESS_REQUIRES_LINE1_CITY},
-        {"MM", ADDRESS_REQUIRES_LINE1_CITY},
-        {"MN", ADDRESS_REQUIRES_LINE1_CITY},
-        {"MO", ADDRESS_REQUIRES_LINE1},
-        {"MP", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"MQ", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"MR", ADDRESS_REQUIRES_LINE1_CITY},
-        {"MS", ADDRESS_REQUIRES_LINE1_CITY},
-        {"MT", ADDRESS_REQUIRES_LINE1_CITY},
-        {"MU", ADDRESS_REQUIRES_LINE1_CITY},
-        {"MV", ADDRESS_REQUIRES_LINE1_CITY},
-        {"MW", ADDRESS_REQUIRES_LINE1_CITY},
-        {"MX", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"MY", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"MZ", ADDRESS_REQUIRES_LINE1_CITY},
-        {"NA", ADDRESS_REQUIRES_LINE1_CITY},
-        {"NC", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"NE", ADDRESS_REQUIRES_LINE1_CITY},
-        {"NF", ADDRESS_REQUIRES_LINE1_CITY},
-        {"NG", ADDRESS_REQUIRES_LINE1_CITY},
-        {"NI", ADDRESS_REQUIRES_LINE1_CITY},
-        {"NL", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"NO", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"NP", ADDRESS_REQUIRES_LINE1_CITY},
-        {"NR", ADDRESS_REQUIRES_LINE1_STATE},
-        {"NU", ADDRESS_REQUIRES_LINE1_CITY},
-        {"NZ", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"OM", ADDRESS_REQUIRES_LINE1_CITY},
-        {"PA", ADDRESS_REQUIRES_LINE1_CITY},
-        {"PE", ADDRESS_REQUIRES_LINE1_CITY},
-        {"PF", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"PG", ADDRESS_REQUIRES_LINE1_CITY_STATE},
-        {"PH", ADDRESS_REQUIRES_LINE1_CITY},
-        {"PK", ADDRESS_REQUIRES_LINE1_CITY},
-        {"PL", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"PM", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"PN", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"PR", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"PS", ADDRESS_REQUIRES_LINE1_CITY},
-        {"PT", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"PW", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"PY", ADDRESS_REQUIRES_LINE1_CITY},
-        {"QA", ADDRESS_REQUIRES_LINE1_CITY},
-        {"RE", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"RO", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"RS", ADDRESS_REQUIRES_LINE1_CITY},
-        {"RU", ADDRESS_REQUIRES_LINE1_CITY},
-        {"RW", ADDRESS_REQUIRES_LINE1_CITY},
-        {"SA", ADDRESS_REQUIRES_LINE1_CITY},
-        {"SB", ADDRESS_REQUIRES_LINE1_CITY},
-        {"SC", ADDRESS_REQUIRES_LINE1_CITY},
-        {"SD", ADDRESS_REQUIRES_LINE1_CITY},
-        {"SE", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"SG", ADDRESS_REQUIRES_LINE1_ZIP},
-        {"SH", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"SI", ADDRESS_REQUIRES_LINE1_CITY},
-        {"SJ", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"SK", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"SL", ADDRESS_REQUIRES_LINE1_CITY},
-        {"SM", ADDRESS_REQUIRES_LINE1_ZIP},
-        {"SN", ADDRESS_REQUIRES_LINE1_CITY},
-        {"SO", ADDRESS_REQUIRES_LINE1_CITY_STATE},
-        {"SR", ADDRESS_REQUIRES_LINE1_CITY},
-        {"SS", ADDRESS_REQUIRES_LINE1_CITY},
-        {"ST", ADDRESS_REQUIRES_LINE1_CITY},
-        {"SV", ADDRESS_REQUIRES_LINE1_CITY_STATE},
-        {"SX", ADDRESS_REQUIRES_LINE1_CITY},
-        {"SY", ADDRESS_REQUIRES_LINE1_CITY},
-        {"SZ", ADDRESS_REQUIRES_LINE1_CITY},
-        {"TA", ADDRESS_REQUIRES_LINE1_CITY},
-        {"TC", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"TD", ADDRESS_REQUIRES_LINE1_CITY},
-        {"TF", ADDRESS_REQUIRES_LINE1_CITY},
-        {"TG", ADDRESS_REQUIRES_LINE1_CITY},
-        {"TH", ADDRESS_REQUIRES_LINE1_CITY},
-        {"TJ", ADDRESS_REQUIRES_LINE1_CITY},
-        {"TK", ADDRESS_REQUIRES_LINE1_CITY},
-        {"TL", ADDRESS_REQUIRES_LINE1_CITY},
-        {"TM", ADDRESS_REQUIRES_LINE1_CITY},
-        {"TN", ADDRESS_REQUIRES_LINE1_CITY},
-        {"TO", ADDRESS_REQUIRES_LINE1_CITY},
-        {"TR", ADDRESS_REQUIRES_LINE1_CITY_STATE},
-        {"TT", ADDRESS_REQUIRES_LINE1_CITY},
-        {"TV", ADDRESS_REQUIRES_LINE1_CITY},
-        {"TW", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"TZ", ADDRESS_REQUIRES_LINE1_CITY},
-        {"UA", ADDRESS_REQUIRES_LINE1_CITY},
-        {"UG", ADDRESS_REQUIRES_LINE1_CITY},
-        {"UM", ADDRESS_REQUIRES_LINE1_CITY_STATE},
-        {"US", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"UY", ADDRESS_REQUIRES_LINE1_CITY},
-        {"UZ", ADDRESS_REQUIRES_LINE1_CITY},
-        {"VA", ADDRESS_REQUIRES_LINE1_CITY},
-        {"VC", ADDRESS_REQUIRES_LINE1_CITY},
-        {"VE", ADDRESS_REQUIRES_LINE1_CITY_STATE},
-        {"VG", ADDRESS_REQUIRES_LINE1},
-        {"VI", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
-        {"VN", ADDRESS_REQUIRES_LINE1_CITY},
-        {"VU", ADDRESS_REQUIRES_LINE1_CITY},
-        {"WF", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"WS", ADDRESS_REQUIRES_LINE1_CITY},
-        {"XK", ADDRESS_REQUIRES_LINE1_CITY},
-        {"YE", ADDRESS_REQUIRES_LINE1_CITY},
-        {"YT", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"ZA", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
-        {"ZM", ADDRESS_REQUIRES_LINE1_CITY},
-        {"ZW", ADDRESS_REQUIRES_LINE1_CITY},
-};
+constexpr auto kCountryAddressImportRequirementsData =
+    std::to_array<StaticCountryAddressImportRequirementsData>(
+        {{"AC", ADDRESS_REQUIRES_LINE1_CITY},
+         {"AD", ADDRESS_REQUIRES_LINE1},
+         {"AE", ADDRESS_REQUIRES_LINE1_STATE},
+         {"AF", ADDRESS_REQUIRES_LINE1_CITY},
+         {"AG", ADDRESS_REQUIRES_LINE1},
+         {"AI", ADDRESS_REQUIRES_LINE1_CITY},
+         {"AL", ADDRESS_REQUIRES_LINE1_CITY},
+         {"AM", ADDRESS_REQUIRES_LINE1_CITY},
+         {"AO", ADDRESS_REQUIRES_LINE1_CITY},
+         {"AQ", ADDRESS_REQUIRES_LINE1_CITY},
+         {"AR", ADDRESS_REQUIRES_LINE1_CITY},
+         {"AS", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"AT", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"AU", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"AW", ADDRESS_REQUIRES_LINE1_CITY},
+         {"AX", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"AZ", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BA", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BB", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BD", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BE", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"BF", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BG", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BH", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BI", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BJ", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BL", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"BM", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BN", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BO", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BQ", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BR", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"BS", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BT", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BV", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BW", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BY", ADDRESS_REQUIRES_LINE1_CITY},
+         {"BZ", ADDRESS_REQUIRES_LINE1_CITY},
+         {"CA", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"CC", ADDRESS_REQUIRES_LINE1_CITY},
+         {"CD", ADDRESS_REQUIRES_LINE1_CITY},
+         {"CF", ADDRESS_REQUIRES_LINE1_CITY},
+         {"CG", ADDRESS_REQUIRES_LINE1_CITY},
+         {"CH", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"CI", ADDRESS_REQUIRES_LINE1_CITY},
+         {"CK", ADDRESS_REQUIRES_LINE1_CITY},
+         {"CL", ADDRESS_REQUIRES_LINE1_CITY},
+         {"CM", ADDRESS_REQUIRES_LINE1_CITY},
+         {"CN", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"CO", ADDRESS_REQUIRES_LINE1_STATE},
+         {"CR", ADDRESS_REQUIRES_LINE1_STATE},
+         {"CU", ADDRESS_REQUIRES_LINE1_CITY},
+         {"CV", ADDRESS_REQUIRES_LINE1_CITY},
+         {"CW", ADDRESS_REQUIRES_LINE1_CITY},
+         {"CX", ADDRESS_REQUIRES_LINE1_CITY},
+         {"CY", ADDRESS_REQUIRES_LINE1_CITY},
+         {"CZ", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"DE", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"DJ", ADDRESS_REQUIRES_LINE1_CITY},
+         {"DK", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"DM", ADDRESS_REQUIRES_LINE1_CITY},
+         {"DO", ADDRESS_REQUIRES_LINE1_CITY},
+         {"DZ", ADDRESS_REQUIRES_LINE1_CITY},
+         {"EC", ADDRESS_REQUIRES_LINE1_CITY},
+         {"EE", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"EG", ADDRESS_REQUIRES_LINE1_CITY},
+         {"EH", ADDRESS_REQUIRES_LINE1_CITY},
+         {"ER", ADDRESS_REQUIRES_LINE1_CITY},
+         {"ES", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"ET", ADDRESS_REQUIRES_LINE1_CITY},
+         {"FI", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"FJ", ADDRESS_REQUIRES_LINE1_CITY},
+         {"FK", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"FM", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"FO", ADDRESS_REQUIRES_LINE1_CITY},
+         {"FR", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"GA", ADDRESS_REQUIRES_LINE1_CITY},
+         {"GB", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"GD", ADDRESS_REQUIRES_LINE1_CITY},
+         {"GE", ADDRESS_REQUIRES_LINE1_CITY},
+         {"GF", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"GG", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"GH", ADDRESS_REQUIRES_LINE1_CITY},
+         {"GI", ADDRESS_REQUIRES_LINE1},
+         {"GL", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"GM", ADDRESS_REQUIRES_LINE1_CITY},
+         {"GN", ADDRESS_REQUIRES_LINE1_CITY},
+         {"GP", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"GQ", ADDRESS_REQUIRES_LINE1_CITY},
+         {"GR", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"GS", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"GT", ADDRESS_REQUIRES_LINE1_CITY},
+         {"GU", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"GW", ADDRESS_REQUIRES_LINE1_CITY},
+         {"GY", ADDRESS_REQUIRES_LINE1_CITY},
+         {"HK", ADDRESS_REQUIRES_LINE1_STATE},
+         {"HM", ADDRESS_REQUIRES_LINE1_CITY},
+         {"HN", ADDRESS_REQUIRES_LINE1_CITY_STATE},
+         {"HR", ADDRESS_REQUIRES_LINE1_CITY},
+         {"HT", ADDRESS_REQUIRES_LINE1_CITY},
+         {"HU", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"ID", ADDRESS_REQUIRES_LINE1_STATE},
+         {"IE", ADDRESS_REQUIRES_LINE1_CITY},
+         {"IL", ADDRESS_REQUIRES_LINE1_CITY},
+         {"IM", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"IN", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"IO", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"IQ", ADDRESS_REQUIRES_LINE1_CITY_STATE},
+         {"IR", ADDRESS_REQUIRES_LINE1_CITY},
+         {"IS", ADDRESS_REQUIRES_LINE1_CITY},
+         {"IT", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"JE", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"JM", ADDRESS_REQUIRES_LINE1_CITY_STATE},
+         {"JO", ADDRESS_REQUIRES_LINE1_CITY},
+         {"JP", ADDRESS_REQUIRES_LINE1_STATE_ZIP},
+         {"KE", ADDRESS_REQUIRES_LINE1_CITY},
+         {"KG", ADDRESS_REQUIRES_LINE1_CITY},
+         {"KH", ADDRESS_REQUIRES_LINE1_CITY},
+         {"KI", ADDRESS_REQUIRES_LINE1_CITY},
+         {"KM", ADDRESS_REQUIRES_LINE1_CITY},
+         {"KN", ADDRESS_REQUIRES_LINE1_CITY_STATE},
+         {"KP", ADDRESS_REQUIRES_LINE1_CITY},
+         {"KR", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"KW", ADDRESS_REQUIRES_LINE1_CITY},
+         {"KY", ADDRESS_REQUIRES_LINE1_STATE},
+         {"KZ", ADDRESS_REQUIRES_LINE1_CITY},
+         {"LA", ADDRESS_REQUIRES_LINE1_CITY},
+         {"LB", ADDRESS_REQUIRES_LINE1_CITY},
+         {"LC", ADDRESS_REQUIRES_LINE1_CITY},
+         {"LI", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"LK", ADDRESS_REQUIRES_LINE1_CITY},
+         {"LR", ADDRESS_REQUIRES_LINE1_CITY},
+         {"LS", ADDRESS_REQUIRES_LINE1_CITY},
+         {"LT", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"LU", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"LV", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"LY", ADDRESS_REQUIRES_LINE1_CITY},
+         {"MA", ADDRESS_REQUIRES_LINE1_CITY},
+         {"MC", ADDRESS_REQUIRES_LINE1_CITY},
+         {"MD", ADDRESS_REQUIRES_LINE1_CITY},
+         {"ME", ADDRESS_REQUIRES_LINE1_CITY},
+         {"MF", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"MG", ADDRESS_REQUIRES_LINE1_CITY},
+         {"MH", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"MK", ADDRESS_REQUIRES_LINE1_CITY},
+         {"ML", ADDRESS_REQUIRES_LINE1_CITY},
+         {"MM", ADDRESS_REQUIRES_LINE1_CITY},
+         {"MN", ADDRESS_REQUIRES_LINE1_CITY},
+         {"MO", ADDRESS_REQUIRES_LINE1},
+         {"MP", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"MQ", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"MR", ADDRESS_REQUIRES_LINE1_CITY},
+         {"MS", ADDRESS_REQUIRES_LINE1_CITY},
+         {"MT", ADDRESS_REQUIRES_LINE1_CITY},
+         {"MU", ADDRESS_REQUIRES_LINE1_CITY},
+         {"MV", ADDRESS_REQUIRES_LINE1_CITY},
+         {"MW", ADDRESS_REQUIRES_LINE1_CITY},
+         {"MX", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"MY", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"MZ", ADDRESS_REQUIRES_LINE1_CITY},
+         {"NA", ADDRESS_REQUIRES_LINE1_CITY},
+         {"NC", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"NE", ADDRESS_REQUIRES_LINE1_CITY},
+         {"NF", ADDRESS_REQUIRES_LINE1_CITY},
+         {"NG", ADDRESS_REQUIRES_LINE1_CITY},
+         {"NI", ADDRESS_REQUIRES_LINE1_CITY},
+         {"NL", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"NO", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"NP", ADDRESS_REQUIRES_LINE1_CITY},
+         {"NR", ADDRESS_REQUIRES_LINE1_STATE},
+         {"NU", ADDRESS_REQUIRES_LINE1_CITY},
+         {"NZ", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"OM", ADDRESS_REQUIRES_LINE1_CITY},
+         {"PA", ADDRESS_REQUIRES_LINE1_CITY},
+         {"PE", ADDRESS_REQUIRES_LINE1_CITY},
+         {"PF", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"PG", ADDRESS_REQUIRES_LINE1_CITY_STATE},
+         {"PH", ADDRESS_REQUIRES_LINE1_CITY},
+         {"PK", ADDRESS_REQUIRES_LINE1_CITY},
+         {"PL", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"PM", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"PN", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"PR", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"PS", ADDRESS_REQUIRES_LINE1_CITY},
+         {"PT", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"PW", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"PY", ADDRESS_REQUIRES_LINE1_CITY},
+         {"QA", ADDRESS_REQUIRES_LINE1_CITY},
+         {"RE", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"RO", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"RS", ADDRESS_REQUIRES_LINE1_CITY},
+         {"RU", ADDRESS_REQUIRES_LINE1_CITY},
+         {"RW", ADDRESS_REQUIRES_LINE1_CITY},
+         {"SA", ADDRESS_REQUIRES_LINE1_CITY},
+         {"SB", ADDRESS_REQUIRES_LINE1_CITY},
+         {"SC", ADDRESS_REQUIRES_LINE1_CITY},
+         {"SD", ADDRESS_REQUIRES_LINE1_CITY},
+         {"SE", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"SG", ADDRESS_REQUIRES_LINE1_ZIP},
+         {"SH", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"SI", ADDRESS_REQUIRES_LINE1_CITY},
+         {"SJ", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"SK", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"SL", ADDRESS_REQUIRES_LINE1_CITY},
+         {"SM", ADDRESS_REQUIRES_LINE1_ZIP},
+         {"SN", ADDRESS_REQUIRES_LINE1_CITY},
+         {"SO", ADDRESS_REQUIRES_LINE1_CITY_STATE},
+         {"SR", ADDRESS_REQUIRES_LINE1_CITY},
+         {"SS", ADDRESS_REQUIRES_LINE1_CITY},
+         {"ST", ADDRESS_REQUIRES_LINE1_CITY},
+         {"SV", ADDRESS_REQUIRES_LINE1_CITY_STATE},
+         {"SX", ADDRESS_REQUIRES_LINE1_CITY},
+         {"SY", ADDRESS_REQUIRES_LINE1_CITY},
+         {"SZ", ADDRESS_REQUIRES_LINE1_CITY},
+         {"TA", ADDRESS_REQUIRES_LINE1_CITY},
+         {"TC", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"TD", ADDRESS_REQUIRES_LINE1_CITY},
+         {"TF", ADDRESS_REQUIRES_LINE1_CITY},
+         {"TG", ADDRESS_REQUIRES_LINE1_CITY},
+         {"TH", ADDRESS_REQUIRES_LINE1_CITY},
+         {"TJ", ADDRESS_REQUIRES_LINE1_CITY},
+         {"TK", ADDRESS_REQUIRES_LINE1_CITY},
+         {"TL", ADDRESS_REQUIRES_LINE1_CITY},
+         {"TM", ADDRESS_REQUIRES_LINE1_CITY},
+         {"TN", ADDRESS_REQUIRES_LINE1_CITY},
+         {"TO", ADDRESS_REQUIRES_LINE1_CITY},
+         {"TR", ADDRESS_REQUIRES_LINE1_CITY_STATE},
+         {"TT", ADDRESS_REQUIRES_LINE1_CITY},
+         {"TV", ADDRESS_REQUIRES_LINE1_CITY},
+         {"TW", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"TZ", ADDRESS_REQUIRES_LINE1_CITY},
+         {"UA", ADDRESS_REQUIRES_LINE1_CITY},
+         {"UG", ADDRESS_REQUIRES_LINE1_CITY},
+         {"UM", ADDRESS_REQUIRES_LINE1_CITY_STATE},
+         {"US", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"UY", ADDRESS_REQUIRES_LINE1_CITY},
+         {"UZ", ADDRESS_REQUIRES_LINE1_CITY},
+         {"VA", ADDRESS_REQUIRES_LINE1_CITY},
+         {"VC", ADDRESS_REQUIRES_LINE1_CITY},
+         {"VE", ADDRESS_REQUIRES_LINE1_CITY_STATE},
+         {"VG", ADDRESS_REQUIRES_LINE1},
+         {"VI", ADDRESS_REQUIRES_LINE1_CITY_STATE_ZIP},
+         {"VN", ADDRESS_REQUIRES_LINE1_CITY},
+         {"VU", ADDRESS_REQUIRES_LINE1_CITY},
+         {"WF", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"WS", ADDRESS_REQUIRES_LINE1_CITY},
+         {"XK", ADDRESS_REQUIRES_LINE1_CITY},
+         {"YE", ADDRESS_REQUIRES_LINE1_CITY},
+         {"YT", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"ZA", ADDRESS_REQUIRES_LINE1_CITY_ZIP},
+         {"ZM", ADDRESS_REQUIRES_LINE1_CITY},
+         {"ZW", ADDRESS_REQUIRES_LINE1_CITY}});
 
 // GetCountryCodes and GetCountryData compute the data for CountryDataMap
 // based on |kCountryAddressImportRequirementsData|.
@@ -318,8 +313,10 @@
 
   // Add any other countries that ICU knows about, falling back to default data
   // values.
+  // SAFETY: `icu::Locale::getISOCountries` returns a C-style array whose last
+  // entry is a nullptr.
   for (const char* const* country_pointer = icu::Locale::getISOCountries();
-       *country_pointer; ++country_pointer) {
+       *country_pointer; UNSAFE_BUFFERS(++country_pointer)) {
     std::string country_code = *country_pointer;
     if (!import_requirements.count(country_code)) {
       import_requirements.insert(std::make_pair(
diff --git a/components/autofill/core/browser/heuristic_source.cc b/components/autofill/core/browser/heuristic_source.cc
index 3c10b36..b72373c5 100644
--- a/components/autofill/core/browser/heuristic_source.cc
+++ b/components/autofill/core/browser/heuristic_source.cc
@@ -20,13 +20,8 @@
 #if !BUILDFLAG(USE_INTERNAL_AUTOFILL_PATTERNS)
   return HeuristicSource::kLegacy;
 #else
-  if (!base::FeatureList::IsEnabled(
-          features::kAutofillParsingPatternProvider)) {
-    return HeuristicSource::kLegacy;
-  }
   const std::string& source =
       features::kAutofillParsingPatternActiveSource.Get();
-  CHECK(source == "default" || source == "experimental" || source == "nextgen");
   return source == "default"        ? HeuristicSource::kDefault
          : source == "experimental" ? HeuristicSource::kExperimental
                                     : HeuristicSource::kNextGen;
diff --git a/components/autofill/core/browser/heuristic_source_unittest.cc b/components/autofill/core/browser/heuristic_source_unittest.cc
index 6dd6df5d..a183c14 100644
--- a/components/autofill/core/browser/heuristic_source_unittest.cc
+++ b/components/autofill/core/browser/heuristic_source_unittest.cc
@@ -25,7 +25,7 @@
 
 struct HeuristicSourceParams {
   std::optional<bool> model_predictions_feature;
-  std::optional<std::string> pattern_provider_feature;
+  std::string pattern_provider_feature;
   const HeuristicSource expected_active_source;
   const DenseSet<HeuristicSource> expected_nonactive_sources;
 };
@@ -47,14 +47,10 @@
     } else {
       disabled_features.push_back(features::kAutofillModelPredictions);
     }
-    if (test_case.pattern_provider_feature) {
-      enabled_features.push_back(
-          {features::kAutofillParsingPatternProvider,
-           {{features::kAutofillParsingPatternActiveSource.name,
-             *test_case.pattern_provider_feature}}});
-    } else {
-      disabled_features.push_back(features::kAutofillParsingPatternProvider);
-    }
+    enabled_features.push_back(
+        {features::kAutofillParsingPatternProvider,
+         {{features::kAutofillParsingPatternActiveSource.name,
+           test_case.pattern_provider_feature}}});
     features_.InitWithFeaturesAndParameters(enabled_features,
                                             disabled_features);
   }
@@ -74,8 +70,8 @@
     HeuristicSourceTest,
     HeuristicSourceTest,
     testing::Values(
-// Tests when `kAutofillParsingPatternProvider` is enabled. The behavior is
-// different for Chrome and non-Chrome branded instances.
+// The pattern provider behavior differs between Chrome and non-Chrome branded
+// instances.
 #if !BUILDFLAG(USE_INTERNAL_AUTOFILL_PATTERNS)
         HeuristicSourceParams{
             .pattern_provider_feature = "legacy",
@@ -88,11 +84,14 @@
             .expected_active_source = HeuristicSource::kMachineLearning,
             .expected_nonactive_sources = {HeuristicSource::kLegacy}},
 
-        HeuristicSourceParams{
-            .model_predictions_feature = false,
-            .pattern_provider_feature = "legacy",
-            .expected_active_source = HeuristicSource::kLegacy,
-            .expected_nonactive_sources = {HeuristicSource::kMachineLearning}},
+        HeuristicSourceParams {
+          .model_predictions_feature = false,
+          .pattern_provider_feature = "legacy",
+          .expected_active_source = HeuristicSource::kLegacy,
+          .expected_nonactive_sources = {
+            HeuristicSource::kMachineLearning
+          }
+        }
 #else
         HeuristicSourceParams{
             .model_predictions_feature = true,
@@ -114,24 +113,8 @@
         HeuristicSourceParams{
             .pattern_provider_feature = "experimental",
             .expected_active_source = HeuristicSource::kExperimental,
-            .expected_nonactive_sources = {HeuristicSource::kNextGen}},
+            .expected_nonactive_sources = {HeuristicSource::kNextGen}}
 #endif
-        // Tests when `kAutofillParsingPatternProvider` is disabled. In this
-        // case, parsing doesn't depend on the pattern source. But since
-        // `MatchPatternRef`s are loaded regardless, expect that the code
-        // defaults to `kLegacy`.
-        HeuristicSourceParams{
-            .expected_active_source = HeuristicSource::kLegacy,
-            .expected_nonactive_sources = {}},
-        HeuristicSourceParams{
-            .model_predictions_feature = true,
-            .expected_active_source = HeuristicSource::kMachineLearning,
-            .expected_nonactive_sources = {HeuristicSource::kLegacy}},
-        HeuristicSourceParams{
-            .model_predictions_feature = false,
-            .expected_active_source = HeuristicSource::kLegacy,
-            .expected_nonactive_sources = {HeuristicSource::kMachineLearning}}
-
         ));
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/iban_manager.cc b/components/autofill/core/browser/iban_manager.cc
index 749f34a8..1ed047dc 100644
--- a/components/autofill/core/browser/iban_manager.cc
+++ b/components/autofill/core/browser/iban_manager.cc
@@ -127,9 +127,7 @@
   }
 
   std::move(on_suggestions_returned)
-      .Run(field.global_id(),
-           PaymentsSuggestionGenerator::GetSuggestionsForIbans(
-               std::move(ibans)));
+      .Run(field.global_id(), GetSuggestionsForIbans(std::move(ibans)));
 
   uma_recorder_.OnIbanSuggestionsShown(field.global_id());
 }
diff --git a/components/autofill/core/browser/merchant_promo_code_manager.cc b/components/autofill/core/browser/merchant_promo_code_manager.cc
index ec16c96..1e8366c 100644
--- a/components/autofill/core/browser/merchant_promo_code_manager.cc
+++ b/components/autofill/core/browser/merchant_promo_code_manager.cc
@@ -156,8 +156,7 @@
 
   std::move(on_suggestions_returned)
       .Run(field.global_id(),
-           PaymentsSuggestionGenerator::
-               GetPromoCodeSuggestionsFromPromoCodeOffers(promo_code_offers));
+           GetPromoCodeSuggestionsFromPromoCodeOffers(promo_code_offers));
 
   // Log that promo code autofill suggestions were shown.
   uma_recorder_.OnOffersSuggestionsShown(field.global_id(), promo_code_offers);
diff --git a/components/autofill/core/browser/metrics/form_events/form_event_logger_base.cc b/components/autofill/core/browser/metrics/form_events/form_event_logger_base.cc
index 55f5104..6c29620 100644
--- a/components/autofill/core/browser/metrics/form_events/form_event_logger_base.cc
+++ b/components/autofill/core/browser/metrics/form_events/form_event_logger_base.cc
@@ -151,8 +151,8 @@
 
 void FormEventLoggerBase::RecordFillingOperation(
     FormGlobalId form_id,
-    base::span<const FormFieldData*> filled_fields,
-    base::span<const AutofillField*> filled_autofill_fields) {
+    base::span<const FormFieldData* const> filled_fields,
+    base::span<const AutofillField* const> filled_autofill_fields) {
   ++filling_operation_count_;
   bool is_address =
       parsed_form_types_.contains(FormTypeNameForLogging::kAddressForm);
diff --git a/components/autofill/core/browser/metrics/form_events/form_event_logger_base.h b/components/autofill/core/browser/metrics/form_events/form_event_logger_base.h
index 4b01d54..8114c34 100644
--- a/components/autofill/core/browser/metrics/form_events/form_event_logger_base.h
+++ b/components/autofill/core/browser/metrics/form_events/form_event_logger_base.h
@@ -62,8 +62,8 @@
   // by field filling.
   void RecordFillingOperation(
       FormGlobalId form_id,
-      base::span<const FormFieldData*> filled_fields,
-      base::span<const AutofillField*> filled_autofill_fields);
+      base::span<const FormFieldData* const> filled_fields,
+      base::span<const AutofillField* const> filled_autofill_fields);
 
   void OnDidRefill(
       AutofillMetrics::PaymentsSigninState signin_state_for_metrics,
diff --git a/components/autofill/core/browser/metrics/profile_deduplication_metrics.cc b/components/autofill/core/browser/metrics/profile_deduplication_metrics.cc
index 98c5e85..f88b6d7 100644
--- a/components/autofill/core/browser/metrics/profile_deduplication_metrics.cc
+++ b/components/autofill/core/browser/metrics/profile_deduplication_metrics.cc
@@ -62,7 +62,7 @@
       duplication_rank);
   LogTypeOfQuasiDuplicateTokenMetric(kStartupHistogramPrefix, duplication_rank,
                                      min_incompatible_sets);
-  // TODO(b/325452461): Implement more metrics.
+  // TODO(crbug.com/325452461): Implement more metrics.
 }
 
 }  // namespace
@@ -130,7 +130,7 @@
       duplication_rank);
   LogTypeOfQuasiDuplicateTokenMetric(metric_name_prefix, duplication_rank,
                                      min_incompatible_sets);
-  // TODO(b/325452461): Implement more metrics.
+  // TODO(crbug.com/325452461): Implement more metrics.
 }
 
 }  // namespace autofill::autofill_metrics
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
index e42f7da0..4432660 100644
--- a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
@@ -521,8 +521,8 @@
         .OnUserAcceptedAuthenticationSelectionDialog(
             challenge_option.id.value());
 
-    // TODO(b/329523854): Check that the challenge selection acceptance was
-    // handled correctly using mocks instead of test classes.
+    // TODO(crbug.com/329523854): Check that the challenge selection acceptance
+    // was handled correctly using mocks instead of test classes.
     switch (challenge_option.type) {
       case CardUnmaskChallengeOptionType::kCvc: {
         CreditCardCvcAuthenticator& cvc_authenticator =
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager.cc b/components/autofill/core/browser/payments/credit_card_save_manager.cc
index 810e29d8..2025b76 100644
--- a/components/autofill/core/browser/payments/credit_card_save_manager.cc
+++ b/components/autofill/core/browser/payments/credit_card_save_manager.cc
@@ -526,7 +526,7 @@
 
   // Init virtual card enrollment since there is no save card
   // confirmation bubble showing if the flag is disabled.
-  // TODO(b/309627643): Clean up Chrome feature flag:
+  // TODO(crbug.com/309627643): Clean up Chrome feature flag:
   // autofill-enable-save-card-loading-and-confirmation
   if (get_details_for_enrollment_response_details.has_value() &&
       !IsSaveCardLoadingAndConfirmationEnabled()) {
diff --git a/components/autofill/core/browser/payments/iban_access_manager.cc b/components/autofill/core/browser/payments/iban_access_manager.cc
index 3e124971..c6296d6 100644
--- a/components/autofill/core/browser/payments/iban_access_manager.cc
+++ b/components/autofill/core/browser/payments/iban_access_manager.cc
@@ -159,7 +159,7 @@
 }
 
 void IbanAccessManager::OnServerIbanUnmaskCancelled() {
-  // TODO(b/296651899): Log the cancel metrics.
+  // TODO(crbug.com/296651899): Log the cancel metrics.
 }
 
 void IbanAccessManager::StartDeviceAuthenticationForFilling(
diff --git a/components/autofill/core/browser/payments/payments_network_interface.h b/components/autofill/core/browser/payments/payments_network_interface.h
index 78822f9..135ae3b 100644
--- a/components/autofill/core/browser/payments/payments_network_interface.h
+++ b/components/autofill/core/browser/payments/payments_network_interface.h
@@ -123,7 +123,7 @@
     std::string context_token;
     // The origin of the primary main frame where the unmasking happened.
     // Should be populated when the unmasking is for a virtual-card.
-    // TODO(b/325465172): Convert this to an std::optional<url::Origin>.
+    // TODO(crbug.com/325465172): Convert this to an std::optional<url::Origin>.
     std::optional<GURL> last_committed_primary_main_frame_origin;
     // The selected challenge option. Should be populated when we are doing CVC
     // unmasking for a virtual card.
diff --git a/components/autofill/core/browser/payments/virtual_card_enrollment_manager_unittest.cc b/components/autofill/core/browser/payments/virtual_card_enrollment_manager_unittest.cc
index 49331dd..012edb0 100644
--- a/components/autofill/core/browser/payments/virtual_card_enrollment_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/virtual_card_enrollment_manager_unittest.cc
@@ -123,8 +123,8 @@
     return response;
   }
 
-  // TODO(b/303715506): This part does not test the desired behavior on iOS as
-  // the virtual card enrollment strikedatabase on iOS is not initialized
+  // TODO(crbug.com/303715506): This part does not test the desired behavior on
+  // iOS as the virtual card enrollment strikedatabase on iOS is not initialized
   // (guarded by the feature flag).
   void SetUpStrikeDatabaseTest() {
     VirtualCardEnrollmentProcessState* state =
diff --git a/components/autofill/core/browser/payments_data_manager.cc b/components/autofill/core/browser/payments_data_manager.cc
index 30151a4..cff8169 100644
--- a/components/autofill/core/browser/payments_data_manager.cc
+++ b/components/autofill/core/browser/payments_data_manager.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO: crbug.com/347137620 - Remove this and spanify to fix the errors.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "components/autofill/core/browser/payments_data_manager.h"
 
 #include <memory>
@@ -804,7 +799,7 @@
     return cached_image;
   }
 
-  FetchImagesForURLs(base::make_span(&card_art_url, 1u));
+  FetchImagesForURLs(base::span_from_ref(card_art_url));
   return nullptr;
 }
 
diff --git a/components/autofill/core/browser/payments_data_manager.h b/components/autofill/core/browser/payments_data_manager.h
index 001c78f..fe86dd45 100644
--- a/components/autofill/core/browser/payments_data_manager.h
+++ b/components/autofill/core/browser/payments_data_manager.h
@@ -304,7 +304,7 @@
   // De-dupe credit card to suggest. Full server cards are preferred over their
   // local duplicates, and local cards are preferred over their masked server
   // card duplicate.
-  // TODO(b/326408802): Move to suggestion generator?
+  // TODO(crbug.com/326408802): Move to suggestion generator?
   static void DedupeCreditCardToSuggest(
       std::list<CreditCard*>* cards_to_suggest);
 
@@ -419,7 +419,7 @@
   // Returns true if the user pref to store CVC is enabled.
   virtual bool IsPaymentCvcStorageEnabled();
 
-  // TODO(b/322170538): Remove.
+  // TODO(crbug.com/322170538): Remove.
   scoped_refptr<AutofillWebDataService> GetLocalDatabase();
   scoped_refptr<AutofillWebDataService> GetServerDatabase();
   bool IsUsingAccountStorageForServerDataForTest();
diff --git a/components/autofill/core/browser/payments_suggestion_generator.cc b/components/autofill/core/browser/payments_suggestion_generator.cc
index 4db80f9..1727bff0 100644
--- a/components/autofill/core/browser/payments_suggestion_generator.cc
+++ b/components/autofill/core/browser/payments_suggestion_generator.cc
@@ -67,7 +67,8 @@
 #if BUILDFLAG(IS_IOS)
   std::u16string value =
       l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM);
-  // TODO(b/40266549): iOS still uses Clear Form logic, replace with Undo.
+  // TODO(crbug.com/40266549): iOS still uses Clear Form logic, replace with
+  // Undo.
   Suggestion suggestion(value, SuggestionType::kUndoOrClear);
   suggestion.icon = Suggestion::Icon::kClear;
 #else
@@ -78,7 +79,7 @@
   Suggestion suggestion(value, SuggestionType::kUndoOrClear);
   suggestion.icon = Suggestion::Icon::kUndo;
 #endif
-  // TODO(b/40266549): update "Clear Form" a11y announcement to "Undo"
+  // TODO(crbug.com/40266549): update "Clear Form" a11y announcement to "Undo"
   suggestion.acceptance_a11y_announcement =
       l10n_util::GetStringUTF16(IDS_AUTOFILL_A11Y_ANNOUNCE_CLEARED_FORM);
   return suggestion;
@@ -723,8 +724,7 @@
     footer_suggestions.push_back(CreateUndoOrClearFormSuggestion());
   }
   footer_suggestions.push_back(
-      PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
-          with_gpay_logo));
+      CreateManageCreditCardsSuggestion(with_gpay_logo));
   return footer_suggestions;
 }
 
@@ -753,14 +753,186 @@
   return true;
 }
 
+// Helper function to decide whether to show the virtual card option for
+// `candidate_card`.
+// TODO(crbug.com/326950201): Pass the argument by reference.
+bool ShouldShowVirtualCardOption(const CreditCard* candidate_card,
+                                 const AutofillClient& client) {
+  const CreditCard* candidate_server_card = nullptr;
+  switch (candidate_card->record_type()) {
+    case CreditCard::RecordType::kLocalCard:
+      candidate_server_card = client.GetPersonalDataManager()
+                                  ->payments_data_manager()
+                                  .GetServerCardForLocalCard(candidate_card);
+      break;
+    case CreditCard::RecordType::kMaskedServerCard:
+      candidate_server_card = candidate_card;
+      break;
+    case CreditCard::RecordType::kFullServerCard:
+      break;
+    case CreditCard::RecordType::kVirtualCard:
+      // Should not happen since virtual card is not persisted.
+      NOTREACHED_NORETURN();
+  }
+  if (!candidate_server_card) {
+    return false;
+  }
+  candidate_card = candidate_server_card;
+  return ShouldShowVirtualCardOptionForServerCard(*candidate_server_card,
+                                                  client);
+}
+
+// Returns the local and server cards ordered by the Autofill ranking.
+// If `suppress_disused_cards`, local expired disused cards are removed.
+// If `prefix_match`, cards are matched with the contents of `trigger_field`.
+// If `include_virtual_cards`, virtual cards will be added when possible.
+std::vector<CreditCard> GetOrderedCardsToSuggest(
+    const AutofillClient& client,
+    const FormFieldData& trigger_field,
+    FieldType trigger_field_type,
+    bool suppress_disused_cards,
+    bool prefix_match,
+    bool include_virtual_cards) {
+  std::vector<CreditCard*> available_cards = client.GetPersonalDataManager()
+                                                 ->payments_data_manager()
+                                                 .GetCreditCardsToSuggest();
+  // If a card has available card linked offers on the last committed url, rank
+  // it to the top.
+  if (std::map<std::string, AutofillOfferData*> card_linked_offers_map =
+          GetCardLinkedOffers(client);
+      !card_linked_offers_map.empty()) {
+    base::ranges::stable_sort(
+        available_cards,
+        [&card_linked_offers_map](const CreditCard* a, const CreditCard* b) {
+          return base::Contains(card_linked_offers_map, a->guid()) &&
+                 !base::Contains(card_linked_offers_map, b->guid());
+        });
+  }
+  // Suppress disused credit cards when triggered from an empty field.
+  if (suppress_disused_cards) {
+    const base::Time min_last_used =
+        AutofillClock::Now() - kDisusedDataModelTimeDelta;
+    RemoveExpiredLocalCreditCardsNotUsedSinceTimestamp(min_last_used,
+                                                       available_cards);
+  }
+  std::vector<CreditCard> cards_to_suggest;
+  std::u16string field_contents =
+      base::i18n::ToLower(SanitizeCreditCardFieldValue(trigger_field.value()));
+  for (const CreditCard* credit_card : available_cards) {
+    std::u16string suggested_value = credit_card->GetInfo(
+        trigger_field_type,
+        client.GetPersonalDataManager()->payments_data_manager().app_locale());
+    if (prefix_match && suggested_value.empty()) {
+      continue;
+    }
+    if (prefix_match &&
+        !IsValidPaymentsSuggestionForFieldContents(
+            /*suggestion_canon=*/base::i18n::ToLower(suggested_value),
+            field_contents, trigger_field_type,
+            credit_card->record_type() ==
+                CreditCard::RecordType::kMaskedServerCard,
+            trigger_field.is_autofilled())) {
+      continue;
+    }
+    if (include_virtual_cards &&
+        ShouldShowVirtualCardOption(credit_card, client)) {
+      cards_to_suggest.push_back(CreditCard::CreateVirtualCard(*credit_card));
+    }
+    cards_to_suggest.push_back(*credit_card);
+  }
+  return cards_to_suggest;
+}
+
+// Creates a suggestion for the given `credit_card`. `virtual_card_option`
+// suggests whether the suggestion is a virtual card option.
+// `card_linked_offer_available` indicates whether a card-linked offer is
+// attached to the `credit_card`. `metadata_logging_context` contains card
+// metadata related information used for metrics logging.
+// TODO(crbug.com/40232456): Separate logic for desktop, Android dropdown, and
+// Keyboard Accessory.
+Suggestion CreateCreditCardSuggestion(
+    const CreditCard& credit_card,
+    const AutofillClient& client,
+    FieldType trigger_field_type,
+    bool virtual_card_option,
+    bool card_linked_offer_available,
+    autofill_metrics::CardMetadataLoggingContext& metadata_logging_context) {
+  // Manual fallback entries are shown for all non credit card fields.
+  const bool is_manual_fallback =
+      GroupTypeOfFieldType(trigger_field_type) != FieldTypeGroup::kCreditCard;
+
+  Suggestion suggestion;
+  suggestion.icon = credit_card.CardIconForAutofillSuggestion();
+  // First layer manual fallback entries can't fill forms and thus can't be
+  // selected by the user.
+  suggestion.type = SuggestionType::kCreditCardEntry;
+  suggestion.is_acceptable =
+      IsCardSuggestionAcceptable(credit_card, client, is_manual_fallback);
+  suggestion.payload = Suggestion::Guid(credit_card.guid());
+#if BUILDFLAG(IS_ANDROID)
+  // The card art icon should always be shown at the start of the suggestion.
+  suggestion.is_icon_at_start = true;
+#endif  // BUILDFLAG(IS_ANDROID)
+
+  // Manual fallback suggestions labels are computed as if the triggering field
+  // type was the credit card number.
+  auto [main_text, minor_text] = GetSuggestionMainTextAndMinorTextForCard(
+      credit_card, client,
+      is_manual_fallback ? CREDIT_CARD_NUMBER : trigger_field_type);
+  suggestion.main_text = std::move(main_text);
+  suggestion.minor_text = std::move(minor_text);
+  SetSuggestionLabelsForCard(
+      credit_card, client,
+      is_manual_fallback ? CREDIT_CARD_NUMBER : trigger_field_type,
+      metadata_logging_context, suggestion);
+  SetCardArtURL(suggestion, credit_card,
+                client.GetPersonalDataManager()->payments_data_manager(),
+                virtual_card_option);
+
+  // For virtual cards, make some adjustments for the suggestion contents.
+  if (virtual_card_option) {
+    // We don't show card linked offers for virtual card options.
+    AdjustVirtualCardSuggestionContent(suggestion, credit_card, client,
+                                       trigger_field_type);
+  } else if (card_linked_offer_available) {
+#if BUILDFLAG(IS_ANDROID)
+    // For Keyboard Accessory, set Suggestion::feature_for_iph and change the
+    // suggestion icon only if card linked offers are also enabled.
+    if (base::FeatureList::IsEnabled(
+            features::kAutofillEnableOffersInClankKeyboardAccessory)) {
+      suggestion.feature_for_iph =
+          &feature_engagement::kIPHKeyboardAccessoryPaymentOfferFeature;
+      suggestion.icon = Suggestion::Icon::kOfferTag;
+    } else {
+#else   // Add the offer label on Desktop unconditionally.
+    {
+#endif  // BUILDFLAG(IS_ANDROID)
+      suggestion.labels.push_back(
+          std::vector<Suggestion::Text>{Suggestion::Text(
+              l10n_util::GetStringUTF16(IDS_AUTOFILL_OFFERS_CASHBACK))});
+    }
+  }
+
+  if (virtual_card_option) {
+    suggestion.acceptance_a11y_announcement = l10n_util::GetStringUTF16(
+        IDS_AUTOFILL_A11Y_ANNOUNCE_VIRTUAL_CARD_MANUAL_FALLBACK_ENTRY);
+  } else if (is_manual_fallback) {
+    AddPaymentsGranularFillingChildSuggestions(
+        credit_card, suggestion,
+        client.GetPersonalDataManager()->payments_data_manager().app_locale());
+    suggestion.acceptance_a11y_announcement = l10n_util::GetStringUTF16(
+        IDS_AUTOFILL_A11Y_ANNOUNCE_EXPANDABLE_ONLY_ENTRY);
+  } else {
+    suggestion.acceptance_a11y_announcement =
+        l10n_util::GetStringUTF16(IDS_AUTOFILL_A11Y_ANNOUNCE_FILLED_FORM);
+  }
+
+  return suggestion;
+}
+
 }  // namespace
 
-PaymentsSuggestionGenerator::PaymentsSuggestionGenerator() = default;
-
-PaymentsSuggestionGenerator::~PaymentsSuggestionGenerator() = default;
-
-std::vector<Suggestion>
-PaymentsSuggestionGenerator::GetSuggestionsForCreditCards(
+std::vector<Suggestion> GetSuggestionsForCreditCards(
     const AutofillClient& client,
     const FormFieldData& trigger_field,
     FieldType trigger_field_type,
@@ -833,8 +1005,7 @@
   return suggestions;
 }
 
-std::vector<Suggestion>
-PaymentsSuggestionGenerator::GetSuggestionsForVirtualCardStandaloneCvc(
+std::vector<Suggestion> GetSuggestionsForVirtualCardStandaloneCvc(
     const AutofillClient& client,
     const FormFieldData& trigger_field,
     autofill_metrics::CardMetadataLoggingContext& metadata_logging_context,
@@ -901,18 +1072,16 @@
   return suggestions;
 }
 
-std::vector<CreditCard>
-PaymentsSuggestionGenerator::GetTouchToFillCardsToSuggest(
+std::vector<CreditCard> GetTouchToFillCardsToSuggest(
     const AutofillClient& client,
     const FormFieldData& trigger_field,
     FieldType trigger_field_type) {
   // TouchToFill actually has a trigger field which must be classified in some
   // way, but we intentionally fetch suggestions irrelevant of them.
-  std::vector<CreditCard> cards_to_suggest =
-      PaymentsSuggestionGenerator::GetOrderedCardsToSuggest(
-          client, trigger_field, trigger_field_type,
-          /*suppress_disused_cards=*/true, /*prefix_match=*/false,
-          /*include_virtual_cards=*/true);
+  std::vector<CreditCard> cards_to_suggest = GetOrderedCardsToSuggest(
+      client, trigger_field, trigger_field_type,
+      /*suppress_disused_cards=*/true, /*prefix_match=*/false,
+      /*include_virtual_cards=*/true);
   return base::ranges::any_of(cards_to_suggest,
                               &CreditCard::IsCompleteValidCard)
              ? cards_to_suggest
@@ -920,79 +1089,19 @@
 }
 
 // static
-Suggestion PaymentsSuggestionGenerator::CreateManageCreditCardsEntry(
-    bool with_gpay_logo) {
+Suggestion CreateManageCreditCardsSuggestion(bool with_gpay_logo) {
   return CreateManagePaymentMethodsEntry(SuggestionType::kManageCreditCard,
                                          with_gpay_logo);
 }
 
 // static
-Suggestion PaymentsSuggestionGenerator::CreateManageIbansEntry() {
+Suggestion CreateManageIbansSuggestion() {
   return CreateManagePaymentMethodsEntry(SuggestionType::kManageIban,
                                          /*with_gpay_logo=*/false);
 }
 
 // static
-std::vector<CreditCard> PaymentsSuggestionGenerator::GetOrderedCardsToSuggest(
-    const AutofillClient& client,
-    const FormFieldData& trigger_field,
-    FieldType trigger_field_type,
-    bool suppress_disused_cards,
-    bool prefix_match,
-    bool include_virtual_cards) {
-  std::vector<CreditCard*> available_cards = client.GetPersonalDataManager()
-                                                 ->payments_data_manager()
-                                                 .GetCreditCardsToSuggest();
-  // If a card has available card linked offers on the last committed url, rank
-  // it to the top.
-  if (std::map<std::string, AutofillOfferData*> card_linked_offers_map =
-          GetCardLinkedOffers(client);
-      !card_linked_offers_map.empty()) {
-    base::ranges::stable_sort(
-        available_cards,
-        [&card_linked_offers_map](const CreditCard* a, const CreditCard* b) {
-          return base::Contains(card_linked_offers_map, a->guid()) &&
-                 !base::Contains(card_linked_offers_map, b->guid());
-        });
-  }
-  // Suppress disused credit cards when triggered from an empty field.
-  if (suppress_disused_cards) {
-    const base::Time min_last_used =
-        AutofillClock::Now() - kDisusedDataModelTimeDelta;
-    RemoveExpiredLocalCreditCardsNotUsedSinceTimestamp(min_last_used,
-                                                       available_cards);
-  }
-  std::vector<CreditCard> cards_to_suggest;
-  std::u16string field_contents =
-      base::i18n::ToLower(SanitizeCreditCardFieldValue(trigger_field.value()));
-  for (const CreditCard* credit_card : available_cards) {
-    std::u16string suggested_value = credit_card->GetInfo(
-        trigger_field_type,
-        client.GetPersonalDataManager()->payments_data_manager().app_locale());
-    if (prefix_match && suggested_value.empty()) {
-      continue;
-    }
-    if (prefix_match &&
-        !IsValidPaymentsSuggestionForFieldContents(
-            /*suggestion_canon=*/base::i18n::ToLower(suggested_value),
-            field_contents, trigger_field_type,
-            credit_card->record_type() ==
-                CreditCard::RecordType::kMaskedServerCard,
-            trigger_field.is_autofilled())) {
-      continue;
-    }
-    if (include_virtual_cards &&
-        ShouldShowVirtualCardOption(credit_card, client)) {
-      cards_to_suggest.push_back(CreditCard::CreateVirtualCard(*credit_card));
-    }
-    cards_to_suggest.push_back(*credit_card);
-  }
-  return cards_to_suggest;
-}
-
-// static
-std::vector<Suggestion> PaymentsSuggestionGenerator::GetSuggestionsForIbans(
-    const std::vector<Iban>& ibans) {
+std::vector<Suggestion> GetSuggestionsForIbans(const std::vector<Iban>& ibans) {
   if (ibans.empty()) {
     return {};
   }
@@ -1019,13 +1128,12 @@
   }
 
   suggestions.push_back(CreateSeparator());
-  suggestions.push_back(CreateManageIbansEntry());
+  suggestions.push_back(CreateManageIbansSuggestion());
   return suggestions;
 }
 
 // static
-std::vector<Suggestion>
-PaymentsSuggestionGenerator::GetPromoCodeSuggestionsFromPromoCodeOffers(
+std::vector<Suggestion> GetPromoCodeSuggestionsFromPromoCodeOffers(
     const std::vector<const AutofillOfferData*>& promo_code_offers) {
   std::vector<Suggestion> suggestions;
   GURL footer_offer_details_url;
@@ -1077,9 +1185,9 @@
   return suggestions;
 }
 
-bool PaymentsSuggestionGenerator::IsCardAcceptable(const CreditCard& card,
-                                                   const AutofillClient& client,
-                                                   bool is_manual_fallback) {
+bool IsCardSuggestionAcceptable(const CreditCard& card,
+                                const AutofillClient& client,
+                                bool is_manual_fallback) {
   if (card.record_type() == CreditCard::RecordType::kVirtualCard) {
     auto* optimization_guide = client.GetAutofillOptimizationGuide();
     return !(
@@ -1091,113 +1199,37 @@
   return !is_manual_fallback;
 }
 
-bool PaymentsSuggestionGenerator::ShouldShowVirtualCardOption(
-    const CreditCard* candidate_card,
-    const AutofillClient& client) {
-  const CreditCard* candidate_server_card = nullptr;
-  switch (candidate_card->record_type()) {
-    case CreditCard::RecordType::kLocalCard:
-      candidate_server_card = client.GetPersonalDataManager()
-                                  ->payments_data_manager()
-                                  .GetServerCardForLocalCard(candidate_card);
-      break;
-    case CreditCard::RecordType::kMaskedServerCard:
-      candidate_server_card = candidate_card;
-      break;
-    case CreditCard::RecordType::kFullServerCard:
-      break;
-    case CreditCard::RecordType::kVirtualCard:
-      // Should not happen since virtual card is not persisted.
-      NOTREACHED_NORETURN();
-  }
-  if (!candidate_server_card) {
-    return false;
-  }
-  candidate_card = candidate_server_card;
-  return ShouldShowVirtualCardOptionForServerCard(*candidate_server_card,
-                                                  client);
+std::vector<CreditCard> GetOrderedCardsToSuggestForTest(
+    const AutofillClient& client,
+    const FormFieldData& trigger_field,
+    FieldType trigger_field_type,
+    bool suppress_disused_cards,
+    bool prefix_match,
+    bool include_virtual_cards) {
+  return GetOrderedCardsToSuggest(client, trigger_field, trigger_field_type,
+                                  suppress_disused_cards, prefix_match,
+                                  include_virtual_cards);
 }
 
-// TODO(crbug.com/40232456): Separate logic for desktop, Android dropdown, and
-// Keyboard Accessory.
-Suggestion PaymentsSuggestionGenerator::CreateCreditCardSuggestion(
+Suggestion CreateCreditCardSuggestionForTest(
     const CreditCard& credit_card,
     const AutofillClient& client,
     FieldType trigger_field_type,
     bool virtual_card_option,
     bool card_linked_offer_available,
-    autofill_metrics::CardMetadataLoggingContext& metadata_logging_context) {
-  // Manual fallback entries are shown for all non credit card fields.
-  const bool is_manual_fallback =
-      GroupTypeOfFieldType(trigger_field_type) != FieldTypeGroup::kCreditCard;
+    base::optional_ref<autofill_metrics::CardMetadataLoggingContext>
+        metadata_logging_context) {
+  autofill_metrics::CardMetadataLoggingContext dummy_context;
+  return CreateCreditCardSuggestion(
+      credit_card, client, trigger_field_type, virtual_card_option,
+      card_linked_offer_available,
+      metadata_logging_context.has_value() ? *metadata_logging_context
+                                           : dummy_context);
+}
 
-  Suggestion suggestion;
-  suggestion.icon = credit_card.CardIconForAutofillSuggestion();
-  // First layer manual fallback entries can't fill forms and thus can't be
-  // selected by the user.
-  suggestion.type = SuggestionType::kCreditCardEntry;
-  suggestion.is_acceptable =
-      IsCardAcceptable(credit_card, client, is_manual_fallback);
-  suggestion.payload = Suggestion::Guid(credit_card.guid());
-#if BUILDFLAG(IS_ANDROID)
-  // The card art icon should always be shown at the start of the suggestion.
-  suggestion.is_icon_at_start = true;
-#endif  // BUILDFLAG(IS_ANDROID)
-
-  // Manual fallback suggestions labels are computed as if the triggering field
-  // type was the credit card number.
-  auto [main_text, minor_text] = GetSuggestionMainTextAndMinorTextForCard(
-      credit_card, client,
-      is_manual_fallback ? CREDIT_CARD_NUMBER : trigger_field_type);
-  suggestion.main_text = std::move(main_text);
-  suggestion.minor_text = std::move(minor_text);
-  SetSuggestionLabelsForCard(
-      credit_card, client,
-      is_manual_fallback ? CREDIT_CARD_NUMBER : trigger_field_type,
-      metadata_logging_context, suggestion);
-  SetCardArtURL(suggestion, credit_card,
-                client.GetPersonalDataManager()->payments_data_manager(),
-                virtual_card_option);
-
-  // For virtual cards, make some adjustments for the suggestion contents.
-  if (virtual_card_option) {
-    // We don't show card linked offers for virtual card options.
-    AdjustVirtualCardSuggestionContent(suggestion, credit_card, client,
-                                       trigger_field_type);
-  } else if (card_linked_offer_available) {
-#if BUILDFLAG(IS_ANDROID)
-    // For Keyboard Accessory, set Suggestion::feature_for_iph and change the
-    // suggestion icon only if card linked offers are also enabled.
-    if (base::FeatureList::IsEnabled(
-            features::kAutofillEnableOffersInClankKeyboardAccessory)) {
-      suggestion.feature_for_iph =
-          &feature_engagement::kIPHKeyboardAccessoryPaymentOfferFeature;
-      suggestion.icon = Suggestion::Icon::kOfferTag;
-    } else {
-#else   // Add the offer label on Desktop unconditionally.
-    {
-#endif  // BUILDFLAG(IS_ANDROID)
-      suggestion.labels.push_back(
-          std::vector<Suggestion::Text>{Suggestion::Text(
-              l10n_util::GetStringUTF16(IDS_AUTOFILL_OFFERS_CASHBACK))});
-    }
-  }
-
-  if (virtual_card_option) {
-    suggestion.acceptance_a11y_announcement = l10n_util::GetStringUTF16(
-        IDS_AUTOFILL_A11Y_ANNOUNCE_VIRTUAL_CARD_MANUAL_FALLBACK_ENTRY);
-  } else if (is_manual_fallback) {
-    AddPaymentsGranularFillingChildSuggestions(
-        credit_card, suggestion,
-        client.GetPersonalDataManager()->payments_data_manager().app_locale());
-    suggestion.acceptance_a11y_announcement = l10n_util::GetStringUTF16(
-        IDS_AUTOFILL_A11Y_ANNOUNCE_EXPANDABLE_ONLY_ENTRY);
-  } else {
-    suggestion.acceptance_a11y_announcement =
-        l10n_util::GetStringUTF16(IDS_AUTOFILL_A11Y_ANNOUNCE_FILLED_FORM);
-  }
-
-  return suggestion;
+bool ShouldShowVirtualCardOptionForTest(const CreditCard* candidate_card,
+                                        const AutofillClient& client) {
+  return ShouldShowVirtualCardOption(candidate_card, client);
 }
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/payments_suggestion_generator.h b/components/autofill/core/browser/payments_suggestion_generator.h
index 1ef71aa..2727d0b 100644
--- a/components/autofill/core/browser/payments_suggestion_generator.h
+++ b/components/autofill/core/browser/payments_suggestion_generator.h
@@ -5,12 +5,14 @@
 #ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_SUGGESTION_GENERATOR_H_
 #define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_SUGGESTION_GENERATOR_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "base/check_deref.h"
 #include "base/containers/flat_map.h"
 #include "base/memory/raw_ptr.h"
+#include "base/types/optional_ref.h"
 #include "components/autofill/core/browser/data_model/autofill_wallet_usage_data.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/browser/metrics/log_event.h"
@@ -27,122 +29,100 @@
 class FormFieldData;
 class Iban;
 
-// Helper class to generate Autofill suggestions, such as for credit card and
-// address profile Autofill.
-class PaymentsSuggestionGenerator {
- public:
-  // Describes the suggestions returned by
-  // `GetSuggestionsForCreditCards()`.
-  struct CreditCardSuggestionSummary {
-    // Whether any card has card-linked offers.
-    bool with_offer = false;
-    // True if any card has a saved CVC.
-    bool with_cvc = false;
-    // Contains card metadata related information used for metrics logging.
-    autofill_metrics::CardMetadataLoggingContext metadata_logging_context;
-  };
-  PaymentsSuggestionGenerator();
-  ~PaymentsSuggestionGenerator();
-  PaymentsSuggestionGenerator(const PaymentsSuggestionGenerator&) = delete;
-  PaymentsSuggestionGenerator& operator=(const PaymentsSuggestionGenerator&) =
-      delete;
-
-  // Generates suggestions for all available credit cards based on the
-  // `trigger_field_type`, `trigger_field` and `trigger_source`.
-  // `summary` contains metadata about the returned suggestions.
-  std::vector<Suggestion> GetSuggestionsForCreditCards(
-      const AutofillClient& client,
-      const FormFieldData& trigger_field,
-      FieldType trigger_field_type,
-      AutofillSuggestionTriggerSource trigger_source,
-      bool should_show_scan_credit_card,
-      bool should_show_cards_from_account,
-      CreditCardSuggestionSummary& summary);
-
-  // Generates suggestions for standalone CVC fields. These only apply to
-  // virtual cards that are saved on file to a merchant. In these cases,
-  // we only display the virtual card option and do not show FPAN option.
-  std::vector<Suggestion> GetSuggestionsForVirtualCardStandaloneCvc(
-      const AutofillClient& client,
-      const FormFieldData& trigger_field,
-      autofill_metrics::CardMetadataLoggingContext& metadata_logging_context,
-      base::flat_map<std::string, VirtualCardUsageData::VirtualCardLastFour>&
-          virtual_card_guid_to_last_four_map);
-
-  // Returns the credit cards to be shown in touch to fill suggestions.
-  std::vector<CreditCard> GetTouchToFillCardsToSuggest(
-      const AutofillClient& client,
-      const FormFieldData& trigger_field,
-      FieldType trigger_field_type);
-
-  // Generates a footer suggestion "Manage payment methods..." menu item which
-  // will redirect to Chrome payment settings page. `with_gpay_logo` is used to
-  // conditionally add GPay logo icon to the manage payment methods suggestion.
-  //
-  // The difference between `CreateManageCreditCardsEntry()` and
-  // `CreateManageIbansEntry()` is that they use a different `SuggestionType`.
-  // This distinction is needed for metrics recording.
-  static Suggestion CreateManageCreditCardsEntry(bool with_gpay_logo);
-
-  // Generates a footer suggestion "Manage payment methods..." menu item which
-  // will redirect to Chrome payment settings page.
-  //
-  // The difference between `CreateManageCreditCardsEntry()` and
-  // `CreateManageIbansEntry()` is that they use a different `SuggestionType`.
-  // This distinction is needed for metrics recording.
-  static Suggestion CreateManageIbansEntry();
-
-  // Generates suggestions for all available IBANs.
-  static std::vector<Suggestion> GetSuggestionsForIbans(
-      const std::vector<Iban>& ibans);
-
-  // Converts the vector of promo code offers that is passed in to a vector of
-  // suggestions that can be displayed to the user for a promo code field.
-  static std::vector<Suggestion> GetPromoCodeSuggestionsFromPromoCodeOffers(
-      const std::vector<const AutofillOfferData*>& promo_code_offers);
-
-  // Returns true if the suggestion created from the card is acceptable, returns
-  // false when merchant does not accept the given card for example when
-  // merchants opt-out of VCNs.
-  bool IsCardAcceptable(const CreditCard& card,
-                        const AutofillClient& client,
-                        bool is_manual_fallback);
-
- private:
-  friend class PaymentsSuggestionGeneratorTestApi;
-
-  // Returns the local and server cards ordered by the Autofill ranking.
-  // If `suppress_disused_cards`, local expired disused cards are removed.
-  // If `prefix_match`, cards are matched with the contents of `trigger_field`.
-  // If `include_virtual_cards`, virtual cards will be added when possible.
-  std::vector<CreditCard> GetOrderedCardsToSuggest(
-      const AutofillClient& client,
-      const FormFieldData& trigger_field,
-      FieldType trigger_field_type,
-      bool suppress_disused_cards,
-      bool prefix_match,
-      bool include_virtual_cards);
-
-  // Creates a suggestion for the given `credit_card`. `virtual_card_option`
-  // suggests whether the suggestion is a virtual card option.
-  // `card_linked_offer_available` indicates whether a card-linked offer is
-  // attached to the `credit_card`. `metadata_logging_context` contains card
-  // metadata related information used for metrics logging.
-  Suggestion CreateCreditCardSuggestion(
-      const CreditCard& credit_card,
-      const AutofillClient& client,
-      FieldType trigger_field_type,
-      bool virtual_card_option,
-      bool card_linked_offer_available,
-      autofill_metrics::CardMetadataLoggingContext& metadata_logging_context);
-
-  // Helper function to decide whether to show the virtual card option for
-  // `candidate_card`.
-  // TODO(b/326950201): Pass the argument by reference.
-  bool ShouldShowVirtualCardOption(const CreditCard* candidate_card,
-                                   const AutofillClient& client);
+// Describes the suggestions returned by
+// `GetSuggestionsForCreditCards()`.
+struct CreditCardSuggestionSummary {
+  // Whether any card has card-linked offers.
+  bool with_offer = false;
+  // True if any card has a saved CVC.
+  bool with_cvc = false;
+  // Contains card metadata related information used for metrics logging.
+  autofill_metrics::CardMetadataLoggingContext metadata_logging_context;
 };
 
+// Generates suggestions for all available credit cards based on the
+// `trigger_field_type`, `trigger_field` and `trigger_source`.
+// `summary` contains metadata about the returned suggestions.
+std::vector<Suggestion> GetSuggestionsForCreditCards(
+    const AutofillClient& client,
+    const FormFieldData& trigger_field,
+    FieldType trigger_field_type,
+    AutofillSuggestionTriggerSource trigger_source,
+    bool should_show_scan_credit_card,
+    bool should_show_cards_from_account,
+    CreditCardSuggestionSummary& summary);
+
+// Generates suggestions for standalone CVC fields. These only apply to
+// virtual cards that are saved on file to a merchant. In these cases,
+// we only display the virtual card option and do not show FPAN option.
+std::vector<Suggestion> GetSuggestionsForVirtualCardStandaloneCvc(
+    const AutofillClient& client,
+    const FormFieldData& trigger_field,
+    autofill_metrics::CardMetadataLoggingContext& metadata_logging_context,
+    base::flat_map<std::string, VirtualCardUsageData::VirtualCardLastFour>&
+        virtual_card_guid_to_last_four_map);
+
+// Returns the credit cards to be shown in touch to fill suggestions.
+std::vector<CreditCard> GetTouchToFillCardsToSuggest(
+    const AutofillClient& client,
+    const FormFieldData& trigger_field,
+    FieldType trigger_field_type);
+
+// Generates a footer suggestion "Manage payment methods..." menu item which
+// will redirect to Chrome payment settings page. `with_gpay_logo` is used to
+// conditionally add GPay logo icon to the manage payment methods suggestion.
+//
+// The difference between `CreateManageCreditCardsSuggestion()` and
+// `CreateManageIbansSuggestion()` is that they use a different
+// `SuggestionType`. This distinction is needed for metrics recording.
+Suggestion CreateManageCreditCardsSuggestion(bool with_gpay_logo);
+
+// Generates a footer suggestion "Manage payment methods..." menu item which
+// will redirect to Chrome payment settings page.
+//
+// The difference between `CreateManageCreditCardsSuggestion()` and
+// `CreateManageIbansSuggestion()` is that they use a different
+// `SuggestionType`. This distinction is needed for metrics recording.
+Suggestion CreateManageIbansSuggestion();
+
+// Generates suggestions for all available IBANs.
+std::vector<Suggestion> GetSuggestionsForIbans(const std::vector<Iban>& ibans);
+
+// Converts the vector of promo code offers that is passed in to a vector of
+// suggestions that can be displayed to the user for a promo code field.
+std::vector<Suggestion> GetPromoCodeSuggestionsFromPromoCodeOffers(
+    const std::vector<const AutofillOfferData*>& promo_code_offers);
+
+// Returns true if the suggestion created from the card can be accepted by the
+// user. Returns false when merchant does not accept the given card for example
+// when merchants opt-out of VCNs.
+bool IsCardSuggestionAcceptable(const CreditCard& card,
+                                const AutofillClient& client,
+                                bool is_manual_fallback);
+
+// Exposes `GetOrderedCardsToSuggest` in tests.
+std::vector<CreditCard> GetOrderedCardsToSuggestForTest(
+    const AutofillClient& client,
+    const FormFieldData& trigger_field,
+    FieldType trigger_field_type,
+    bool suppress_disused_cards,
+    bool prefix_match,
+    bool include_virtual_cards);
+
+// Exposes `CreateCreditCardSuggestion` in tests.
+Suggestion CreateCreditCardSuggestionForTest(
+    const CreditCard& credit_card,
+    const AutofillClient& client,
+    FieldType trigger_field_type,
+    bool virtual_card_option,
+    bool card_linked_offer_available,
+    base::optional_ref<autofill_metrics::CardMetadataLoggingContext>
+        metadata_logging_context = std::nullopt);
+
+// Exposes `ShouldShowVirtualCardOption` in tests.
+bool ShouldShowVirtualCardOptionForTest(const CreditCard* candidate_card,
+                                        const AutofillClient& client);
+
 }  // namespace autofill
 
 #endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_SUGGESTION_GENERATOR_H_
diff --git a/components/autofill/core/browser/payments_suggestion_generator_test_api.h b/components/autofill/core/browser/payments_suggestion_generator_test_api.h
deleted file mode 100644
index d26547a5..0000000
--- a/components/autofill/core/browser/payments_suggestion_generator_test_api.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2024 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_SUGGESTION_GENERATOR_TEST_API_H_
-#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_SUGGESTION_GENERATOR_TEST_API_H_
-
-#include "components/autofill/core/browser/field_types.h"
-#include "components/autofill/core/browser/metrics/payments/card_metadata_metrics.h"
-#include "components/autofill/core/browser/payments_suggestion_generator.h"
-#include "components/autofill/core/common/aliases.h"
-#include "components/autofill/core/common/form_field_data.h"
-
-namespace autofill {
-
-// Exposes some testing operations for BrowserAutofillManager.
-class PaymentsSuggestionGeneratorTestApi {
- public:
-  explicit PaymentsSuggestionGeneratorTestApi(
-      PaymentsSuggestionGenerator& suggestion_generator)
-      : suggestion_generator_(suggestion_generator) {}
-
-  std::vector<CreditCard> GetOrderedCardsToSuggest(
-      const AutofillClient& client,
-      const FormFieldData& trigger_field,
-      FieldType trigger_field_type,
-      bool suppress_disused_cards,
-      bool prefix_match,
-      bool include_virtual_cards) {
-    return suggestion_generator_->GetOrderedCardsToSuggest(
-        client, trigger_field, trigger_field_type, suppress_disused_cards,
-        prefix_match, include_virtual_cards);
-  }
-
-  Suggestion CreateCreditCardSuggestion(
-      const CreditCard& credit_card,
-      const AutofillClient& client,
-      FieldType trigger_field_type,
-      bool virtual_card_option,
-      bool card_linked_offer_available,
-      url::Origin origin = url::Origin()) const {
-    autofill_metrics::CardMetadataLoggingContext metadata_logging_context;
-    return suggestion_generator_->CreateCreditCardSuggestion(
-        credit_card, client, trigger_field_type, virtual_card_option,
-        card_linked_offer_available, metadata_logging_context);
-  }
-
-  Suggestion CreateCreditCardSuggestionWithMetadataContext(
-      const CreditCard& credit_card,
-      const AutofillClient& client,
-      FieldType trigger_field_type,
-      bool virtual_card_option,
-      bool card_linked_offer_available,
-      autofill_metrics::CardMetadataLoggingContext& metadata_logging_context,
-      url::Origin origin = url::Origin()) const {
-    return suggestion_generator_->CreateCreditCardSuggestion(
-        credit_card, client, trigger_field_type, virtual_card_option,
-        card_linked_offer_available, metadata_logging_context);
-  }
-
-  // TODO(b/326950201): Remove and use GetOrderedCardsToSuggest instead.
-  bool ShouldShowVirtualCardOption(const CreditCard* candidate_card,
-                                   const AutofillClient& client) {
-    return suggestion_generator_->ShouldShowVirtualCardOption(candidate_card,
-                                                              client);
-  }
-
- private:
-  raw_ref<PaymentsSuggestionGenerator> suggestion_generator_;
-};
-
-inline PaymentsSuggestionGeneratorTestApi test_api(
-    PaymentsSuggestionGenerator& suggestion_generator) {
-  return PaymentsSuggestionGeneratorTestApi(suggestion_generator);
-}
-
-}  // namespace autofill
-
-#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_SUGGESTION_GENERATOR_TEST_API_H_
diff --git a/components/autofill/core/browser/payments_suggestion_generator_unittest.cc b/components/autofill/core/browser/payments_suggestion_generator_unittest.cc
index 8346c3a..195294e 100644
--- a/components/autofill/core/browser/payments_suggestion_generator_unittest.cc
+++ b/components/autofill/core/browser/payments_suggestion_generator_unittest.cc
@@ -26,7 +26,6 @@
 #include "components/autofill/core/browser/mock_autofill_optimization_guide.h"
 #include "components/autofill/core/browser/payments/constants.h"
 #include "components/autofill/core/browser/payments_data_manager.h"
-#include "components/autofill/core/browser/payments_suggestion_generator_test_api.h"
 #include "components/autofill/core/browser/test_autofill_client.h"
 #include "components/autofill/core/browser/test_payments_data_manager.h"
 #include "components/autofill/core/browser/test_personal_data_manager.h"
@@ -178,7 +177,6 @@
     autofill_client_.SetPrefs(test::PrefServiceForTesting());
     payments_data().SetPrefService(autofill_client_.GetPrefs());
     payments_data().SetSyncServiceForTest(&sync_service_);
-    suggestion_generator_ = std::make_unique<PaymentsSuggestionGenerator>();
     autofill_client_.set_autofill_offer_manager(
         std::make_unique<AutofillOfferManager>(
             autofill_client_.GetPersonalDataManager(),
@@ -247,10 +245,6 @@
 #endif
   }
 
-  PaymentsSuggestionGenerator& suggestion_generator() {
-    return *suggestion_generator_.get();
-  }
-
   TestPaymentsDataManager& payments_data() {
     return autofill_client_.GetPersonalDataManager()
         ->test_payments_data_manager();
@@ -266,7 +260,6 @@
   test::AutofillUnitTestEnvironment autofill_test_environment_;
   syncer::TestSyncService sync_service_;
   TestAutofillClient autofill_client_;
-  std::unique_ptr<PaymentsSuggestionGenerator> suggestion_generator_;
   testing::NiceMock<ui::MockResourceBundleDelegate> mock_resource_delegate_;
   raw_ptr<ui::ResourceBundle> original_resource_bundle_;
   // Tracks whether SetUpIbanImageResources() has been called, so that the
@@ -356,11 +349,10 @@
   // benefits in MetadataLoggingContext.
   void DoBenefitSuggestionLabel_MetadataLoggingContextTest() {
     autofill_metrics::CardMetadataLoggingContext metadata_logging_context;
-    test_api(suggestion_generator())
-        .CreateCreditCardSuggestionWithMetadataContext(
-            card(), *autofill_client(), CREDIT_CARD_NUMBER,
-            /*virtual_card_option=*/false,
-            /*card_linked_offer_available=*/false, metadata_logging_context);
+    CreateCreditCardSuggestionForTest(
+        card(), *autofill_client(), CREDIT_CARD_NUMBER,
+        /*virtual_card_option=*/false,
+        /*card_linked_offer_available=*/false, &metadata_logging_context);
 
     base::flat_map<int64_t, std::string>
         expected_instrument_ids_to_issuer_ids_with_benefits_available = {
@@ -387,11 +379,10 @@
 // Checks that for FPAN suggestions that the benefit description is displayed.
 TEST_P(AutofillCreditCardBenefitsLabelTest, BenefitSuggestionLabel_Fpan) {
   EXPECT_THAT(
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(card(), *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false)
+      CreateCreditCardSuggestionForTest(card(), *autofill_client(),
+                                        CREDIT_CARD_NUMBER,
+                                        /*virtual_card_option=*/false,
+                                        /*card_linked_offer_available=*/false)
           .labels,
       testing::ElementsAre(
           std::vector<Suggestion::Text>{
@@ -404,11 +395,10 @@
 // FPAN suggestions with benefits labels.
 TEST_P(AutofillCreditCardBenefitsLabelTest,
        BenefitSuggestionFeatureForIph_Fpan) {
-  EXPECT_EQ(test_api(suggestion_generator())
-                .CreateCreditCardSuggestion(
-                    card(), *autofill_client(), CREDIT_CARD_NUMBER,
-                    /*virtual_card_option=*/false,
-                    /*card_linked_offer_available=*/false)
+  EXPECT_EQ(CreateCreditCardSuggestionForTest(
+                card(), *autofill_client(), CREDIT_CARD_NUMBER,
+                /*virtual_card_option=*/false,
+                /*card_linked_offer_available=*/false)
                 .feature_for_iph,
             &feature_engagement::kIPHAutofillCreditCardBenefitFeature);
 }
@@ -417,11 +407,10 @@
 // virtual card suggestions with benefits labels.
 TEST_P(AutofillCreditCardBenefitsLabelTest,
        BenefitSuggestionFeatureForIph_VirtualCard) {
-  EXPECT_EQ(test_api(suggestion_generator())
-                .CreateCreditCardSuggestion(
-                    card(), *autofill_client(), CREDIT_CARD_NUMBER,
-                    /*virtual_card_option=*/true,
-                    /*card_linked_offer_available=*/false)
+  EXPECT_EQ(CreateCreditCardSuggestionForTest(
+                card(), *autofill_client(), CREDIT_CARD_NUMBER,
+                /*virtual_card_option=*/true,
+                /*card_linked_offer_available=*/false)
                 .feature_for_iph,
             &feature_engagement::kIPHAutofillVirtualCardSuggestionFeature);
 }
@@ -431,11 +420,10 @@
 TEST_P(AutofillCreditCardBenefitsLabelTest,
        BenefitSuggestionLabel_VirtualCard) {
   EXPECT_THAT(
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(card(), *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/true,
-                                      /*card_linked_offer_available=*/false)
+      CreateCreditCardSuggestionForTest(card(), *autofill_client(),
+                                        CREDIT_CARD_NUMBER,
+                                        /*virtual_card_option=*/true,
+                                        /*card_linked_offer_available=*/false)
           .labels,
       testing::ElementsAre(
           std::vector<Suggestion::Text>{
@@ -476,11 +464,10 @@
       GURL("https://random-url.com"));
   // Merchant benefit description is not returned.
   EXPECT_THAT(
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(card(), *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false)
+      CreateCreditCardSuggestionForTest(card(), *autofill_client(),
+                                        CREDIT_CARD_NUMBER,
+                                        /*virtual_card_option=*/false,
+                                        /*card_linked_offer_available=*/false)
           .labels,
       testing::ElementsAre(
           std::vector<Suggestion::Text>{Suggestion::Text(card().GetInfo(
@@ -504,11 +491,10 @@
 
   // Category benefit description is not returned.
   EXPECT_THAT(
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(card(), *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false)
+      CreateCreditCardSuggestionForTest(card(), *autofill_client(),
+                                        CREDIT_CARD_NUMBER,
+                                        /*virtual_card_option=*/false,
+                                        /*card_linked_offer_available=*/false)
           .labels,
       testing::ElementsAre(
           std::vector<Suggestion::Text>{Suggestion::Text(card().GetInfo(
@@ -526,11 +512,10 @@
 
   // Benefit description is not returned.
   EXPECT_THAT(
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(card(), *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false)
+      CreateCreditCardSuggestionForTest(card(), *autofill_client(),
+                                        CREDIT_CARD_NUMBER,
+                                        /*virtual_card_option=*/false,
+                                        /*card_linked_offer_available=*/false)
           .labels,
       testing::ElementsAre(
           std::vector<Suggestion::Text>{Suggestion::Text(card().GetInfo(
@@ -554,13 +539,12 @@
   ASSERT_FALSE(card.HasRawInfo(PHONE_HOME_WHOLE_NUMBER));
   payments_data().AddCreditCard(card);
 
-  PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-  std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForCreditCards(
-          *autofill_client(), FormFieldData(), CREDIT_CARD_NAME_FULL,
-          AutofillSuggestionTriggerSource::kManualFallbackPayments,
-          /*should_show_scan_credit_card=*/false,
-          /*should_show_cards_from_account=*/false, summary);
+  CreditCardSuggestionSummary summary;
+  std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+      *autofill_client(), FormFieldData(), CREDIT_CARD_NAME_FULL,
+      AutofillSuggestionTriggerSource::kManualFallbackPayments,
+      /*should_show_scan_credit_card=*/false,
+      /*should_show_cards_from_account=*/false, summary);
 
   ASSERT_EQ(3u, suggestions.size());
   EXPECT_EQ(suggestions[0].type, SuggestionType::kCreditCardEntry);
@@ -571,7 +555,7 @@
   EXPECT_THAT(suggestions,
               ContainsCreditCardFooterSuggestions(/*with_gpay_logo=*/false));
 
-  suggestions = suggestion_generator().GetSuggestionsForCreditCards(
+  suggestions = GetSuggestionsForCreditCards(
       *autofill_client(), FormFieldData(), CREDIT_CARD_VERIFICATION_CODE,
       AutofillSuggestionTriggerSource::kManualFallbackPayments,
       /*should_show_scan_credit_card=*/false,
@@ -613,12 +597,10 @@
     }
   }
   base::HistogramTester histogram_tester;
-  std::vector<CreditCard> cards_to_suggest =
-      test_api(suggestion_generator())
-          .GetOrderedCardsToSuggest(
-              *autofill_client(), FormFieldData(), UNKNOWN_TYPE,
-              /*suppress_disused_cards=*/true,
-              /*prefix_match=*/false, /*include_virtual_cards=*/false);
+  std::vector<CreditCard> cards_to_suggest = GetOrderedCardsToSuggestForTest(
+      *autofill_client(), FormFieldData(), UNKNOWN_TYPE,
+      /*suppress_disused_cards=*/true,
+      /*prefix_match=*/false, /*include_virtual_cards=*/false);
 
   // Expect that only the last card (disused, expired and local) is removed.
   credit_cards.pop_back();
@@ -646,11 +628,11 @@
   auto get_cards = [&](std::u16string field_value) {
     FormFieldData field;
     field.set_value(std::move(field_value));
-    return test_api(suggestion_generator())
-        .GetOrderedCardsToSuggest(*autofill_client(), field, CREDIT_CARD_NUMBER,
-                                  /*suppress_disused_cards=*/false,
-                                  /*prefix_match=*/true,
-                                  /*include_virtual_cards=*/false);
+    return GetOrderedCardsToSuggestForTest(*autofill_client(), field,
+                                           CREDIT_CARD_NUMBER,
+                                           /*suppress_disused_cards=*/false,
+                                           /*prefix_match=*/true,
+                                           /*include_virtual_cards=*/false);
   };
 
   EXPECT_THAT(get_cards(u""), UnorderedElementsAre(card1, card2));
@@ -679,12 +661,11 @@
   auto get_cards = [&](std::u16string field_value) {
     FormFieldData field;
     field.set_value(std::move(field_value));
-    return test_api(suggestion_generator())
-        .GetOrderedCardsToSuggest(*autofill_client(), field,
-                                  CREDIT_CARD_VERIFICATION_CODE,
-                                  /*suppress_disused_cards=*/false,
-                                  /*prefix_match=*/true,
-                                  /*include_virtual_cards=*/false);
+    return GetOrderedCardsToSuggestForTest(*autofill_client(), field,
+                                           CREDIT_CARD_VERIFICATION_CODE,
+                                           /*suppress_disused_cards=*/false,
+                                           /*prefix_match=*/true,
+                                           /*include_virtual_cards=*/false);
   };
 
   EXPECT_THAT(get_cards(u""), ElementsAre(credit_card));
@@ -701,13 +682,12 @@
                           base::Days(1));
   payments_data().AddCreditCard(local_card);
 
-  PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-  std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForCreditCards(
-          *autofill_client(), FormFieldData(), UNKNOWN_TYPE,
-          AutofillSuggestionTriggerSource::kManualFallbackPayments,
-          /*should_show_scan_credit_card=*/false,
-          /*should_show_cards_from_account=*/false, summary);
+  CreditCardSuggestionSummary summary;
+  std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+      *autofill_client(), FormFieldData(), UNKNOWN_TYPE,
+      AutofillSuggestionTriggerSource::kManualFallbackPayments,
+      /*should_show_scan_credit_card=*/false,
+      /*should_show_cards_from_account=*/false, summary);
 
   EXPECT_FALSE(suggestions.empty());
 }
@@ -760,13 +740,12 @@
       GURL("http://www.example1.com"));
   payments_data().AddAutofillOfferData(offer_data);
 
-  PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-  std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForCreditCards(
-          *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
-          kDefaultTriggerSource,
-          /*should_show_scan_credit_card=*/false,
-          /*should_show_cards_from_account=*/false, summary);
+  CreditCardSuggestionSummary summary;
+  std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+      *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
+      kDefaultTriggerSource,
+      /*should_show_scan_credit_card=*/false,
+      /*should_show_cards_from_account=*/false, summary);
 
   EXPECT_TRUE(summary.with_offer);
   ASSERT_EQ(suggestions.size(), 5U);
@@ -799,7 +778,7 @@
       {server_card.guid(), VirtualCardUsageData::VirtualCardLastFour(u"1234")});
   autofill_metrics::CardMetadataLoggingContext metadata_logging_context;
   std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForVirtualCardStandaloneCvc(
+      GetSuggestionsForVirtualCardStandaloneCvc(
           *autofill_client(), FormFieldData(), metadata_logging_context,
           virtual_card_guid_to_last_four_map);
 
@@ -822,7 +801,7 @@
   FormFieldData field;
   field.set_is_autofilled(true);
   std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForVirtualCardStandaloneCvc(
+      GetSuggestionsForVirtualCardStandaloneCvc(
           *autofill_client(), field, metadata_logging_context,
           virtual_card_guid_to_last_four_map);
 
@@ -841,13 +820,12 @@
   CreditCard card = test::WithCvc(test::GetMaskedServerCard2());
   payments_data().AddServerCreditCard(card);
 
-  PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-  std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForCreditCards(
-          *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
-          kDefaultTriggerSource,
-          /*should_show_scan_credit_card=*/false,
-          /*should_show_cards_from_account=*/false, summary);
+  CreditCardSuggestionSummary summary;
+  std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+      *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
+      kDefaultTriggerSource,
+      /*should_show_scan_credit_card=*/false,
+      /*should_show_cards_from_account=*/false, summary);
 
   ASSERT_EQ(suggestions.size(), 3U);
   EXPECT_TRUE(summary.with_cvc);
@@ -867,13 +845,12 @@
         /*guid=*/"00000000-0000-0000-0000-000000000002",
         /*server_id=*/"server_id2", /*instrument_id=*/2));
 
-    PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-    std::vector<Suggestion> suggestions =
-        suggestion_generator().GetSuggestionsForCreditCards(
-            *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
-            kDefaultTriggerSource,
-            /*should_show_scan_credit_card=*/false,
-            /*should_show_cards_from_account=*/false, summary);
+    CreditCardSuggestionSummary summary;
+    std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+        *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
+        kDefaultTriggerSource,
+        /*should_show_scan_credit_card=*/false,
+        /*should_show_cards_from_account=*/false, summary);
 
     EXPECT_EQ(suggestions.size(), 4U);
     EXPECT_THAT(suggestions,
@@ -894,13 +871,12 @@
         /*guid=*/"00000000-0000-0000-0000-000000000002",
         /*server_id=*/"server_id2", /*instrument_id=*/2));
 
-    PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-    std::vector<Suggestion> suggestions =
-        suggestion_generator().GetSuggestionsForCreditCards(
-            *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
-            kDefaultTriggerSource,
-            /*should_show_scan_credit_card=*/false,
-            /*should_show_cards_from_account=*/false, summary);
+    CreditCardSuggestionSummary summary;
+    std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+        *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
+        kDefaultTriggerSource,
+        /*should_show_scan_credit_card=*/false,
+        /*should_show_cards_from_account=*/false, summary);
 
     EXPECT_EQ(suggestions.size(), 4U);
     EXPECT_THAT(suggestions,
@@ -923,13 +899,12 @@
         /*guid=*/"00000000-0000-0000-0000-000000000002",
         /*server_id=*/"server_id2", /*instrument_id=*/2));
 
-    PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-    std::vector<Suggestion> suggestions =
-        suggestion_generator().GetSuggestionsForCreditCards(
-            *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
-            kDefaultTriggerSource,
-            /*should_show_scan_credit_card=*/false,
-            /*should_show_cards_from_account=*/false, summary);
+    CreditCardSuggestionSummary summary;
+    std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+        *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
+        kDefaultTriggerSource,
+        /*should_show_scan_credit_card=*/false,
+        /*should_show_cards_from_account=*/false, summary);
 
     EXPECT_EQ(suggestions.size(), 3U);
     EXPECT_THAT(suggestions,
@@ -940,25 +915,23 @@
 TEST_F(PaymentsSuggestionGeneratorTest, NoSuggestionsWhenNoUserData) {
   FormFieldData field;
   field.set_is_autofilled(true);
-  PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-  std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForCreditCards(
-          *autofill_client(), field, CREDIT_CARD_NUMBER, kDefaultTriggerSource,
-          /*should_show_scan_credit_card=*/true,
-          /*should_show_cards_from_account=*/true, summary);
+  CreditCardSuggestionSummary summary;
+  std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+      *autofill_client(), field, CREDIT_CARD_NUMBER, kDefaultTriggerSource,
+      /*should_show_scan_credit_card=*/true,
+      /*should_show_cards_from_account=*/true, summary);
 
   EXPECT_TRUE(suggestions.empty());
 }
 
 TEST_F(PaymentsSuggestionGeneratorTest, ShouldShowScanCreditCard) {
   payments_data().AddCreditCard(test::GetCreditCard());
-  PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-  std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForCreditCards(
-          *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
-          kDefaultTriggerSource,
-          /*should_show_scan_credit_card=*/true,
-          /*should_show_cards_from_account=*/false, summary);
+  CreditCardSuggestionSummary summary;
+  std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+      *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
+      kDefaultTriggerSource,
+      /*should_show_scan_credit_card=*/true,
+      /*should_show_cards_from_account=*/false, summary);
 
   EXPECT_EQ(suggestions.size(), 4ul);
   EXPECT_THAT(suggestions[0],
@@ -974,13 +947,12 @@
 
 TEST_F(PaymentsSuggestionGeneratorTest, ShouldShowCardsFromAccount) {
   payments_data().AddCreditCard(test::GetCreditCard());
-  PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-  std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForCreditCards(
-          *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
-          kDefaultTriggerSource,
-          /*should_show_scan_credit_card=*/false,
-          /*should_show_cards_from_account=*/true, summary);
+  CreditCardSuggestionSummary summary;
+  std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+      *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
+      kDefaultTriggerSource,
+      /*should_show_scan_credit_card=*/false,
+      /*should_show_cards_from_account=*/true, summary);
 
   EXPECT_EQ(suggestions.size(), 4ul);
   EXPECT_THAT(suggestions[0],
@@ -1000,12 +972,11 @@
   payments_data().AddCreditCard(test::GetCreditCard());
   FormFieldData field;
   field.set_is_autofilled(true);
-  PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-  std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForCreditCards(
-          *autofill_client(), field, CREDIT_CARD_NUMBER, kDefaultTriggerSource,
-          /*should_show_scan_credit_card=*/false,
-          /*should_show_cards_from_account=*/false, summary);
+  CreditCardSuggestionSummary summary;
+  std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+      *autofill_client(), field, CREDIT_CARD_NUMBER, kDefaultTriggerSource,
+      /*should_show_scan_credit_card=*/false,
+      /*should_show_cards_from_account=*/false, summary);
 
   EXPECT_THAT(suggestions,
               ElementsAre(EqualsSuggestion(SuggestionType::kCreditCardEntry),
@@ -1032,11 +1003,9 @@
 
   // If all prerequisites are met, it should return true.
   EXPECT_TRUE(
-      test_api(suggestion_generator())
-          .ShouldShowVirtualCardOption(&server_card, *autofill_client()));
+      ShouldShowVirtualCardOptionForTest(&server_card, *autofill_client()));
   EXPECT_TRUE(
-      test_api(suggestion_generator())
-          .ShouldShowVirtualCardOption(&local_card, *autofill_client()));
+      ShouldShowVirtualCardOptionForTest(&local_card, *autofill_client()));
 }
 
 // Test that the virtual card option is shown when the autofill optimization
@@ -1057,11 +1026,9 @@
 
   // If all prerequisites are met, it should return true.
   EXPECT_TRUE(
-      test_api(suggestion_generator())
-          .ShouldShowVirtualCardOption(&server_card, *autofill_client()));
+      ShouldShowVirtualCardOptionForTest(&server_card, *autofill_client()));
   EXPECT_TRUE(
-      test_api(suggestion_generator())
-          .ShouldShowVirtualCardOption(&local_card, *autofill_client()));
+      ShouldShowVirtualCardOptionForTest(&local_card, *autofill_client()));
 }
 
 // Test that the virtual card option is shown even if the merchant is opted-out
@@ -1083,8 +1050,7 @@
           ShouldBlockFormFieldSuggestion)
       .WillByDefault(testing::Return(true));
   EXPECT_TRUE(
-      test_api(suggestion_generator())
-          .ShouldShowVirtualCardOption(&server_card, *autofill_client()));
+      ShouldShowVirtualCardOptionForTest(&server_card, *autofill_client()));
 }
 
 // Test that the virtual card option is not shown if the merchant is opted-out
@@ -1112,11 +1078,9 @@
           ShouldBlockFormFieldSuggestion)
       .WillByDefault(testing::Return(true));
   EXPECT_FALSE(
-      test_api(suggestion_generator())
-          .ShouldShowVirtualCardOption(&server_card, *autofill_client()));
+      ShouldShowVirtualCardOptionForTest(&server_card, *autofill_client()));
   EXPECT_FALSE(
-      test_api(suggestion_generator())
-          .ShouldShowVirtualCardOption(&local_card, *autofill_client()));
+      ShouldShowVirtualCardOptionForTest(&local_card, *autofill_client()));
 }
 
 // Test that the virtual card option is not shown if the server card we might be
@@ -1137,11 +1101,9 @@
   // For server card not enrolled, both local and server card should return
   // false.
   EXPECT_FALSE(
-      test_api(suggestion_generator())
-          .ShouldShowVirtualCardOption(&server_card, *autofill_client()));
+      ShouldShowVirtualCardOptionForTest(&server_card, *autofill_client()));
   EXPECT_FALSE(
-      test_api(suggestion_generator())
-          .ShouldShowVirtualCardOption(&local_card, *autofill_client()));
+      ShouldShowVirtualCardOptionForTest(&local_card, *autofill_client()));
 }
 
 // Test that the virtual card option is not shown for a local card with no
@@ -1154,8 +1116,7 @@
 
   // The local card does not have a server duplicate, should return false.
   EXPECT_FALSE(
-      test_api(suggestion_generator())
-          .ShouldShowVirtualCardOption(&local_card, *autofill_client()));
+      ShouldShowVirtualCardOptionForTest(&local_card, *autofill_client()));
 }
 
 TEST_F(PaymentsSuggestionGeneratorTest, GetLocalIbanSuggestions) {
@@ -1179,8 +1140,7 @@
   Iban iban3 = MakeLocalIban(u"PK70 BANK 0000 1234 5678 9000", u"");
 
   std::vector<Suggestion> iban_suggestions =
-      PaymentsSuggestionGenerator::GetSuggestionsForIbans(
-          {iban0, iban1, iban2, iban3});
+      GetSuggestionsForIbans({iban0, iban1, iban2, iban3});
 
   // There are 6 suggestions, 4 for IBAN suggestions, followed by a separator,
   // and followed by "Manage payment methods..." which redirects to the Chrome
@@ -1222,8 +1182,7 @@
   Iban server_iban3 = test::GetServerIban3();
 
   std::vector<Suggestion> iban_suggestions =
-      PaymentsSuggestionGenerator::GetSuggestionsForIbans(
-          {server_iban1, server_iban2, server_iban3});
+      GetSuggestionsForIbans({server_iban1, server_iban2, server_iban3});
 
   // There are 5 suggestions, 3 for IBAN suggestions, followed by a separator,
   // and followed by "Manage payment methods..." which redirects to the Chrome
@@ -1266,8 +1225,7 @@
   Iban local_iban1 = test::GetLocalIban();
 
   std::vector<Suggestion> iban_suggestions =
-      PaymentsSuggestionGenerator::GetSuggestionsForIbans(
-          {server_iban1, server_iban2, local_iban1});
+      GetSuggestionsForIbans({server_iban1, server_iban2, local_iban1});
 
   // There are 5 suggestions, 3 for IBAN suggestions, followed by a separator,
   // and followed by "Manage payment methods..." which redirects to the Chrome
@@ -1328,8 +1286,7 @@
   promo_code_offers.push_back(&offer2);
 
   std::vector<Suggestion> promo_code_suggestions =
-      PaymentsSuggestionGenerator::GetPromoCodeSuggestionsFromPromoCodeOffers(
-          promo_code_offers);
+      GetPromoCodeSuggestionsFromPromoCodeOffers(promo_code_offers);
   EXPECT_TRUE(promo_code_suggestions.size() == 4);
 
   EXPECT_EQ(promo_code_suggestions[0].main_text.value, u"test_promo_code_1");
@@ -1374,8 +1331,7 @@
   promo_code_offers.push_back(&offer);
 
   std::vector<Suggestion> promo_code_suggestions =
-      PaymentsSuggestionGenerator::GetPromoCodeSuggestionsFromPromoCodeOffers(
-          promo_code_offers);
+      GetPromoCodeSuggestionsFromPromoCodeOffers(promo_code_offers);
   EXPECT_TRUE(promo_code_suggestions.size() == 1);
 
   EXPECT_EQ(promo_code_suggestions[0].main_text.value, u"test_promo_code_1");
@@ -1437,11 +1393,10 @@
 
   // Name field suggestion for virtual cards.
   Suggestion virtual_card_name_field_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      CREDIT_CARD_NAME_FULL,
-                                      /*virtual_card_option=*/true,
-                                      /*card_linked_offer_available=*/false);
+      CreateCreditCardSuggestionForTest(server_card, *autofill_client(),
+                                        CREDIT_CARD_NAME_FULL,
+                                        /*virtual_card_option=*/true,
+                                        /*card_linked_offer_available=*/false);
 
   if (keyboard_accessory_enabled()) {
     // For the keyboard accessory, the "Virtual card" label is added as a prefix
@@ -1502,11 +1457,10 @@
 
   // Card number field suggestion for virtual cards.
   Suggestion virtual_card_number_field_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/true,
-                                      /*card_linked_offer_available=*/false);
+      CreateCreditCardSuggestionForTest(server_card, *autofill_client(),
+                                        CREDIT_CARD_NUMBER,
+                                        /*virtual_card_option=*/true,
+                                        /*card_linked_offer_available=*/false);
 
 #if BUILDFLAG(IS_IOS)
   // Only card number is displayed on the first line.
@@ -1552,11 +1506,10 @@
 
   // Name field suggestion for non-virtual cards.
   Suggestion real_card_name_field_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      CREDIT_CARD_NAME_FULL,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false);
+      CreateCreditCardSuggestionForTest(server_card, *autofill_client(),
+                                        CREDIT_CARD_NAME_FULL,
+                                        /*virtual_card_option=*/false,
+                                        /*card_linked_offer_available=*/false);
 
   // Only the name is displayed on the first line.
   EXPECT_EQ(real_card_name_field_suggestion.main_text.value, u"Elvis Presley");
@@ -1594,11 +1547,10 @@
 
   // Card number field suggestion for non-virtual cards.
   Suggestion real_card_number_field_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false);
+      CreateCreditCardSuggestionForTest(server_card, *autofill_client(),
+                                        CREDIT_CARD_NUMBER,
+                                        /*virtual_card_option=*/false,
+                                        /*card_linked_offer_available=*/false);
 
 #if BUILDFLAG(IS_IOS)
   // Only the card number is displayed on the first line.
@@ -1632,12 +1584,10 @@
        CreateCreditCardSuggestion_ManualFallback) {
   CreditCard server_card = CreateServerCard();
 
-  Suggestion server_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      UNKNOWN_TYPE,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false);
+  Suggestion server_card_suggestion = CreateCreditCardSuggestionForTest(
+      server_card, *autofill_client(), UNKNOWN_TYPE,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
 
   // Only the name is displayed on the first line.
   EXPECT_EQ(server_card_suggestion.type, SuggestionType::kCreditCardEntry);
@@ -1664,12 +1614,10 @@
        CreateCreditCardSuggestion_ManualFallback_VirtualCreditCard) {
   CreditCard enrolled_card = test::GetVirtualCard();
 
-  Suggestion enrolled_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(enrolled_card, *autofill_client(),
-                                      UNKNOWN_TYPE,
-                                      /*virtual_card_option=*/true,
-                                      /*card_linked_offer_available=*/false);
+  Suggestion enrolled_card_suggestion = CreateCreditCardSuggestionForTest(
+      enrolled_card, *autofill_client(), UNKNOWN_TYPE,
+      /*virtual_card_option=*/true,
+      /*card_linked_offer_available=*/false);
 
   // Only the name is displayed on the first line.
   EXPECT_EQ(enrolled_card_suggestion.type,
@@ -1685,12 +1633,10 @@
        CreateCreditCardSuggestion_ManualFallback_VirtualCreditCard_Labels) {
   CreditCard enrolled_card = test::GetVirtualCard();
 
-  Suggestion enrolled_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(enrolled_card, *autofill_client(),
-                                      UNKNOWN_TYPE,
-                                      /*virtual_card_option=*/true,
-                                      /*card_linked_offer_available=*/false);
+  Suggestion enrolled_card_suggestion = CreateCreditCardSuggestionForTest(
+      enrolled_card, *autofill_client(), UNKNOWN_TYPE,
+      /*virtual_card_option=*/true,
+      /*card_linked_offer_available=*/false);
 
   // For Desktop, split the first line and populate the card name and
   // the last 4 digits separately.
@@ -1717,12 +1663,10 @@
   CreditCard enrolled_card =
       test::GetMaskedServerCardEnrolledIntoVirtualCardNumber();
 
-  Suggestion enrolled_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(enrolled_card, *autofill_client(),
-                                      UNKNOWN_TYPE,
-                                      /*virtual_card_option=*/true,
-                                      /*card_linked_offer_available=*/false);
+  Suggestion enrolled_card_suggestion = CreateCreditCardSuggestionForTest(
+      enrolled_card, *autofill_client(), UNKNOWN_TYPE,
+      /*virtual_card_option=*/true,
+      /*card_linked_offer_available=*/false);
 
   EXPECT_TRUE(enrolled_card_suggestion.children.empty());
 }
@@ -1733,12 +1677,10 @@
        CreateCreditCardSuggestion_ManualFallback_NestedSuggestions) {
   CreditCard server_card = test::GetMaskedServerCard();
 
-  Suggestion server_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      UNKNOWN_TYPE,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false);
+  Suggestion server_card_suggestion = CreateCreditCardSuggestionForTest(
+      server_card, *autofill_client(), UNKNOWN_TYPE,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
 
   // The child suggestions should be:
   //
@@ -1782,12 +1724,10 @@
                           /*expiration_year*/ nullptr,
                           /*billing_address_id=*/"", /*cvc=*/u"123");
 
-  Suggestion server_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(credit_card, *autofill_client(),
-                                      UNKNOWN_TYPE,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false);
+  Suggestion server_card_suggestion = CreateCreditCardSuggestionForTest(
+      credit_card, *autofill_client(), UNKNOWN_TYPE,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
 
   // The child suggestions should be:
   //
@@ -1819,12 +1759,10 @@
                           test::NextYear().c_str(),
                           /*billing_address_id=*/"", /*cvc=*/u"123");
 
-  Suggestion server_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(credit_card, *autofill_client(),
-                                      UNKNOWN_TYPE,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false);
+  Suggestion server_card_suggestion = CreateCreditCardSuggestionForTest(
+      credit_card, *autofill_client(), UNKNOWN_TYPE,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
 
   // The child suggestions should be:
   //
@@ -1845,12 +1783,10 @@
        CreateCreditCardSuggestion_ManualFallback_NestedExpiryDateSuggestions) {
   CreditCard server_card = CreateServerCard();
 
-  Suggestion server_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      UNKNOWN_TYPE,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false);
+  Suggestion server_card_suggestion = CreateCreditCardSuggestionForTest(
+      server_card, *autofill_client(), UNKNOWN_TYPE,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
 
   // The expiry date child suggestions should be:
   //
@@ -1881,13 +1817,12 @@
 
   FormFieldData field_data;
   field_data.set_value(u"$$$");
-  PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-  std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForCreditCards(
-          *autofill_client(), field_data, UNKNOWN_TYPE,
-          AutofillSuggestionTriggerSource::kManualFallbackPayments,
-          /*should_show_scan_credit_card=*/false,
-          /*should_show_cards_from_account=*/false, summary);
+  CreditCardSuggestionSummary summary;
+  std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+      *autofill_client(), field_data, UNKNOWN_TYPE,
+      AutofillSuggestionTriggerSource::kManualFallbackPayments,
+      /*should_show_scan_credit_card=*/false,
+      /*should_show_cards_from_account=*/false, summary);
 
   // Credit card suggestions should not depend on the field's value.
   EXPECT_EQ(suggestions.size(), 3U);
@@ -1908,13 +1843,12 @@
   payments_data().AddCreditCard(std::move(local_card));
   payments_data().AddServerCreditCard(CreateServerCard());
 
-  PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-  const std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForCreditCards(
-          *autofill_client(), FormFieldData(), CREDIT_CARD_VERIFICATION_CODE,
-          kDefaultTriggerSource,
-          /*should_show_scan_credit_card=*/false,
-          /*should_show_cards_from_account=*/false, summary);
+  CreditCardSuggestionSummary summary;
+  const std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+      *autofill_client(), FormFieldData(), CREDIT_CARD_VERIFICATION_CODE,
+      kDefaultTriggerSource,
+      /*should_show_scan_credit_card=*/false,
+      /*should_show_cards_from_account=*/false, summary);
 
   // Both local card and server card suggestion should be shown when CVC field
   // is focused.
@@ -1942,13 +1876,12 @@
   payments_data().AddCreditCard(CreateLocalCard());
   payments_data().AddServerCreditCard(CreateServerCard());
 
-  PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-  const std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForCreditCards(
-          *autofill_client(), FormFieldData(), CREDIT_CARD_VERIFICATION_CODE,
-          kDefaultTriggerSource,
-          /*should_show_scan_credit_card=*/false,
-          /*should_show_cards_from_account=*/false, summary);
+  CreditCardSuggestionSummary summary;
+  const std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+      *autofill_client(), FormFieldData(), CREDIT_CARD_VERIFICATION_CODE,
+      kDefaultTriggerSource,
+      /*should_show_scan_credit_card=*/false,
+      /*should_show_cards_from_account=*/false, summary);
 
   // Only 1 suggestion + footer should be shown when CVC field is focused.
   ASSERT_EQ(suggestions.size(), 3U);
@@ -1966,13 +1899,12 @@
       CreditCard::VirtualCardEnrollmentState::kEnrolled);
   payments_data().AddServerCreditCard(std::move(server_card));
 
-  PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-  const std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForCreditCards(
-          *autofill_client(), FormFieldData(), CREDIT_CARD_VERIFICATION_CODE,
-          kDefaultTriggerSource,
-          /*should_show_scan_credit_card=*/false,
-          /*should_show_cards_from_account=*/false, summary);
+  CreditCardSuggestionSummary summary;
+  const std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+      *autofill_client(), FormFieldData(), CREDIT_CARD_VERIFICATION_CODE,
+      kDefaultTriggerSource,
+      /*should_show_scan_credit_card=*/false,
+      /*should_show_cards_from_account=*/false, summary);
 
   // Both FPAN and VCN suggestion should be shown when CVC field is focused.
   ASSERT_EQ(suggestions.size(), 4U);
@@ -2004,13 +1936,12 @@
   payments_data().AddServerCreditCard(std::move(server_card));
   payments_data().AddCreditCard(CreateLocalCard());
 
-  PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-  const std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForCreditCards(
-          *autofill_client(), FormFieldData(), CREDIT_CARD_VERIFICATION_CODE,
-          kDefaultTriggerSource,
-          /*should_show_scan_credit_card=*/false,
-          /*should_show_cards_from_account=*/false, summary);
+  CreditCardSuggestionSummary summary;
+  const std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+      *autofill_client(), FormFieldData(), CREDIT_CARD_VERIFICATION_CODE,
+      kDefaultTriggerSource,
+      /*should_show_scan_credit_card=*/false,
+      /*should_show_cards_from_account=*/false, summary);
 
   // Both FPAN and VCN suggestion should be shown when CVC field is focused.
   ASSERT_EQ(suggestions.size(), 4U);
@@ -2038,24 +1969,20 @@
   const std::u16string type_and_number =
       base::StrCat({card_type, u"  ", obfuscated_number});
 
-  Suggestion card_number_field_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false);
+  Suggestion card_number_field_suggestion = CreateCreditCardSuggestionForTest(
+      server_card, *autofill_client(), CREDIT_CARD_NUMBER,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
 
   // From the credit card number field, the suggestion should show the card type
   // and number and the label should show the expiration date.
   EXPECT_EQ(card_number_field_suggestion.main_text.value, type_and_number);
   EXPECT_THAT(card_number_field_suggestion, EqualLabels({{exp_date}}));
 
-  card_number_field_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      CREDIT_CARD_NAME_FULL,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false);
+  card_number_field_suggestion = CreateCreditCardSuggestionForTest(
+      server_card, *autofill_client(), CREDIT_CARD_NAME_FULL,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
 
   // From the credit card name field, the suggestion should show the full name
   // and the label should show the card type and number.
@@ -2063,12 +1990,10 @@
             base::StrCat({name_full}));
   EXPECT_THAT(card_number_field_suggestion, EqualLabels({{type_and_number}}));
 
-  card_number_field_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      CREDIT_CARD_EXP_MONTH,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false);
+  card_number_field_suggestion = CreateCreditCardSuggestionForTest(
+      server_card, *autofill_client(), CREDIT_CARD_EXP_MONTH,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
 
   // From a credit card expiry field, the suggestion should show the expiration
   // date and the label should show the card type and number.
@@ -2077,12 +2002,10 @@
   EXPECT_THAT(card_number_field_suggestion, EqualLabels({{type_and_number}}));
 
   server_card.set_record_type(CreditCard::RecordType::kVirtualCard);
-  card_number_field_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/true,
-                                      /*card_linked_offer_available=*/false);
+  card_number_field_suggestion = CreateCreditCardSuggestionForTest(
+      server_card, *autofill_client(), CREDIT_CARD_NUMBER,
+      /*virtual_card_option=*/true,
+      /*card_linked_offer_available=*/false);
 
   // From a virtual credit card, the suggestion should show the card name and
   // the label should show the card's virtual status, type and number.
@@ -2126,24 +2049,20 @@
   CreditCard server_card = CreateServerCard();
 
   // Name field suggestion.
-  Suggestion card_name_field_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      CREDIT_CARD_NAME_FULL,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false);
+  Suggestion card_name_field_suggestion = CreateCreditCardSuggestionForTest(
+      server_card, *autofill_client(), CREDIT_CARD_NAME_FULL,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
 
   EXPECT_THAT(card_name_field_suggestion,
               EqualLabels({{CreditCard::GetObfuscatedStringForCardDigits(
                   expected_obfuscation_length(), u"1111")}}));
 
   // Card number field suggestion.
-  Suggestion card_number_field_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false);
+  Suggestion card_number_field_suggestion = CreateCreditCardSuggestionForTest(
+      server_card, *autofill_client(), CREDIT_CARD_NUMBER,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
 
   EXPECT_EQ(
       card_number_field_suggestion.main_text.value,
@@ -2197,11 +2116,10 @@
 
   // Name field suggestion for virtual cards.
   Suggestion virtual_card_name_field_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      CREDIT_CARD_NAME_FULL,
-                                      /*virtual_card_option=*/true,
-                                      /*card_linked_offer_available=*/false);
+      CreateCreditCardSuggestionForTest(server_card, *autofill_client(),
+                                        CREDIT_CARD_NAME_FULL,
+                                        /*virtual_card_option=*/true,
+                                        /*card_linked_offer_available=*/false);
 
   // `is_acceptable` is false only when merchant has opted out of VCN.
   EXPECT_EQ(virtual_card_name_field_suggestion.is_acceptable,
@@ -2235,11 +2153,10 @@
 
   // Card number field suggestion for virtual cards.
   Suggestion virtual_card_number_field_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/true,
-                                      /*card_linked_offer_available=*/false);
+      CreateCreditCardSuggestionForTest(server_card, *autofill_client(),
+                                        CREDIT_CARD_NUMBER,
+                                        /*virtual_card_option=*/true,
+                                        /*card_linked_offer_available=*/false);
 
   // `is_acceptable` is false only when flag is enabled and merchant has opted
   // out of VCN.
@@ -2298,12 +2215,10 @@
   gfx::Image fake_image = CustomIconForTest();
   payments_data().AddCardArtImage(card_art_url, fake_image);
 
-  Suggestion virtual_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/true,
-                                      /*card_linked_offer_available=*/false);
+  Suggestion virtual_card_suggestion = CreateCreditCardSuggestionForTest(
+      server_card, *autofill_client(), CREDIT_CARD_NUMBER,
+      /*virtual_card_option=*/true,
+      /*card_linked_offer_available=*/false);
 
   EXPECT_EQ(virtual_card_suggestion.type,
             SuggestionType::kVirtualCreditCardEntry);
@@ -2314,12 +2229,10 @@
                                           fake_image),
             card_art_image_enabled());
 
-  Suggestion real_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card, *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false);
+  Suggestion real_card_suggestion = CreateCreditCardSuggestionForTest(
+      server_card, *autofill_client(), CREDIT_CARD_NUMBER,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
 
   EXPECT_EQ(real_card_suggestion.type, SuggestionType::kCreditCardEntry);
   EXPECT_EQ(real_card_suggestion.GetPayload<Suggestion::BackendId>(),
@@ -2335,12 +2248,10 @@
   // Create a local card.
   CreditCard local_card = CreateLocalCard();
 
-  Suggestion real_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(local_card, *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false);
+  Suggestion real_card_suggestion = CreateCreditCardSuggestionForTest(
+      local_card, *autofill_client(), CREDIT_CARD_NUMBER,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
 
   EXPECT_EQ(real_card_suggestion.type, SuggestionType::kCreditCardEntry);
   EXPECT_EQ(real_card_suggestion.GetPayload<Suggestion::BackendId>(),
@@ -2366,12 +2277,10 @@
   CreditCard local_card =
       CreateLocalCard(/*guid=*/"00000000-0000-0000-0000-000000000002");
 
-  Suggestion virtual_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(local_card, *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/true,
-                                      /*card_linked_offer_available=*/false);
+  Suggestion virtual_card_suggestion = CreateCreditCardSuggestionForTest(
+      local_card, *autofill_client(), CREDIT_CARD_NUMBER,
+      /*virtual_card_option=*/true,
+      /*card_linked_offer_available=*/false);
 
   EXPECT_EQ(virtual_card_suggestion.type,
             SuggestionType::kVirtualCreditCardEntry);
@@ -2382,12 +2291,10 @@
                                           fake_image),
             card_art_image_enabled());
 
-  Suggestion real_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(local_card, *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/false);
+  Suggestion real_card_suggestion = CreateCreditCardSuggestionForTest(
+      local_card, *autofill_client(), CREDIT_CARD_NUMBER,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
 
   EXPECT_EQ(real_card_suggestion.type, SuggestionType::kCreditCardEntry);
   EXPECT_EQ(real_card_suggestion.GetPayload<Suggestion::BackendId>(),
@@ -2410,12 +2317,12 @@
     }
     payments_data().AddServerCreditCard(server_card);
 
-    PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-    suggestion_generator().GetSuggestionsForCreditCards(
-        *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
-        kDefaultTriggerSource,
-        /*should_show_scan_credit_card=*/false,
-        /*should_show_cards_from_account=*/false, summary);
+    CreditCardSuggestionSummary summary;
+    GetSuggestionsForCreditCards(*autofill_client(), FormFieldData(),
+                                 CREDIT_CARD_NUMBER, kDefaultTriggerSource,
+                                 /*should_show_scan_credit_card=*/false,
+                                 /*should_show_cards_from_account=*/false,
+                                 summary);
 
     EXPECT_TRUE(summary.metadata_logging_context
                     .instruments_with_metadata_available.empty());
@@ -2444,12 +2351,12 @@
         GURL("https://www.example.com/card-art.png"));
     payments_data().AddServerCreditCard(server_card_with_metadata);
 
-    PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-    suggestion_generator().GetSuggestionsForCreditCards(
-        *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
-        kDefaultTriggerSource,
-        /*should_show_scan_credit_card=*/false,
-        /*should_show_cards_from_account=*/false, summary);
+    CreditCardSuggestionSummary summary;
+    GetSuggestionsForCreditCards(*autofill_client(), FormFieldData(),
+                                 CREDIT_CARD_NUMBER, kDefaultTriggerSource,
+                                 /*should_show_scan_credit_card=*/false,
+                                 /*should_show_cards_from_account=*/false,
+                                 summary);
 
     EXPECT_TRUE(
         summary.metadata_logging_context.instruments_with_metadata_available
@@ -2489,13 +2396,12 @@
   payments_data().AddServerCreditCard(server_card);
   payments_data().AddCardArtImage(card_art_url, fake_image);
 
-  PaymentsSuggestionGenerator::CreditCardSuggestionSummary summary;
-  std::vector<Suggestion> suggestions =
-      suggestion_generator().GetSuggestionsForCreditCards(
-          *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
-          kDefaultTriggerSource,
-          /*should_show_scan_credit_card=*/false,
-          /*should_show_cards_from_account=*/false, summary);
+  CreditCardSuggestionSummary summary;
+  std::vector<Suggestion> suggestions = GetSuggestionsForCreditCards(
+      *autofill_client(), FormFieldData(), CREDIT_CARD_NUMBER,
+      kDefaultTriggerSource,
+      /*should_show_scan_credit_card=*/false,
+      /*should_show_cards_from_account=*/false, summary);
 
   // Suggestions in `suggestions` are persisted in order of their presentation
   // to the user in the Autofill dropdown and currently virtual cards are shown
@@ -2567,12 +2473,10 @@
   CreditCard server_card1 =
       CreateServerCard(/*guid=*/"00000000-0000-0000-0000-000000000001");
 
-  Suggestion virtual_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card1, *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/true,
-                                      /*card_linked_offer_available=*/true);
+  Suggestion virtual_card_suggestion = CreateCreditCardSuggestionForTest(
+      server_card1, *autofill_client(), CREDIT_CARD_NUMBER,
+      /*virtual_card_option=*/true,
+      /*card_linked_offer_available=*/true);
 
   EXPECT_EQ(virtual_card_suggestion.type,
             SuggestionType::kVirtualCreditCardEntry);
@@ -2581,12 +2485,10 @@
                 Suggestion::Guid("00000000-0000-0000-0000-000000000001")));
   EXPECT_EQ(virtual_card_suggestion.labels.size(), 1u);
 
-  Suggestion real_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card1, *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/true);
+  Suggestion real_card_suggestion = CreateCreditCardSuggestionForTest(
+      server_card1, *autofill_client(), CREDIT_CARD_NUMBER,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/true);
 
   EXPECT_EQ(real_card_suggestion.type, SuggestionType::kCreditCardEntry);
   EXPECT_EQ(real_card_suggestion.GetPayload<Suggestion::BackendId>(),
@@ -2621,12 +2523,10 @@
   CreditCard server_card1 =
       CreateServerCard(/*guid=*/"00000000-0000-0000-0000-000000000001");
 
-  Suggestion virtual_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card1, *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/true,
-                                      /*card_linked_offer_available=*/true);
+  Suggestion virtual_card_suggestion = CreateCreditCardSuggestionForTest(
+      server_card1, *autofill_client(), CREDIT_CARD_NUMBER,
+      /*virtual_card_option=*/true,
+      /*card_linked_offer_available=*/true);
 
   EXPECT_EQ(virtual_card_suggestion.type,
             SuggestionType::kVirtualCreditCardEntry);
@@ -2645,12 +2545,10 @@
 #endif
   EXPECT_EQ(virtual_card_suggestion.labels.size(), expected_labels_size);
 
-  Suggestion real_card_suggestion =
-      test_api(suggestion_generator())
-          .CreateCreditCardSuggestion(server_card1, *autofill_client(),
-                                      CREDIT_CARD_NUMBER,
-                                      /*virtual_card_option=*/false,
-                                      /*card_linked_offer_available=*/true);
+  Suggestion real_card_suggestion = CreateCreditCardSuggestionForTest(
+      server_card1, *autofill_client(), CREDIT_CARD_NUMBER,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/true);
 
   EXPECT_EQ(real_card_suggestion.type, SuggestionType::kCreditCardEntry);
   EXPECT_EQ(real_card_suggestion.GetPayload<Suggestion::BackendId>(),
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h
index b3a497fd..2754b45 100644
--- a/components/autofill/core/browser/personal_data_manager.h
+++ b/components/autofill/core/browser/personal_data_manager.h
@@ -46,8 +46,8 @@
 // general principles that apply to both. For data type specific information,
 // see those classes.
 // The ADM/PayDM are owned by the PDM.
-// TODO(b/322170538): Currently, only the PDM can be observed. Split the PDM
-// observer into an ADM and a PayDM observer.
+// TODO(crbug.com/322170538): Currently, only the PDM can be observed. Split the
+// PDM observer into an ADM and a PayDM observer.
 //
 // Since `AutofillTable` lives on a separate sequence, changes posted to the
 // ADM/PayDM are asynchronous. They only become effective in the ADM/PayDM
@@ -117,8 +117,8 @@
   void OnPaymentsDataChanged() override;
 
   // history::HistoryServiceObserver:
-  // TODO(b/322170538): This is used to clear the crowdsourcing manager's
-  // history. Consider moving the observer there.
+  // TODO(crbug.com/322170538): This is used to clear the crowdsourcing
+  // manager's history. Consider moving the observer there.
   void OnHistoryDeletions(history::HistoryService* history_service,
                           const history::DeletionInfo& deletion_info) override;
 
@@ -127,7 +127,7 @@
 
   // Depending on what the `guid` identifies, removes either an AutofillProfile,
   // a credit card or an IBAN.
-  // TODO(b/322170538): Remove. Callers should use one of the following
+  // TODO(crbug.com/322170538): Remove. Callers should use one of the following
   // functions instead:
   // - `address_data_manager().RemoveProfile()`.
   // - `payments_data_manager().RemoveByGUID()`.
@@ -151,7 +151,7 @@
   // payment changes are pending.
   void NotifyPersonalDataObserver();
 
-  // TODO(b/40100455): Consider moving this to the TestPDM or a TestAPI.
+  // TODO(crbug.com/40100455): Consider moving this to the TestPDM or a TestAPI.
   void SetSyncServiceForTest(syncer::SyncService* sync_service);
 
  protected:
@@ -161,9 +161,9 @@
   // Responsible for all payments-related logic of the PDM. Non-null.
   std::unique_ptr<PaymentsDataManager> payments_data_manager_;
 
-  // TODO(b/322170538): These observers are used to emulate the PDM observer
-  // while it is being split into separate address and payments observers.
-  // Remove once the PDMObserver is gone.
+  // TODO(crbug.com/322170538): These observers are used to emulate the PDM
+  // observer while it is being split into separate address and payments
+  // observers. Remove once the PDMObserver is gone.
   base::ScopedObservation<AddressDataManager, AddressDataManager::Observer>
       address_data_manager_observation_{this};
   base::ScopedObservation<PaymentsDataManager, PaymentsDataManager::Observer>
diff --git a/components/autofill/core/browser/profile_token_quality.cc b/components/autofill/core/browser/profile_token_quality.cc
index 28c1b77..549f5bb 100644
--- a/components/autofill/core/browser/profile_token_quality.cc
+++ b/components/autofill/core/browser/profile_token_quality.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO: crbug.com/347137620 - Remove this and spanify to fix the errors.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "components/autofill/core/browser/profile_token_quality.h"
 
 #include <algorithm>
@@ -150,7 +145,7 @@
       continue;
     }
     if (!field.autofilled_type()) {
-      // TODO(b/311604770): Field-by-field filling doesn't support
+      // TODO(crbug.com/311604770): Field-by-field filling doesn't support
       // `autofilled_type()`.
       continue;
     }
@@ -260,8 +255,8 @@
                                         : 1;
   // Shuffle the `observations` and add the first `observations_to_add` many.
   base::RandomShuffle(observations.begin(), observations.end());
-  for (auto& [type, observation] : base::make_span(
-           observations.begin(), observations.begin() + observations_to_add)) {
+  for (auto& [type, observation] :
+       base::span(observations).first(observations_to_add)) {
     AddObservation(type, std::move(observation));
   }
   return observations_to_add;
diff --git a/components/autofill/core/browser/server_prediction_overrides.cc b/components/autofill/core/browser/server_prediction_overrides.cc
index 733ca65..3c80029 100644
--- a/components/autofill/core/browser/server_prediction_overrides.cc
+++ b/components/autofill/core/browser/server_prediction_overrides.cc
@@ -2,6 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#ifdef UNSAFE_BUFFERS_BUILD
+// TODO(crbug.com/341324165): Fix and remove.
+#pragma allow_unsafe_buffers
+#endif
+
 #include "components/autofill/core/browser/server_prediction_overrides.h"
 
 #include <optional>
diff --git a/components/autofill/core/browser/strike_databases/address_suggestion_strike_database.h b/components/autofill/core/browser/strike_databases/address_suggestion_strike_database.h
index 33e5521..5c5b59b 100644
--- a/components/autofill/core/browser/strike_databases/address_suggestion_strike_database.h
+++ b/components/autofill/core/browser/strike_databases/address_suggestion_strike_database.h
@@ -21,7 +21,7 @@
   static constexpr std::string_view kName = "AddressSuggestion";
   // This value is now meaningless, since precedence is taken by the
   // parameterized `AddressSuggestionStrikeDatabase::GetMaxStrikesLimit`.
-  // TODO(b/41460687): Change to launched parameterization.
+  // TODO(crbug.com/41460687): Change to launched parameterization.
   static constexpr size_t kMaxStrikeLimit = 3;
   static constexpr size_t kMaxStrikeEntities = 300;
   // Strikes in this database do not expire.
@@ -56,7 +56,7 @@
                            FieldSignature field_signature,
                            const GURL& url);
 
-  // TODO(b/41460687): Remove.
+  // TODO(crbug.com/41460687): Remove.
   int GetMaxStrikesLimit() const override;
 };
 
diff --git a/components/autofill/core/browser/ui/payments/autofill_progress_dialog_controller_impl.cc b/components/autofill/core/browser/ui/payments/autofill_progress_dialog_controller_impl.cc
index 819da04..505a460 100644
--- a/components/autofill/core/browser/ui/payments/autofill_progress_dialog_controller_impl.cc
+++ b/components/autofill/core/browser/ui/payments/autofill_progress_dialog_controller_impl.cc
@@ -113,7 +113,8 @@
       return l10n_util::GetStringUTF16(IDS_CANCEL);
     case AutofillProgressDialogType::kVirtualCardUnmaskProgressDialog:
     case AutofillProgressDialogType::kServerCardUnmaskProgressDialog:
-    // TODO(b/296651406): Rename IDS_AUTOFILL_CARD_UNMASK_CANCEL_BUTTON_LABEL to
+    // TODO(crbug.com/296651406): Rename
+    // IDS_AUTOFILL_CARD_UNMASK_CANCEL_BUTTON_LABEL to
     // IDS_AUTOFILL_PAYMENT_METHOD_UNMASK_CANCEL_BUTTON_LABEL
     case AutofillProgressDialogType::kServerIbanUnmaskProgressDialog:
       return l10n_util::GetStringUTF16(
diff --git a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller.h b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller.h
index b59947f73..67ba994 100644
--- a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller.h
+++ b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller.h
@@ -38,9 +38,10 @@
   virtual std::u16string GetOkButtonLabel() const = 0;
   virtual int GetCvcImageRid() const = 0;
   virtual bool ShouldRequestExpirationDate() const = 0;
-  // TODO(b/303715882): Should consider removing these detailed information
-  // accessors and instead return the credit card object directly. Only exposing
-  // necessary information is good but this list is growing larger.
+  // TODO(crbug.com/303715882): Should consider removing these detailed
+  // information accessors and instead return the credit card object directly.
+  // Only exposing necessary information is good but this list is growing
+  // larger.
 #if BUILDFLAG(IS_ANDROID)
   virtual Suggestion::Icon GetCardIcon() const = 0;
   virtual std::u16string GetCardName() const = 0;
diff --git a/components/autofill/core/browser/ui/suggestion.h b/components/autofill/core/browser/ui/suggestion.h
index bd54fe4..34a6a42b 100644
--- a/components/autofill/core/browser/ui/suggestion.h
+++ b/components/autofill/core/browser/ui/suggestion.h
@@ -90,7 +90,7 @@
   enum class Icon {
     kNoIcon,
     kAccount,
-    // TODO(b/40266549): Rename to Undo.
+    // TODO(crbug.com/40266549): Rename to Undo.
     kClear,
     kCreate,
     kCode,
@@ -113,7 +113,8 @@
     kOfferTag,
     kPenSpark,
     kPlusAddress,
-    // TODO(b/342125189): Rename to `kPlusAddress` when UI changes are launched.
+    // TODO(crbug.com/342125189): Rename to `kPlusAddress` when UI changes are
+    // launched.
     kPlusAddressSmall,
     kScanCreditCard,
     kSettings,
@@ -135,10 +136,10 @@
     kIban,
   };
 
-  // TODO(b/335194240): Consolidate expected param types for these constructors.
-  // Some expect UTF16 strings and others UTF8, while internally we only use
-  // UTF16. The ones expecting UTF8 are only used by tests and could be easily
-  // refactored.
+  // TODO(crbug.com/335194240): Consolidate expected param types for these
+  // constructors. Some expect UTF16 strings and others UTF8, while internally
+  // we only use UTF16. The ones expecting UTF8 are only used by tests and could
+  // be easily refactored.
   Suggestion();
   explicit Suggestion(std::u16string main_text);
   explicit Suggestion(SuggestionType type);
@@ -185,7 +186,7 @@
         // Manual fallback password suggestions store the password to preview or
         // fill in the suggestion's payload. Regular per-domain contain empty
         // `BackendId`.
-        // TODO(b/333992198): Use `PasswordSuggestionDetails` for all
+        // TODO(crbug.com/333992198): Use `PasswordSuggestionDetails` for all
         // suggestions with `SuggestionType::kPasswordEntry`.
         return absl::holds_alternative<BackendId>(payload) ||
                absl::holds_alternative<PasswordSuggestionDetails>(payload);
diff --git a/components/autofill/core/browser/ui/suggestion_type.h b/components/autofill/core/browser/ui/suggestion_type.h
index f8aee53..6353968 100644
--- a/components/autofill/core/browser/ui/suggestion_type.h
+++ b/components/autofill/core/browser/ui/suggestion_type.h
@@ -107,7 +107,8 @@
   // Other suggestions.
   kTitle = 45,
   kSeparator = 46,
-  // TODO(b/40266549): Rename to Undo once iOS implements it - it still works
+  // TODO(crbug.com/40266549): Rename to Undo once iOS implements it - it still
+  // works
   // as clear form there.
   kUndoOrClear = 47,
   kMixedFormMessage = 48,
diff --git a/components/autofill/core/browser/webdata/autocomplete/autocomplete_table.cc b/components/autofill/core/browser/webdata/autocomplete/autocomplete_table.cc
index 14ebfc8..dfb064b 100644
--- a/components/autofill/core/browser/webdata/autocomplete/autocomplete_table.cc
+++ b/components/autofill/core/browser/webdata/autocomplete/autocomplete_table.cc
@@ -2,6 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#ifdef UNSAFE_BUFFERS_BUILD
+// TODO(crbug.com/341324165): Fix and remove.
+#pragma allow_unsafe_buffers
+#endif
+
 #include "components/autofill/core/browser/webdata/autocomplete/autocomplete_table.h"
 
 #include <memory>
diff --git a/components/autofill/core/browser/webdata/autocomplete/autocomplete_table_unittest.cc b/components/autofill/core/browser/webdata/autocomplete/autocomplete_table_unittest.cc
index a04c324..c8f65d0 100644
--- a/components/autofill/core/browser/webdata/autocomplete/autocomplete_table_unittest.cc
+++ b/components/autofill/core/browser/webdata/autocomplete/autocomplete_table_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO: crbug.com/347137620 - Remove this and spanify to fix the errors.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "components/autofill/core/browser/webdata/autocomplete/autocomplete_table.h"
 
 #include <string>
@@ -177,7 +172,7 @@
   changes.clear();
   EXPECT_TRUE(table_->RemoveFormElementsAddedBetween(begin, Time(), changes));
 
-  const AutocompleteChange kExpectedChanges[] = {
+  const auto kExpectedChanges = std::array{
       AutocompleteChange(AutocompleteChange::REMOVE,
                          AutocompleteKey(u"Name", u"Superman")),
       AutocompleteChange(AutocompleteChange::REMOVE,
@@ -187,7 +182,7 @@
       AutocompleteChange(AutocompleteChange::REMOVE,
                          AutocompleteKey(u"Favorite Color", u"Green")),
   };
-  EXPECT_EQ(std::size(kExpectedChanges), changes.size());
+  EXPECT_EQ(kExpectedChanges.size(), changes.size());
   for (size_t i = 0; i < std::size(kExpectedChanges); ++i) {
     EXPECT_EQ(kExpectedChanges[i], changes[i]);
   }
diff --git a/components/autofill/core/browser/webdata/autofill_table_utils.cc b/components/autofill/core/browser/webdata/autofill_table_utils.cc
index faac1c2..7c9bf8f 100644
--- a/components/autofill/core/browser/webdata/autofill_table_utils.cc
+++ b/components/autofill/core/browser/webdata/autofill_table_utils.cc
@@ -2,6 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#ifdef UNSAFE_BUFFERS_BUILD
+// TODO(crbug.com/341324165): Fix and remove.
+#pragma allow_unsafe_buffers
+#endif
+
 #include "components/autofill/core/browser/webdata/autofill_table_utils.h"
 
 #include <initializer_list>
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index fdeafde..9c15fff 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -177,7 +177,8 @@
 // When enabled, autofill displays an IPH informing users about using autofill
 // from the context menu. The IPH will be attached to address fields with
 // autocomplete="garbage".
-// TODO(b/313587343) Remove once manual fallback IPH feature is launched.
+// TODO(crbug.com/313587343) Remove once manual fallback IPH feature is
+// launched.
 BASE_FEATURE(kAutofillEnableManualFallbackIPH,
              "AutofillEnableManualFallbackIPH",
              base::FEATURE_DISABLED_BY_DEFAULT);
@@ -319,7 +320,7 @@
 // When enabled, focusing on an autofilled field that was traditionally filled
 // with address data (meaning filled with the value of their classified type)
 // will yield field-by-field filling suggestions without prefix matching.
-// TODO(b/339543182): Remove when launched.
+// TODO(crbug.com/339543182): Remove when launched.
 BASE_FEATURE(kAutofillAddressFieldSwapping,
              "AutofillAddressFieldSwapping",
              base::FEATURE_DISABLED_BY_DEFAULT);
@@ -506,24 +507,23 @@
              "AutofillSkipPreFilledFields",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-// If enabled, use the parsing patterns from a JSON file for heuristics, rather
-// than the hardcoded ones from autofill_regex_constants.cc.
-// The specific pattern set is controlled by the
-// `kAutofillParsingPatternActiveSource` parameter.
-//
-// This feature is intended to work with kAutofillPageLanguageDetection.
-//
-// Enabling this feature is also a prerequisite for emitting shadow metrics.
-// TODO(crbug.com/40146444): Remove once launched.
+// This feature flag only exists for its feature parameter
+// `kAutofillParsingPatternActiveSource`, controlling from which JSON file
+// regexes are loaded.
+// If the flag is disabled (which it should never be in practice), it behaves
+// as if enabled with `kAutofillParsingPatternActiveSource` set to "default".
+// TODO(crbug.com/40280853): Remove once there is a decision what to do about
+// the different JSON files.
 BASE_FEATURE(kAutofillParsingPatternProvider,
              "AutofillParsingPatternProvider",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
-// The specific pattern set is controlled by the `kAutofillParsingPatternActive`
-// parameter. One of "default", "experimental", "nextgen".
+// The specific pattern set from which regexes are loaded for the active
+// predictions. One of "default", "experimental", "nextgen".
 // This parameter is only supported in Chrome-branded builds. Non-Chrome branded
 // builds default to the legacy patterns.
-// TODO(crbug.com/40197215): Remove once experiment is finished.
+// TODO(crbug.com/40280853): Remove once there is a decision what to do about
+// the different JSON files.
 const base::FeatureParam<std::string> kAutofillParsingPatternActiveSource{
     &kAutofillParsingPatternProvider, "prediction_source", "default"};
 
@@ -550,7 +550,7 @@
              "AutofillPopupDisablePaintChecks",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-// TODO(b/334909042): Remove after cleanup.
+// TODO(crbug.com/334909042): Remove after cleanup.
 // If the feature is enabled, the Autofill popup widget is initialized with
 // `Widget::InitParams::z_order` set to `ui::ZOrderLevel::kSecuritySurface`,
 // otherwise the `z_order` is not set and defined by the widget type (see
@@ -732,14 +732,14 @@
 
 // When enabled, various deduplication related metrics are logged on startup
 // and on import.
-// TODO(b/325452461): Remove once rolled out.
+// TODO(crbug.com/325452461): Remove once rolled out.
 BASE_FEATURE(kAutofillLogDeduplicationMetrics,
              "AutofillLogDeduplicationMetrics",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
 // When enabled, low-quality quasi duplicates of rank one are silently removed
 // during the once-per-milestone deduplication routine.
-// TODO(b/325450676): Remove when launched.
+// TODO(crbug.com/325450676): Remove when launched.
 BASE_FEATURE(kAutofillSilentlyRemoveQuasiDuplicates,
              "AutofillSilentlyRemoveQuasiDuplicates",
              base::FEATURE_DISABLED_BY_DEFAULT);
@@ -750,7 +750,7 @@
 // In particular, if the observed profile was autofilled, except for an edit in
 // a single type, this qualifies for an update of the autofilled profile, in
 // case the edited type has low-quality.
-// TODO(b/325451601): Remove when launched.
+// TODO(crbug.com/325451601): Remove when launched.
 BASE_FEATURE(kAutofillUpdateLowQualityTokenOnImport,
              "AutofillUpdateLowQualityTokenOnImport",
              base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/components/autofill/core/common/autofill_prefs.h b/components/autofill/core/common/autofill_prefs.h
index 8c63ab1..3e2ff2f 100644
--- a/components/autofill/core/common/autofill_prefs.h
+++ b/components/autofill/core/common/autofill_prefs.h
@@ -48,7 +48,7 @@
 // To simplify the rollout of AutofillSilentlyRemoveQuasiDuplicates,
 // deduplication can be run a second time per milestone for users enrolled in
 // the experiment. This pref tracks whether deduplication was run a second time.
-// TODO(b/325450676): Remove after the rollout finished.
+// TODO(crbug.com/325450676): Remove after the rollout finished.
 inline constexpr char kAutofillRanQuasiDuplicateExtraDeduplication[] =
     "autofill.ran_quasi_duplicate_extra_deduplication";
 // Integer that is set to the last version where disused addresses were
diff --git a/components/autofill/core/common/autofill_regex_constants.h b/components/autofill/core/common/autofill_regex_constants.h
index 2a960ce..55996af 100644
--- a/components/autofill/core/common/autofill_regex_constants.h
+++ b/components/autofill/core/common/autofill_regex_constants.h
@@ -126,6 +126,7 @@
     u"|(\\b|_)(ülke|ulce|ulke)(\\b|_)"    // tr
     u"|کشور"                              // fa
     u"|negara"                            // id
+    u"|\\bpaese\\b|\\bnazione\\b"         // it
     u"|(?<!o)kraj|pa[nń]stwo";            // pl
 inline constexpr char16_t kCountryLocationRe[] = u"location";
 inline constexpr char16_t kZipCodeRe[] =
diff --git a/components/autofill/core/common/credit_card_number_validation.cc b/components/autofill/core/common/credit_card_number_validation.cc
index 0a6c074..429c295 100644
--- a/components/autofill/core/common/credit_card_number_validation.cc
+++ b/components/autofill/core/common/credit_card_number_validation.cc
@@ -6,6 +6,9 @@
 
 #include <stddef.h>
 
+#include <string>
+#include <string_view>
+
 #include "base/containers/adapters.h"
 #include "base/feature_list.h"
 #include "base/strings/string_number_conversions.h"
@@ -17,12 +20,12 @@
 
 namespace autofill {
 
-bool IsValidCreditCardNumber(const std::u16string& text) {
+bool IsValidCreditCardNumber(std::u16string_view text) {
   const std::u16string number = StripCardNumberSeparators(text);
   return HasCorrectCreditCardNumberLength(number) && PassesLuhnCheck(number);
 }
 
-bool HasCorrectCreditCardNumberLength(const std::u16string& number) {
+bool HasCorrectCreditCardNumberLength(std::u16string_view number) {
   // Credit card numbers are at most 19 digits in length, 12 digits seems to
   // be a fairly safe lower-bound [1].  Specific card issuers have more rigidly
   // defined sizes.
@@ -60,7 +63,7 @@
   return true;
 }
 
-bool PassesLuhnCheck(const std::u16string& number) {
+bool PassesLuhnCheck(std::u16string_view number) {
   // Use the Luhn formula [3] to validate the number.
   // [3] http://en.wikipedia.org/wiki/Luhn_algorithm
   int sum = 0;
@@ -82,13 +85,13 @@
   return (sum % 10) == 0;
 }
 
-std::u16string StripCardNumberSeparators(const std::u16string& number) {
+std::u16string StripCardNumberSeparators(std::u16string_view number) {
   std::u16string stripped;
   base::RemoveChars(number, u"- ", &stripped);
   return stripped;
 }
 
-const char* GetCardNetwork(const std::u16string& number) {
+const char* GetCardNetwork(std::u16string_view number) {
   // Credit card number specifications taken from:
   // https://en.wikipedia.org/wiki/Payment_card_number,
   // http://www.regular-expressions.info/creditcard.html,
diff --git a/components/autofill/core/common/credit_card_number_validation.h b/components/autofill/core/common/credit_card_number_validation.h
index 6d9803d..ad987fa 100644
--- a/components/autofill/core/common/credit_card_number_validation.h
+++ b/components/autofill/core/common/credit_card_number_validation.h
@@ -5,31 +5,31 @@
 #ifndef COMPONENTS_AUTOFILL_CORE_COMMON_CREDIT_CARD_NUMBER_VALIDATION_H_
 #define COMPONENTS_AUTOFILL_CORE_COMMON_CREDIT_CARD_NUMBER_VALIDATION_H_
 
-#include <string>
+#include <string_view>
 
 namespace autofill {
 
-// Returns true if |text| looks like a valid credit card number.
+// Returns true if `text` looks like a valid credit card number.
 // Uses the Luhn formula to validate the number.
-bool IsValidCreditCardNumber(const std::u16string& text);
+bool IsValidCreditCardNumber(std::u16string_view text);
 
-// Returns true if |number| has correct length according to card network.
-bool HasCorrectCreditCardNumberLength(const std::u16string& number);
+// Returns true if `number` has correct length according to card network.
+bool HasCorrectCreditCardNumberLength(std::u16string_view number);
 
-// Returns true if |number| passes the validation by Luhn formula.
-bool PassesLuhnCheck(const std::u16string& number);
+// Returns true if `number` passes the validation by Luhn formula.
+bool PassesLuhnCheck(std::u16string_view number);
 
-// Returns a version of |number| that has any separator characters removed.
-std::u16string StripCardNumberSeparators(const std::u16string& number);
+// Returns a version of `number` that has any separator characters removed.
+std::u16string StripCardNumberSeparators(std::u16string_view number);
 
 // Returns the internal representation of card issuer network corresponding to
-// the given |number|.  The card issuer network is determined purely according
+// the given `number`.  The card issuer network is determined purely according
 // to the Issuer Identification Number (IIN), a.k.a. the "Bank Identification
-// Number (BIN)", which is parsed from the relevant prefix of the |number|. This
-// function performs no additional validation checks on the |number|. Hence, the
+// Number (BIN)", which is parsed from the relevant prefix of the `number`. This
+// function performs no additional validation checks on the `number`. Hence, the
 // returned issuer network for both the valid card "4111-1111-1111-1111" and the
 // invalid card "4garbage" will be Visa, which has an IIN of 4.
-const char* GetCardNetwork(const std::u16string& number);
+const char* GetCardNetwork(std::u16string_view number);
 
 }  // namespace autofill
 
diff --git a/components/autofill/core/common/credit_card_number_validation_unittest.cc b/components/autofill/core/common/credit_card_number_validation_unittest.cc
index 0ef908a3..071030ccd 100644
--- a/components/autofill/core/common/credit_card_number_validation_unittest.cc
+++ b/components/autofill/core/common/credit_card_number_validation_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO: crbug.com/347137620 - Remove this and spanify to fix the errors.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "components/autofill/core/common/credit_card_number_validation.h"
 
 #include <cstddef>
@@ -23,40 +18,39 @@
 
 // From
 // https://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
-const char16_t* const kValidNumbers[] = {
-    u"378282246310005",     u"3714 4963 5398 431",  u"3787-3449-3671-000",
-    u"5610591081018250",    u"3056 9309 0259 04",   u"3852-0000-0232-37",
-    u"6011111111111117",    u"6011 0009 9013 9424", u"3530-1113-3330-0000",
-    u"3566002020360505",
-    u"5555 5555 5555 4444",  // Mastercard.
-    u"5105-1051-0510-5100",
-    u"4111111111111111",  // Visa.
-    u"4012 8888 8888 1881", u"4222-2222-2222-2",    u"5019717010103742",
-    u"6331101999990016",    u"6247130048162403",
-    u"4532261615476013542",  // Visa, 19 digits.
-    u"5067071446391278",     // Elo.
-    u"5060995764815772",     // Verve.
-    u"506099576481577267",   // Verve 18 digits.
-    u"5060995764815772675",  // Verve 19 digits.
-    u"6362970000457013",
-};
-const char16_t* const kInvalidNumbers[] = {
+constexpr auto kValidNumbers = std::to_array<std::u16string_view>(
+    {u"378282246310005",     u"3714 4963 5398 431",  u"3787-3449-3671-000",
+     u"5610591081018250",    u"3056 9309 0259 04",   u"3852-0000-0232-37",
+     u"6011111111111117",    u"6011 0009 9013 9424", u"3530-1113-3330-0000",
+     u"3566002020360505",
+     u"5555 5555 5555 4444",  // Mastercard.
+     u"5105-1051-0510-5100",
+     u"4111111111111111",  // Visa.
+     u"4012 8888 8888 1881", u"4222-2222-2222-2",    u"5019717010103742",
+     u"6331101999990016",    u"6247130048162403",
+     u"4532261615476013542",  // Visa, 19 digits.
+     u"5067071446391278",     // Elo.
+     u"5060995764815772",     // Verve.
+     u"506099576481577267",   // Verve 18 digits.
+     u"5060995764815772675",  // Verve 19 digits.
+     u"6362970000457013"});
+constexpr auto kInvalidNumbers = std::to_array<std::u16string_view>({
     u"4111 1111 112",        /* too short */
     u"41111111111111111115", /* too long */
     u"4111-1111-1111-1110",  /* wrong Luhn checksum */
     u"3056 9309 0259 04aa",  /* non-digit characters */
-    u"50609957648157726",    /* Verve 17 digits */
-};
+    u"50609957648157726"     /* Verve 17 digits */
+});
 
 TEST(AutofillValidation, IsValidCreditCardNumber) {
   base::test::ScopedFeatureList scoped_feature_list{
       features::kAutofillEnableVerveCardSupport};
 
-  for (const char16_t* valid_number : kValidNumbers) {
+  for (std::u16string_view valid_number : kValidNumbers) {
     SCOPED_TRACE(base::UTF16ToUTF8(valid_number));
     EXPECT_TRUE(IsValidCreditCardNumber(valid_number));
   }
-  for (const char16_t* invalid_number : kInvalidNumbers) {
+  for (std::u16string_view invalid_number : kInvalidNumbers) {
     SCOPED_TRACE(base::UTF16ToUTF8(invalid_number));
     EXPECT_FALSE(IsValidCreditCardNumber(invalid_number));
   }
@@ -64,14 +58,15 @@
 
 // Tests the plausibility of the length of the supplied credit card number.
 TEST(AutofillValidation, IsValidCreditCardNumberLength) {
-  for (const char16_t* valid_number : kValidNumbers) {
+  for (std::u16string_view valid_number : kValidNumbers) {
     SCOPED_TRACE(base::UTF16ToUTF8(valid_number));
     EXPECT_TRUE(HasCorrectCreditCardNumberLength(
         StripCardNumberSeparators(valid_number)));
   }
   // Only the first 2 invalid numbers in kInvalidNumbers have a bad length.
+  static_assert(2 <= kInvalidNumbers.size());
   for (size_t i = 0; i < 2; ++i) {
-    const char16_t* invalid_number = kInvalidNumbers[i];
+    std::u16string_view invalid_number = kInvalidNumbers[i];
     SCOPED_TRACE(base::UTF16ToUTF8(invalid_number));
     EXPECT_FALSE(HasCorrectCreditCardNumberLength(
         StripCardNumberSeparators(invalid_number)));
@@ -80,12 +75,12 @@
 
 // Tests the validation of credit card numbers using the Luhn check.
 TEST(AutofillValidation, CreditCardNumberLuhnTest) {
-  for (const char16_t* valid_number : kValidNumbers) {
+  for (std::u16string_view valid_number : kValidNumbers) {
     SCOPED_TRACE(base::UTF16ToUTF8(valid_number));
     EXPECT_TRUE(PassesLuhnCheck(StripCardNumberSeparators(valid_number)));
   }
 
-  const char16_t* invalid_luhn_number = kInvalidNumbers[2];
+  constexpr std::u16string_view invalid_luhn_number = kInvalidNumbers[2];
   SCOPED_TRACE(base::UTF16ToUTF8(invalid_luhn_number));
   EXPECT_FALSE(PassesLuhnCheck(invalid_luhn_number));
 }
diff --git a/components/autofill/core/common/dense_set.h b/components/autofill/core/common/dense_set.h
index 6ce6042fc..914c05b3 100644
--- a/components/autofill/core/common/dense_set.h
+++ b/components/autofill/core/common/dense_set.h
@@ -2,6 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#ifdef UNSAFE_BUFFERS_BUILD
+// TODO(crbug.com/341324165): Fix and remove.
+#pragma allow_unsafe_buffers
+#endif
+
 #ifndef COMPONENTS_AUTOFILL_CORE_COMMON_DENSE_SET_H_
 #define COMPONENTS_AUTOFILL_CORE_COMMON_DENSE_SET_H_
 
diff --git a/components/autofill/ios/browser/autofill_agent.mm b/components/autofill/ios/browser/autofill_agent.mm
index 2bd319b..68976e8 100644
--- a/components/autofill/ios/browser/autofill_agent.mm
+++ b/components/autofill/ios/browser/autofill_agent.mm
@@ -333,14 +333,12 @@
         });
   }
 
-  if (suggestion.popupItemId == autofill::SuggestionType::kAddressEntry ||
-      suggestion.popupItemId == autofill::SuggestionType::kCreditCardEntry ||
-      suggestion.popupItemId ==
-          autofill::SuggestionType::kCreateNewPlusAddress ||
+  if (suggestion.type == autofill::SuggestionType::kAddressEntry ||
+      suggestion.type == autofill::SuggestionType::kCreditCardEntry ||
+      suggestion.type == autofill::SuggestionType::kCreateNewPlusAddress ||
       (base::FeatureList::IsEnabled(
            autofill::features::kAutofillEnableVirtualCards) &&
-       suggestion.popupItemId ==
-           autofill::SuggestionType::kVirtualCreditCardEntry)) {
+       suggestion.type == autofill::SuggestionType::kVirtualCreditCardEntry)) {
     _pendingAutocompleteFieldID = fieldRendererID;
     if (_suggestionDelegate) {
       // TODO(crbug.com/41460687): Replace 0 with the index of the selected
@@ -348,7 +346,7 @@
       autofill::Suggestion autofill_suggestion;
       autofill_suggestion.main_text.value =
           SysNSStringToUTF16(suggestion.value);
-      autofill_suggestion.type = suggestion.popupItemId;
+      autofill_suggestion.type = suggestion.type;
       if (!suggestion.backendIdentifier.length) {
         autofill_suggestion.payload = autofill::Suggestion::BackendId();
       } else {
@@ -377,9 +375,8 @@
     return;
   }
 
-  if (suggestion.popupItemId == autofill::SuggestionType::kAutocompleteEntry ||
-      suggestion.popupItemId ==
-          autofill::SuggestionType::kFillExistingPlusAddress) {
+  if (suggestion.type == autofill::SuggestionType::kAutocompleteEntry ||
+      suggestion.type == autofill::SuggestionType::kFillExistingPlusAddress) {
     // FormSuggestion is a simple, single value that can be filled out now.
     [self fillField:SysNSStringToUTF8(fieldIdentifier)
         fieldRendererID:fieldRendererID
@@ -387,7 +384,7 @@
                formName:SysNSStringToUTF8(formName)
                   value:SysNSStringToUTF16(suggestion.value)
                 inFrame:frame];
-  } else if (suggestion.popupItemId == autofill::SuggestionType::kUndoOrClear) {
+  } else if (suggestion.type == autofill::SuggestionType::kUndoOrClear) {
     __weak __typeof(self) weakSelf = self;
     SuggestionHandledCompletion suggestionHandledCompletionCopy =
         [_suggestionHandledCompletion copy];
@@ -401,8 +398,7 @@
           suggestionHandledCompletionCopy();
         }));
 
-  } else if (suggestion.popupItemId ==
-             autofill::SuggestionType::kShowAccountCards) {
+  } else if (suggestion.type == autofill::SuggestionType::kShowAccountCards) {
     autofill::BrowserAutofillManager* autofillManager =
         [self autofillManagerFromWebState:_webState webFrame:frame];
     if (autofillManager) {
@@ -410,7 +406,7 @@
     }
   } else {
     NOTREACHED_IN_MIGRATION()
-        << "unknown identifier " << base::to_underlying(suggestion.popupItemId);
+        << "unknown identifier " << base::to_underlying(suggestion.type);
   }
 }
 
@@ -554,7 +550,7 @@
     // autofill entries) are zero or positive. Negative entries we are
     // interested in is autofill::SuggestionType::kUndoOrClear, used to show the
     // "clear form" button.
-    // TODO(b/40266549): Replace Clear Form with Undo
+    // TODO(crbug.com/40266549): Replace Clear Form with Undo
     NSString* value = nil;
     NSString* minorValue = nil;
     NSString* displayDescription = nil;
@@ -603,7 +599,8 @@
     } else if (popup_suggestion.type ==
                autofill::SuggestionType::kUndoOrClear) {
       // Show the "clear form" button.
-      // TODO(b/40266549): Replace Clear Form with Undo once this changes
+      // TODO(crbug.com/40266549): Replace Clear Form with Undo once this
+      // changes
       value = SysUTF16ToNSString(popup_suggestion.main_text.value);
     } else if (popup_suggestion.type ==
                autofill::SuggestionType::kShowAccountCards) {
@@ -637,7 +634,7 @@
                         minorValue:minorValue
                 displayDescription:displayDescription
                               icon:icon
-                       popupItemId:popup_suggestion.type
+                              type:popup_suggestion.type
                  backendIdentifier:SysUTF8ToNSString(
                                        popup_suggestion
                                            .GetBackendId<
diff --git a/components/autofill/ios/browser/autofill_agent_unittests.mm b/components/autofill/ios/browser/autofill_agent_unittests.mm
index 37a2900..3b4bc97 100644
--- a/components/autofill/ios/browser/autofill_agent_unittests.mm
+++ b/components/autofill/ios/browser/autofill_agent_unittests.mm
@@ -80,14 +80,13 @@
   return {autofill::FormFieldData::FillData(std::move(field))};
 }
 
-// Returns a simple form suggestion that only consists of a `value` and an
-// `item_id`.
+// Returns a simple form suggestion that only consists of a `value` and a `type`
 FormSuggestion* SimpleFormSuggestion(std::u16string value,
-                                     autofill::SuggestionType item_id) {
+                                     autofill::SuggestionType type) {
   return [FormSuggestion suggestionWithValue:base::SysUTF16ToNSString(value)
                           displayDescription:@""
                                         icon:nil
-                                 popupItemId:item_id
+                                        type:type
                            backendIdentifier:@""
                               requiresReauth:NO];
 }
@@ -477,7 +476,7 @@
   // "Show credit cards from account" should be the only suggestion.
   EXPECT_EQ(1U, completion_handler_suggestions.count);
   EXPECT_EQ(SuggestionType::kShowAccountCards,
-            completion_handler_suggestions[0].popupItemId);
+            completion_handler_suggestions[0].type);
 }
 
 // Tests that virtual cards are being served as suggestions with the
@@ -527,7 +526,7 @@
                         minorValue:[suggestions[0].minorValue copy]
                 displayDescription:[suggestions[0].displayDescription copy]
                               icon:[suggestions[0].icon copy]
-                       popupItemId:suggestions[0].popupItemId
+                              type:suggestions[0].type
                  backendIdentifier:suggestions[0].backendIdentifier
                     requiresReauth:suggestions[0].requiresReauth
         acceptanceA11yAnnouncement:[suggestions[0]
@@ -537,7 +536,7 @@
                         minorValue:[suggestions[1].minorValue copy]
                 displayDescription:[suggestions[1].displayDescription copy]
                               icon:[suggestions[1].icon copy]
-                       popupItemId:suggestions[1].popupItemId
+                              type:suggestions[1].type
                  backendIdentifier:suggestions[1].backendIdentifier
                     requiresReauth:suggestions[1].requiresReauth
         acceptanceA11yAnnouncement:[suggestions[1]
@@ -562,7 +561,7 @@
   EXPECT_TRUE(
       gfx::test::PlatformImagesEqual(virtual_card_suggestion.icon, visa_icon));
   EXPECT_EQ(autofill::SuggestionType::kVirtualCreditCardEntry,
-            virtual_card_suggestion.popupItemId);
+            virtual_card_suggestion.type);
   EXPECT_NSEQ(@"", virtual_card_suggestion.backendIdentifier);
   EXPECT_EQ(false, virtual_card_suggestion.requiresReauth);
   EXPECT_NSEQ(nil, virtual_card_suggestion.acceptanceA11yAnnouncement);
@@ -575,7 +574,7 @@
   EXPECT_TRUE(
       gfx::test::PlatformImagesEqual(credit_card_suggestion.icon, visa_icon));
   EXPECT_EQ(autofill::SuggestionType::kCreditCardEntry,
-            credit_card_suggestion.popupItemId);
+            credit_card_suggestion.type);
   EXPECT_NSEQ(@"", credit_card_suggestion.backendIdentifier);
   EXPECT_EQ(false, credit_card_suggestion.requiresReauth);
   EXPECT_NSEQ(nil, credit_card_suggestion.acceptanceA11yAnnouncement);
@@ -706,11 +705,11 @@
   // `FormSuggestion` objects.
   EXPECT_EQ(2U, completion_handler_suggestions.count);
   EXPECT_EQ(SuggestionType::kCreateNewPlusAddress,
-            completion_handler_suggestions[0].popupItemId);
+            completion_handler_suggestions[0].type);
   EXPECT_NSEQ(base::SysUTF8ToNSString(createSuggestionText),
               completion_handler_suggestions[0].value);
   EXPECT_EQ(autofill::SuggestionType::kFillExistingPlusAddress,
-            completion_handler_suggestions[1].popupItemId);
+            completion_handler_suggestions[1].type);
   EXPECT_NSEQ(base::SysUTF8ToNSString(fillExistingSuggestionText),
               completion_handler_suggestions[1].value);
 }
@@ -820,11 +819,11 @@
   // suggestions should not change.
   EXPECT_EQ(3U, completion_handler_suggestions.count);
   EXPECT_EQ(SuggestionType::kUndoOrClear,
-            completion_handler_suggestions[0].popupItemId);
+            completion_handler_suggestions[0].type);
   EXPECT_EQ(autofill::SuggestionType::kAddressEntry,
-            completion_handler_suggestions[1].popupItemId);
+            completion_handler_suggestions[1].type);
   EXPECT_EQ(autofill::SuggestionType::kAddressEntry,
-            completion_handler_suggestions[2].popupItemId);
+            completion_handler_suggestions[2].type);
 }
 
 // Tests that when Autofill suggestions are made available to AutofillAgent
@@ -876,11 +875,11 @@
 
   EXPECT_EQ(3U, completion_handler_suggestions.count);
   EXPECT_EQ(SuggestionType::kUndoOrClear,
-            completion_handler_suggestions[0].popupItemId);
+            completion_handler_suggestions[0].type);
   EXPECT_EQ(autofill::SuggestionType::kCreditCardEntry,
-            completion_handler_suggestions[1].popupItemId);
+            completion_handler_suggestions[1].type);
   EXPECT_EQ(autofill::SuggestionType::kCreditCardEntry,
-            completion_handler_suggestions[2].popupItemId);
+            completion_handler_suggestions[2].type);
 }
 
 // Test that every frames are processed whatever is the order of pageloading
diff --git a/components/autofill/ios/browser/form_suggestion.h b/components/autofill/ios/browser/form_suggestion.h
index ede3f32..e5a7433 100644
--- a/components/autofill/ios/browser/form_suggestion.h
+++ b/components/autofill/ios/browser/form_suggestion.h
@@ -34,8 +34,8 @@
 // otherwise.
 @property(copy, readonly, nonatomic) UIImage* icon;
 
-// Denotes the popup type.
-@property(assign, readonly, nonatomic) autofill::SuggestionType popupItemId;
+// Denotes the suggestion type.
+@property(assign, readonly, nonatomic) autofill::SuggestionType type;
 
 // Indicates if the user should re-authenticate with the device before applying
 // the suggestion.
@@ -58,7 +58,7 @@
 + (FormSuggestion*)suggestionWithValue:(NSString*)value
                     displayDescription:(NSString*)displayDescription
                                   icon:(UIImage*)icon
-                           popupItemId:(autofill::SuggestionType)popupItemId
+                                  type:(autofill::SuggestionType)type
                      backendIdentifier:(NSString*)backendIdentifier
                         requiresReauth:(BOOL)requiresReauth
             acceptanceA11yAnnouncement:(NSString*)acceptanceA11yAnnouncement
@@ -69,7 +69,7 @@
                             minorValue:(NSString*)minorValue
                     displayDescription:(NSString*)displayDescription
                                   icon:(UIImage*)icon
-                           popupItemId:(autofill::SuggestionType)popupItemId
+                                  type:(autofill::SuggestionType)type
                      backendIdentifier:(NSString*)backendIdentifier
                         requiresReauth:(BOOL)requiresReauth
             acceptanceA11yAnnouncement:(NSString*)acceptanceA11yAnnouncement;
@@ -78,7 +78,7 @@
 + (FormSuggestion*)suggestionWithValue:(NSString*)value
                     displayDescription:(NSString*)displayDescription
                                   icon:(UIImage*)icon
-                           popupItemId:(autofill::SuggestionType)popupItemId
+                                  type:(autofill::SuggestionType)type
                      backendIdentifier:(NSString*)backendIdentifier
                         requiresReauth:(BOOL)requiresReauth;
 
diff --git a/components/autofill/ios/browser/form_suggestion.mm b/components/autofill/ios/browser/form_suggestion.mm
index 76f5de0..296061f 100644
--- a/components/autofill/ios/browser/form_suggestion.mm
+++ b/components/autofill/ios/browser/form_suggestion.mm
@@ -10,7 +10,7 @@
                     minorValue:(NSString*)minorValue
             displayDescription:(NSString*)displayDescription
                           icon:(UIImage*)icon
-                   popupItemId:(autofill::SuggestionType)popupItemId
+                          type:(autofill::SuggestionType)type
              backendIdentifier:(NSString*)backendIdentifier
                 requiresReauth:(BOOL)requiresReauth
     acceptanceA11yAnnouncement:(NSString*)acceptanceA11yAnnouncement
@@ -21,7 +21,7 @@
     _minorValue = [minorValue copy];
     _displayDescription = [displayDescription copy];
     _icon = [icon copy];
-    _popupItemId = popupItemId;
+    _type = type;
     _backendIdentifier = backendIdentifier;
     _requiresReauth = requiresReauth;
     _acceptanceA11yAnnouncement = [acceptanceA11yAnnouncement copy];
@@ -33,7 +33,7 @@
 + (FormSuggestion*)suggestionWithValue:(NSString*)value
                     displayDescription:(NSString*)displayDescription
                                   icon:(UIImage*)icon
-                           popupItemId:(autofill::SuggestionType)popupItemId
+                                  type:(autofill::SuggestionType)type
                      backendIdentifier:(NSString*)backendIdentifier
                         requiresReauth:(BOOL)requiresReauth
             acceptanceA11yAnnouncement:(NSString*)acceptanceA11yAnnouncement
@@ -42,7 +42,7 @@
                                     minorValue:nil
                             displayDescription:displayDescription
                                           icon:icon
-                                   popupItemId:popupItemId
+                                          type:type
                              backendIdentifier:backendIdentifier
                                 requiresReauth:requiresReauth
                     acceptanceA11yAnnouncement:acceptanceA11yAnnouncement
@@ -53,7 +53,7 @@
                             minorValue:(NSString*)minorValue
                     displayDescription:(NSString*)displayDescription
                                   icon:(UIImage*)icon
-                           popupItemId:(autofill::SuggestionType)popupItemId
+                                  type:(autofill::SuggestionType)type
                      backendIdentifier:(NSString*)backendIdentifier
                         requiresReauth:(BOOL)requiresReauth
             acceptanceA11yAnnouncement:(NSString*)acceptanceA11yAnnouncement {
@@ -61,7 +61,7 @@
                                     minorValue:minorValue
                             displayDescription:displayDescription
                                           icon:icon
-                                   popupItemId:popupItemId
+                                          type:type
                              backendIdentifier:backendIdentifier
                                 requiresReauth:requiresReauth
                     acceptanceA11yAnnouncement:acceptanceA11yAnnouncement
@@ -71,14 +71,14 @@
 + (FormSuggestion*)suggestionWithValue:(NSString*)value
                     displayDescription:(NSString*)displayDescription
                                   icon:(UIImage*)icon
-                           popupItemId:(autofill::SuggestionType)popupItemId
+                                  type:(autofill::SuggestionType)type
                      backendIdentifier:(NSString*)backendIdentifier
                         requiresReauth:(BOOL)requiresReauth {
   return [[FormSuggestion alloc] initWithValue:value
                                     minorValue:nil
                             displayDescription:displayDescription
                                           icon:icon
-                                   popupItemId:popupItemId
+                                          type:type
                              backendIdentifier:backendIdentifier
                                 requiresReauth:requiresReauth
                     acceptanceA11yAnnouncement:nil
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_bs.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_bs.xtb
index c060bc4..8525a68 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_bs.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_bs.xtb
@@ -362,6 +362,7 @@
 <translation id="6945221475159498467">Odaberi</translation>
 <translation id="6950072572526089586">Web lokacija koju posjetite može sačuvati informacije o tome šta radite kako bi funkcionirala prema očekivanjima – naprimjer, da ostanete prijavljeni na web lokaciju ili sačuvate artikle u kolica za kupovinu. Web lokacije često privremeno pohranjuju te informacije na vaš uređaj.</translation>
 <translation id="6965382102122355670">Uredu</translation>
+<translation id="6980861169612950611">Želite li izbrisati podatke web-lokacije? <ph name="SITE_NAME" /></translation>
 <translation id="6981982820502123353">Pristupačnost</translation>
 <translation id="6992289844737586249">Web lokacije moraju tražiti dopuštenje da koriste mikrofon (preporučeno)</translation>
 <translation id="7000754031042624318">Isključeno u postavkama Androida</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_hr.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_hr.xtb
index ceeb473..4558678 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_hr.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_hr.xtb
@@ -362,6 +362,7 @@
 <translation id="6945221475159498467">Odaberi</translation>
 <translation id="6950072572526089586">Web-lokacija koju posjećujete može spremiti podatke o tome što radite kako bi funkcionirala kako treba, na primjer kako biste ostali prijavljeni na web-lokaciju ili spremili artikle u košaricu. Web-lokacije često spremaju te podatke na vaš uređaj privremeno.</translation>
 <translation id="6965382102122355670">U redu</translation>
+<translation id="6980861169612950611">Želite li izbrisati podatke web-lokacije? <ph name="SITE_NAME" /></translation>
 <translation id="6981982820502123353">Pristupačnost</translation>
 <translation id="6992289844737586249">Web-lokacije moraju tražiti dopuštenje za upotrebu mikrofona (preporučeno)</translation>
 <translation id="7000754031042624318">Isključeno u postavkama Androida</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_hy.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_hy.xtb
index 8f59dde..2e90df1f 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_hy.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_hy.xtb
@@ -158,6 +158,7 @@
 <translation id="3602290021589620013">Նախադիտում</translation>
 <translation id="3628308229821498208">Որոնման առաջարկվող հարցումներ</translation>
 <translation id="3697164069658504920">Երբ այս պարամետրը միացված է, կայքերը կարող են USB սարքերն օգտագործելու թույլտվություն խնդրել։ Երբ այն անջատված է, կայքերը չեն կարող օգտագործել USB սարքերը։</translation>
+<translation id="3701220924999499408"><ph name="HOST_NAME" /> <ph name="SEPARATOR1" /> <ph name="FROM_DEVICE" /> <ph name="SEPARATOR2" /> <ph name="RECENCY" /></translation>
 <translation id="3707034683772193706">Կայքը, որն այցելում եք, կարող է փոքր քանակությամբ տեղեկություններ պահպանել Chrome-ի միջոցով՝ հիմնականում հաստատելու, որ դուք ռոբոտ չեք</translation>
 <translation id="3721953990244350188">Փակել և ցույց տալ հաջորդ հասանելի գործողությունը</translation>
 <translation id="3744111561329211289">Ֆոնային համաժամացում</translation>
@@ -227,6 +228,7 @@
 <translation id="4962975101802056554">Չեղարկել սարքի բոլոր թույլտվությունները</translation>
 <translation id="497421865427891073">Առաջ գնալ</translation>
 <translation id="4976702386844183910">Վերջին այցելությունը՝ <ph name="DATE" /></translation>
+<translation id="498287755803443017"><ph name="FROM_DEVICE" /> <ph name="SEPARATOR" /> <ph name="RECENCY" /></translation>
 <translation id="4985206706500620449">Դուք թույլատրել եք երրորդ կողմի քուքիները այս կայքի համար</translation>
 <translation id="4994033804516042629">Ոչ մի կոնտակտ չի գտնվել</translation>
 <translation id="4996978546172906250">Համօգտագործման միջոցը`</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_mr.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_mr.xtb
index d8297e0..186b47e 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_mr.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_mr.xtb
@@ -158,6 +158,7 @@
 <translation id="3602290021589620013">पूर्वावलोकन</translation>
 <translation id="3628308229821498208">सुचवलेले शोध</translation>
 <translation id="3697164069658504920">सुरू असताना, साइट USB डिव्हाइस वापरण्याची विनंती करू शकतात. बंद असताना, साइट USB डिव्हाइस वापरू शकत नाहीत.</translation>
+<translation id="3701220924999499408"><ph name="HOST_NAME" /> <ph name="SEPARATOR1" /> <ph name="FROM_DEVICE" /> <ph name="SEPARATOR2" /> <ph name="RECENCY" /></translation>
 <translation id="3707034683772193706">तुम्ही भेट देता ती साइट Chrome सह थोड्या प्रमाणात माहिती सेव्ह करू शकते, जी प्रामुख्याने तुम्ही बॉट नाही हे प्रमाणित करते</translation>
 <translation id="3721953990244350188">डिसमिस करा आणि पुढील उपलब्ध कृती दाखवा</translation>
 <translation id="3744111561329211289">पार्श्वभूमी सिंक</translation>
@@ -227,6 +228,7 @@
 <translation id="4962975101802056554">डिव्हाइससाठीच्या सर्व परवानग्या रद्द करा</translation>
 <translation id="497421865427891073">पुढे जा</translation>
 <translation id="4976702386844183910"><ph name="DATE" /> रोजी शेवटची भेट दिली</translation>
+<translation id="498287755803443017"><ph name="FROM_DEVICE" /> <ph name="SEPARATOR" /> <ph name="RECENCY" /></translation>
 <translation id="4985206706500620449">तुम्ही या साइटसाठी तृतीय पक्ष कुकीना अनुमती दिली आहे</translation>
 <translation id="4994033804516042629">संपर्क सापडले नाहीत</translation>
 <translation id="4996978546172906250">याद्वारे शेअर करा</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb
index 922722e..6ea09fc 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb
@@ -158,6 +158,7 @@
 <translation id="3602290021589620013">Pratonton</translation>
 <translation id="3628308229821498208">Carian cadangan</translation>
 <translation id="3697164069658504920">Apabila dihidupkan, laman dapat meminta untuk menggunakan peranti USB. Apabila dimatikan, laman tidak dapat menggunakan peranti USB.</translation>
+<translation id="3701220924999499408"><ph name="HOST_NAME" /> <ph name="SEPARATOR1" /> <ph name="FROM_DEVICE" /> <ph name="SEPARATOR2" /> <ph name="RECENCY" /></translation>
 <translation id="3707034683772193706">Laman yang anda lawati boleh menyimpan sedikit maklumat dengan Chrome, terutamanya untuk mengesahkan bahawa anda bukan bot</translation>
 <translation id="3721953990244350188">Ketepikan dan tunjukkan tindakan seterusnya yang tersedia</translation>
 <translation id="3744111561329211289">Penyegerakan latar belakang</translation>
@@ -227,6 +228,7 @@
 <translation id="4962975101802056554">Batalkan semua kebenaran untuk peranti</translation>
 <translation id="497421865427891073">Ke hadapan</translation>
 <translation id="4976702386844183910">Terakhir dilawati <ph name="DATE" /></translation>
+<translation id="498287755803443017"><ph name="FROM_DEVICE" /> <ph name="SEPARATOR" /> <ph name="RECENCY" /></translation>
 <translation id="4985206706500620449">Anda membenarkan kuki pihak ketiga untuk laman ini</translation>
 <translation id="4994033804516042629">Tiada kenalan ditemui</translation>
 <translation id="4996978546172906250">Kongsi melalui</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_nl.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_nl.xtb
index f74a685..49b2621 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_nl.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_nl.xtb
@@ -158,6 +158,7 @@
 <translation id="3602290021589620013">Voorbeeld</translation>
 <translation id="3628308229821498208">Voorgestelde zoekopdrachten</translation>
 <translation id="3697164069658504920">Als deze optie aanstaat, kunnen sites vragen of ze USB-apparaten mogen gebruiken. Staat de optie uit, dan kunnen sites geen USB-apparaten gebruiken.</translation>
+<translation id="3701220924999499408"><ph name="HOST_NAME" /> <ph name="SEPARATOR1" /> <ph name="FROM_DEVICE" /> <ph name="SEPARATOR2" /> <ph name="RECENCY" /></translation>
 <translation id="3707034683772193706">Een site die je bezoekt, kan een kleine hoeveelheid informatie opslaan in Chrome, voornamelijk om te bevestigen dat je geen bot bent</translation>
 <translation id="3721953990244350188">Sluiten en volgende beschikbare actie tonen</translation>
 <translation id="3744111561329211289">Synchronisatie op de achtergrond</translation>
@@ -227,6 +228,7 @@
 <translation id="4962975101802056554">Alle rechten voor apparaat intrekken</translation>
 <translation id="497421865427891073">Naar voren gaan</translation>
 <translation id="4976702386844183910">Laatst bezocht: <ph name="DATE" /></translation>
+<translation id="498287755803443017"><ph name="FROM_DEVICE" /> <ph name="SEPARATOR" /> <ph name="RECENCY" /></translation>
 <translation id="4985206706500620449">Je hebt cookies van derden toegestaan voor deze site</translation>
 <translation id="4994033804516042629">Geen contacten gevonden</translation>
 <translation id="4996978546172906250">Delen via</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_si.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_si.xtb
index 0805e44..44bc78f 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_si.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_si.xtb
@@ -364,6 +364,7 @@
 <translation id="6945221475159498467">තෝරන්න</translation>
 <translation id="6950072572526089586">ඔබ පිවිසෙන අඩවියකට ඔබ කරන දේ පිළිබඳ තතු සුරැකිය හැකි අතර, එවිට එය අපේක්ෂා කරන පරිදි ක්‍රියා කරයි — උදාහරණයක් ලෙස, ඔබව අඩවියකට පුරනය වී තබා ගැනීමට හෝ ඔබේ සාප්පු කරත්තයේ අයිතම සුරැකීමට. බොහෝ විට අඩවි මෙම තතු ඔබේ උපාංගයෙහි තාවකාලිකව සුරකියි.</translation>
 <translation id="6965382102122355670">හරි</translation>
+<translation id="6980861169612950611">අඩවි දත්ත මකන්නද? <ph name="SITE_NAME" /></translation>
 <translation id="6981982820502123353">ප්‍රවේශ්‍යතාව</translation>
 <translation id="6992289844737586249">අඩවි වලට ඔබගේ මයික්‍රෆෝනය භාවිතා කිරීමට ඉඩ දීමට පෙර පළමුව විමසන්න (නිර්දේශිතයි)</translation>
 <translation id="7000754031042624318">Android සැකසීම් තුළ අක්‍රිය කළා</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_sr-Latn.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_sr-Latn.xtb
index 7d985a28..4e16dc78d 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_sr-Latn.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_sr-Latn.xtb
@@ -362,6 +362,7 @@
 <translation id="6945221475159498467">Izaberi</translation>
 <translation id="6950072572526089586">Sajt koji posećujete može da čuva informacije o tome šta radite kako bi radio na očekivani način – na primer, da biste ostali prijavljeni na sajt ili da biste sačuvali stavke u korpi za kupovinu. Sajtovi često privremeno čuvaju te informacije na uređaju.</translation>
 <translation id="6965382102122355670">Potvrdi</translation>
+<translation id="6980861169612950611">Želite da izbrišete podatke sajta? <ph name="SITE_NAME" /></translation>
 <translation id="6981982820502123353">Pristupačnost</translation>
 <translation id="6992289844737586249">Pitaj pre nego što dozvoliš sajtovima da koriste mikrofon (preporučeno)</translation>
 <translation id="7000754031042624318">Isključeno je u Android podešavanjima</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_sr.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_sr.xtb
index b893a76..d4d7783 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_sr.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_sr.xtb
@@ -362,6 +362,7 @@
 <translation id="6945221475159498467">Изабери</translation>
 <translation id="6950072572526089586">Сајт који посећујете може да чува информације о томе шта радите како би радио на очекивани начин – на пример, да бисте остали пријављени на сајт или да бисте сачували ставке у корпи за куповину. Сајтови често привремено чувају те информације на уређају.</translation>
 <translation id="6965382102122355670">Потврди</translation>
+<translation id="6980861169612950611">Желите да избришете податке сајта? <ph name="SITE_NAME" /></translation>
 <translation id="6981982820502123353">Приступачност</translation>
 <translation id="6992289844737586249">Питај пре него што дозволиш сајтовима да користе микрофон (препоручено)</translation>
 <translation id="7000754031042624318">Искључено је у Android подешавањима</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_uz.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_uz.xtb
index a55f9e9..e43714c 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_uz.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_uz.xtb
@@ -158,6 +158,7 @@
 <translation id="3602290021589620013">Razm solish</translation>
 <translation id="3628308229821498208">Tavsiya etilgan qidiruvlar</translation>
 <translation id="3697164069658504920">Yoqilsa, saytlar USB qurilmalardan foydalanishni soʻrashi mumkin. Oʻchirilsa, bunday qurilmalardan foydalana olmaydi.</translation>
+<translation id="3701220924999499408"><ph name="HOST_NAME" /> <ph name="SEPARATOR1" /> <ph name="FROM_DEVICE" /> <ph name="SEPARATOR2" /> <ph name="RECENCY" /></translation>
 <translation id="3707034683772193706">Siz ochadigan sayt Chrome orqali real foydalanuvchi ekaningizni tasdiqlovchi axborotni saqlashi mumkin.</translation>
 <translation id="3721953990244350188">Yopish va keyingi mavjud amalni koʻrsatish</translation>
 <translation id="3744111561329211289">Orqa fonda sinxronlash</translation>
@@ -227,6 +228,7 @@
 <translation id="4962975101802056554">Qurilma uchun barcha ruxsatnomalarni bekor qilish</translation>
 <translation id="497421865427891073">Oldinga</translation>
 <translation id="4976702386844183910">Oxirgi tashrif: <ph name="DATE" /></translation>
+<translation id="498287755803443017"><ph name="FROM_DEVICE" />, <ph name="SEPARATOR" /> (<ph name="RECENCY" />)</translation>
 <translation id="4985206706500620449">Bu sayt uchun tashqi cookie fayllarga ruxsat bergansiz</translation>
 <translation id="4994033804516042629">Hech qanday kontakt topilmadi</translation>
 <translation id="4996978546172906250">Yuborish usuli</translation>
diff --git a/components/browsing_topics/browsing_topics_redirect_observer_unittest.cc b/components/browsing_topics/browsing_topics_redirect_observer_unittest.cc
index b2e7ef51..77d4a1e4a51 100644
--- a/components/browsing_topics/browsing_topics_redirect_observer_unittest.cc
+++ b/components/browsing_topics/browsing_topics_redirect_observer_unittest.cc
@@ -22,11 +22,9 @@
     : public content::RenderViewHostTestHarness {
  public:
   BrowsingTopicsRedirectObserverTest() {
-    // Disable navigation queueing so we can test the racing commit scenario.
     scoped_feature_list_.InitWithFeatures(
         /*enabled_features=*/{blink::features::kBrowsingTopics},
-        /*disabled_features=*/{
-            features::kQueueNavigationsWhileWaitingForCommit});
+        /*disabled_features=*/{});
   }
 
   ~BrowsingTopicsRedirectObserverTest() override = default;
@@ -42,7 +40,6 @@
 
 TEST_F(BrowsingTopicsRedirectObserverTest, TwoNavigationsRacingCommit) {
   BrowsingTopicsRedirectObserver::MaybeCreateForWebContents(web_contents());
-
   auto initial_navigation =
       content::NavigationSimulator::CreateBrowserInitiated(
           GURL("https://foo.com"), web_contents());
@@ -60,7 +57,7 @@
   auto navigation2 = content::NavigationSimulator::CreateRendererInitiated(
       GURL("https://bar.com"), main_rfh());
   navigation2->SetHasUserGesture(false);
-  navigation2->ReadyToCommit();
+  navigation2->Start();
 
   navigation1->Commit();
 
@@ -69,14 +66,14 @@
                 ->redirect_with_topics_invoked_count(),
             1);
 
+  navigation2->ReadyToCommit();
   navigation2->Commit();
 
-  // Even though two navigations have committed in the WebContents, it's okay
-  // and expected for the redirect count to stay at 1 (for Topics API misuse
-  // metrics purposes). This is because the two navigations were initiated from
-  // the same page and were racing, and thus the first navigation cannot pass
-  // information to the second navigation.
-  EXPECT_EQ(GetBrowsingTopicsPageLoadDataTracker()->redirect_count(), 1);
+  // The `redirect_count()` is 2 because the second navigation gets to
+  // ReadyToCommit after the first one committed.
+  // `redirect_with_topics_invoked_count()` is still 1 because Topics API wasn't
+  // invoked.
+  EXPECT_EQ(GetBrowsingTopicsPageLoadDataTracker()->redirect_count(), 2);
   EXPECT_EQ(GetBrowsingTopicsPageLoadDataTracker()
                 ->redirect_with_topics_invoked_count(),
             1);
diff --git a/components/browsing_topics/common/semantic_tree.cc b/components/browsing_topics/common/semantic_tree.cc
index 8ac4ab00..777d6db 100644
--- a/components/browsing_topics/common/semantic_tree.cc
+++ b/components/browsing_topics/common/semantic_tree.cc
@@ -12,6 +12,7 @@
 #include "base/check_op.h"
 #include "base/containers/flat_set.h"
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "base/no_destructor.h"
 #include "base/notreached.h"
 #include "components/strings/grit/components_strings.h"
@@ -90,7 +91,7 @@
   // message ID.
   base::flat_map<uint16_t, uint16_t> renamed_topics;
   // The topics that have been deleted since the prior taxonomy version.
-  const base::span<const uint16_t> deleted_topics;
+  const base::raw_span<const uint16_t> deleted_topics;
 };
 
 const uint16_t kDeletedTopicsV2[] = {
diff --git a/components/cbor/reader.h b/components/cbor/reader.h
index 73c5dcb..5f11ba48 100644
--- a/components/cbor/reader.h
+++ b/components/cbor/reader.h
@@ -12,6 +12,7 @@
 
 #include "base/containers/span.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_span.h"
 #include "components/cbor/cbor_export.h"
 #include "components/cbor/values.h"
 
@@ -218,7 +219,7 @@
 
   size_t num_bytes_remaining() const { return rest_.size(); }
 
-  base::span<const uint8_t> rest_;
+  base::raw_span<const uint8_t> rest_;
   DecoderError error_code_;
 };
 
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json
index 79108dc..bd3cec4b 100644
--- a/components/certificate_transparency/data/log_list.json
+++ b/components/certificate_transparency/data/log_list.json
@@ -1,6 +1,6 @@
 {
-  "version": "35.28",
-  "log_list_timestamp": "2024-06-15T12:55:09Z",
+  "version": "35.30",
+  "log_list_timestamp": "2024-06-17T12:54:37Z",
   "operators": [
     {
       "name": "Google",
diff --git a/components/commerce/core/commerce_feature_list.cc b/components/commerce/core/commerce_feature_list.cc
index 6a6f6dc..cefdf0cd 100644
--- a/components/commerce/core/commerce_feature_list.cc
+++ b/components/commerce/core/commerce_feature_list.cc
@@ -493,11 +493,8 @@
 }
 
 bool IsShoppingListAllowedForEnterprise(PrefService* prefs) {
-  const base::Value* pref =
-      prefs->GetUserPrefValue(kShoppingListEnabledPrefName);
-
-  // Default to true if there is no value set.
-  return !pref || pref->GetBool();
+  return prefs->GetBoolean(kShoppingListEnabledPrefName) ||
+         !prefs->IsManagedPreference(kShoppingListEnabledPrefName);
 }
 
 bool IsEnabledForCountryAndLocale(const base::Feature& feature,
diff --git a/components/commerce/core/commerce_feature_list_unittest.cc b/components/commerce/core/commerce_feature_list_unittest.cc
index b9822441..1d9ef7c 100644
--- a/components/commerce/core/commerce_feature_list_unittest.cc
+++ b/components/commerce/core/commerce_feature_list_unittest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "components/commerce/core/commerce_feature_list.h"
+
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/buildflag.h"
@@ -10,6 +11,7 @@
 #include "components/commerce/core/commerce_heuristics_data_metrics_helper.h"
 #include "components/commerce/core/pref_names.h"
 #include "components/commerce/core/test_utils.h"
+#include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/testing_pref_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -172,3 +174,22 @@
   ASSERT_FALSE(commerce::IsEnabledForCountryAndLocale(
       commerce::kShoppingPDPMetricsRegionLaunched, "", ""));
 }
+
+TEST_F(CommerceFeatureListTest, IsShoppingListEnabled) {
+  TestingPrefServiceSimple prefs;
+  prefs.registry()->RegisterBooleanPref(commerce::kShoppingListEnabledPrefName,
+                                        true);
+
+  EXPECT_TRUE(commerce::IsShoppingListAllowedForEnterprise(&prefs));
+
+  prefs.SetUserPref(commerce::kShoppingListEnabledPrefName, base::Value(false));
+  EXPECT_TRUE(commerce::IsShoppingListAllowedForEnterprise(&prefs));
+
+  prefs.SetManagedPref(commerce::kShoppingListEnabledPrefName,
+                       base::Value(true));
+  EXPECT_TRUE(commerce::IsShoppingListAllowedForEnterprise(&prefs));
+
+  prefs.SetManagedPref(commerce::kShoppingListEnabledPrefName,
+                       base::Value(false));
+  EXPECT_FALSE(commerce::IsShoppingListAllowedForEnterprise(&prefs));
+}
diff --git a/components/commerce/core/test_utils.cc b/components/commerce/core/test_utils.cc
index 74fded64..03aabe96 100644
--- a/components/commerce/core/test_utils.cc
+++ b/components/commerce/core/test_utils.cc
@@ -18,6 +18,7 @@
 #include "components/power_bookmarks/core/proto/power_bookmark_meta.pb.h"
 #include "components/power_bookmarks/core/proto/shopping_specifics.pb.h"
 #include "components/prefs/pref_service.h"
+#include "components/prefs/testing_pref_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
@@ -78,8 +79,9 @@
                                             std::move(meta));
 }
 
-void SetShoppingListEnterprisePolicyPref(PrefService* prefs, bool enabled) {
-  prefs->SetBoolean(kShoppingListEnabledPrefName, enabled);
+void SetShoppingListEnterprisePolicyPref(TestingPrefServiceSimple* prefs,
+                                         bool enabled) {
+  prefs->SetManagedPref(kShoppingListEnabledPrefName, base::Value(enabled));
 }
 
 std::optional<PriceInsightsInfo> CreateValidPriceInsightsInfo(
diff --git a/components/commerce/core/test_utils.h b/components/commerce/core/test_utils.h
index a0e8df7..aecbb71 100644
--- a/components/commerce/core/test_utils.h
+++ b/components/commerce/core/test_utils.h
@@ -13,7 +13,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 
 class GURL;
-class PrefService;
+class TestingPrefServiceSimple;
 
 namespace bookmarks {
 class BookmarkModel;
@@ -72,7 +72,8 @@
 
 // Sets the state of the enterprise policy for the shopping list feature for
 // testing.
-void SetShoppingListEnterprisePolicyPref(PrefService* prefs, bool enabled);
+void SetShoppingListEnterprisePolicyPref(TestingPrefServiceSimple* prefs,
+                                         bool enabled);
 
 std::optional<PriceInsightsInfo> CreateValidPriceInsightsInfo(
     bool has_price_range_data = false,
diff --git a/components/commerce_strings.grdp b/components/commerce_strings.grdp
index a1617b8..307296b 100644
--- a/components/commerce_strings.grdp
+++ b/components/commerce_strings.grdp
@@ -440,6 +440,12 @@
   <message name="IDS_PRICE_INSIGHTS_TRACK_BUTTON_TITLE" desc="The title text for track button of price insights.">
     Track
   </message>
+  <message name="IDS_PRICE_INSIGHTS_RANGE_LABEL_LOW" desc="The range slider label text for low prices.">
+    Low
+  </message>
+  <message name="IDS_PRICE_INSIGHTS_RANGE_LABEL_HIGH" desc="The range slider label text for high prices.">
+    High
+  </message>
   <message name="IDS_PRICE_INSIGHTS_TRACKING_BUTTON_TITLE" desc="The title text for tracking button of price insights.">
     Tracking
   </message>
@@ -465,9 +471,12 @@
     <message name="IDS_SHOPPING_INSIGHTS_ICON_EXPANDED_TEXT_HIGH_PRICE" desc="The expanded text for the price insights icon in the location bar, indicating an option has relatively high price.">
       Price is High
     </message>
-    <message name="IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE" desc="The title text for the price range component of price insights.">
+    <message name="IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE_VARIANT" desc="The title text for the price range component of price insights when the product has a variant.">
       Price Range for All Options
     </message>
+    <message name="IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE_NO_VARIANT" desc="The title text for the price range component of price insights when the product has no variant.">
+      Price Range
+    </message>
   </if> <!-- use_titlecase -->
   <if expr="not use_titlecase">
     <message name="IDS_PRICE_HISTORY_TITLE_SINGLE_OPTION" desc="The title of the Price History section in the Shopping Insights side panel when we only find one option of this product.">
@@ -479,9 +488,12 @@
     <message name="IDS_SHOPPING_INSIGHTS_ICON_EXPANDED_TEXT_HIGH_PRICE" desc="The expanded text for the price insights icon in the location bar, indicating an option has relatively high price.">
       Price is high
     </message>
-    <message name="IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE" desc="The title text for the price range component of price insights.">
+    <message name="IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE_VARIANT" desc="The title text for the price range component of price insights when the product has a variant.">
       Price range for all options
     </message>
+    <message name="IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE_NO_VARIANT" desc="The title text for the price range component of price insights when the product has no variant.">
+      Price range
+    </message>
   </if> <!-- not use_titlecase -->
 
   <message name="IDS_SHOPPING_COLLECTION_FOLDER_NAME" desc="The name of bookmark folder that is automatically created when a user bookmarks a product page.">
diff --git a/components/commerce_strings_grdp/IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE_NO_VARIANT.png.sha1 b/components/commerce_strings_grdp/IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE_NO_VARIANT.png.sha1
new file mode 100644
index 0000000..3b99daa
--- /dev/null
+++ b/components/commerce_strings_grdp/IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE_NO_VARIANT.png.sha1
@@ -0,0 +1 @@
+feb3255e51f94a0512e6d0cb9f355c1864f41da4
\ No newline at end of file
diff --git a/components/commerce_strings_grdp/IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE.png.sha1 b/components/commerce_strings_grdp/IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE_VARIANT.png.sha1
similarity index 100%
rename from components/commerce_strings_grdp/IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE.png.sha1
rename to components/commerce_strings_grdp/IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE_VARIANT.png.sha1
diff --git a/components/commerce_strings_grdp/IDS_PRICE_INSIGHTS_RANGE_LABEL_HIGH.png.sha1 b/components/commerce_strings_grdp/IDS_PRICE_INSIGHTS_RANGE_LABEL_HIGH.png.sha1
new file mode 100644
index 0000000..388a402
--- /dev/null
+++ b/components/commerce_strings_grdp/IDS_PRICE_INSIGHTS_RANGE_LABEL_HIGH.png.sha1
@@ -0,0 +1 @@
+6ded45b199b9576a980238e316e757ea3c0edaae
\ No newline at end of file
diff --git a/components/commerce_strings_grdp/IDS_PRICE_INSIGHTS_RANGE_LABEL_LOW.png.sha1 b/components/commerce_strings_grdp/IDS_PRICE_INSIGHTS_RANGE_LABEL_LOW.png.sha1
new file mode 100644
index 0000000..388a402
--- /dev/null
+++ b/components/commerce_strings_grdp/IDS_PRICE_INSIGHTS_RANGE_LABEL_LOW.png.sha1
@@ -0,0 +1 @@
+6ded45b199b9576a980238e316e757ea3c0edaae
\ No newline at end of file
diff --git a/components/content_capture/common/content_capture_features.cc b/components/content_capture/common/content_capture_features.cc
index 1c80d889..d6ceb49 100644
--- a/components/content_capture/common/content_capture_features.cc
+++ b/components/content_capture/common/content_capture_features.cc
@@ -29,10 +29,6 @@
              base::FEATURE_DISABLED_BY_DEFAULT);
 #endif
 
-BASE_FEATURE(kContentCaptureInWebLayer,
-             "ContentCaptureInWebLayer",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
 bool IsContentCaptureEnabled() {
   return base::FeatureList::IsEnabled(kContentCapture);
 }
@@ -41,10 +37,6 @@
   return base::FeatureList::IsEnabled(kContentCaptureTriggeringForExperiment);
 }
 
-bool IsContentCaptureEnabledInWebLayer() {
-  return base::FeatureList::IsEnabled(kContentCaptureInWebLayer);
-}
-
 int TaskInitialDelayInMilliseconds() {
   return base::GetFieldTrialParamByFeatureAsInt(
       kContentCapture, "task_initial_delay_in_milliseconds", 500);
diff --git a/components/content_capture/common/content_capture_features.h b/components/content_capture/common/content_capture_features.h
index b165493..6753e33 100644
--- a/components/content_capture/common/content_capture_features.h
+++ b/components/content_capture/common/content_capture_features.h
@@ -18,13 +18,8 @@
 // us to trigger the ContentCapture independently to get the unbiased result.
 BASE_DECLARE_FEATURE(kContentCaptureTriggeringForExperiment);
 
-// ContentCapture in WebLayer, this flag is independent from the kContentCapture
-// flag.
-BASE_DECLARE_FEATURE(kContentCaptureInWebLayer);
-
 bool IsContentCaptureEnabled();
 bool ShouldTriggerContentCaptureForExperiment();
-bool IsContentCaptureEnabledInWebLayer();
 
 int TaskInitialDelayInMilliseconds();
 
diff --git a/components/content_settings/core/browser/content_settings_registry.cc b/components/content_settings/core/browser/content_settings_registry.cc
index 229ac34..11ac041 100644
--- a/components/content_settings/core/browser/content_settings_registry.cc
+++ b/components/content_settings/core/browser/content_settings_registry.cc
@@ -529,7 +529,7 @@
            /*allowlisted_primary_schemes=*/{},
            /*valid_settings=*/
            {CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK, CONTENT_SETTING_BLOCK},
-           WebsiteSettingsInfo::REQUESTING_AND_TOP_ORIGIN_SCOPE,
+           WebsiteSettingsInfo::REQUESTING_ORIGIN_AND_TOP_SCHEMEFUL_SITE_SCOPE,
            WebsiteSettingsRegistry::ALL_PLATFORMS,
            ContentSettingsInfo::INHERIT_IF_LESS_PERMISSIVE,
            ContentSettingsInfo::EXCEPTIONS_ON_SECURE_AND_INSECURE_ORIGINS);
diff --git a/components/content_settings/core/browser/host_content_settings_map.cc b/components/content_settings/core/browser/host_content_settings_map.cc
index 5182be2..210a4fca 100644
--- a/components/content_settings/core/browser/host_content_settings_map.cc
+++ b/components/content_settings/core/browser/host_content_settings_map.cc
@@ -167,12 +167,6 @@
       patterns.first = ContentSettingsPattern::FromURL(primary_url);
       patterns.second = ContentSettingsPattern::Wildcard();
       break;
-    case WebsiteSettingsInfo::REQUESTING_AND_TOP_ORIGIN_SCOPE:
-      CHECK(!secondary_url.is_empty());
-      patterns.first = ContentSettingsPattern::FromURLNoWildcard(primary_url);
-      patterns.second =
-          ContentSettingsPattern::FromURLNoWildcard(secondary_url);
-      break;
     case WebsiteSettingsInfo::REQUESTING_AND_TOP_SCHEMEFUL_SITE_SCOPE:
       CHECK(!secondary_url.is_empty());
       patterns.first =
diff --git a/components/content_settings/core/browser/website_settings_info.cc b/components/content_settings/core/browser/website_settings_info.cc
index 74c69f3..c2e3c96 100644
--- a/components/content_settings/core/browser/website_settings_info.cc
+++ b/components/content_settings/core/browser/website_settings_info.cc
@@ -70,7 +70,6 @@
 bool WebsiteSettingsInfo::SupportsSecondaryPattern() const {
   switch (scoping_type_) {
     case REQUESTING_ORIGIN_WITH_TOP_ORIGIN_EXCEPTIONS_SCOPE:
-    case REQUESTING_AND_TOP_ORIGIN_SCOPE:
     case TOP_ORIGIN_WITH_RESOURCE_EXCEPTIONS_SCOPE:
     case REQUESTING_AND_TOP_SCHEMEFUL_SITE_SCOPE:
     case REQUESTING_ORIGIN_AND_TOP_SCHEMEFUL_SITE_SCOPE:
diff --git a/components/content_settings/core/browser/website_settings_info.h b/components/content_settings/core/browser/website_settings_info.h
index c44e599..8d6b167 100644
--- a/components/content_settings/core/browser/website_settings_info.h
+++ b/components/content_settings/core/browser/website_settings_info.h
@@ -42,13 +42,6 @@
     // right and often result in surprising UX.
     REQUESTING_ORIGIN_WITH_TOP_ORIGIN_EXCEPTIONS_SCOPE,
 
-    // Settings scoped to the origin of the requesting frame and the top-level
-    // frame.
-    // Use only after strongly considering if this is the right choice;
-    // presenting settings that are scoped on two origins is difficult to get
-    // right and often result in surprising UX.
-    REQUESTING_AND_TOP_ORIGIN_SCOPE,
-
     // Settings scoped to the schemeful site of the requesting frame and the
     // top-level frame.
     // Use only after strongly considering if this is the right choice;
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetManifest.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetManifest.java
index 9ab09d2..b8e82280 100644
--- a/components/cronet/android/java/src/org/chromium/net/impl/CronetManifest.java
+++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetManifest.java
@@ -4,6 +4,7 @@
 
 package org.chromium.net.impl;
 
+import android.annotation.SuppressLint;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -17,7 +18,7 @@
 /**
  * Utilities for working with Cronet Android manifest flags.
  *
- * Cronet manifest flags must be defined within a service definition named after {@link
+ * <p>Cronet manifest flags must be defined within a service definition named after {@link
  * #META_DATA_HOLDER_SERVICE_NAME} (the reason this is not defined at the application level is to
  * avoid scalability issues with PackageManager queries). For example, to enable telemetry, add the
  * following to {@code AndroidManifest.xml}:
@@ -71,26 +72,60 @@
         return getMetaData(context).getBoolean(READ_HTTP_FLAGS_META_DATA_KEY, /* default= */ true);
     }
 
+    private static final Object sLock = new Object();
+
+    // Leaking this is fine because this is storing an application context which lives for the
+    // entire process duration anyway.
+    @SuppressLint("StaticFieldLeak")
+    private static Context sLastContext;
+
+    private static Bundle sMetaData;
+
     /**
      * @return The meta-data contained within the Cronet meta-data holder service definition in the
-     * Android manifest, or an empty Bundle if there is no such definition. Never returns null.
+     *     Android manifest, or an empty Bundle if there is no such definition. Never returns null.
      */
     private static Bundle getMetaData(Context context) {
-        ServiceInfo serviceInfo;
-        try {
-            serviceInfo =
-                    context.getPackageManager()
-                            .getServiceInfo(
-                                    new ComponentName(context, META_DATA_HOLDER_SERVICE_NAME),
-                                    PackageManager.GET_META_DATA
-                                            | PackageManager.MATCH_DISABLED_COMPONENTS
-                                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
-                                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
-        } catch (PackageManager.NameNotFoundException | NullPointerException e) {
-            // TODO(b/331573772): Consider removing this NPE check once we can check for
-            // CRONET_SOURCE_FAKE when creating logger.
-            serviceInfo = null;
+        // Make sure we don't create a memory leak by only caching the application context, not a
+        // local short-lived context.
+        context = context.getApplicationContext();
+        synchronized (sLock) {
+            // If we are being asked for the meta-data again for the same Context, assume the answer
+            // will be the same and serve a cached result. This is deemed safe because manifests are
+            // not supposed to change over the lifetime of the app, and this makes the code
+            // considerably more efficient because PackageManager calls are expensive (they involve
+            // an IPC to the system server). See also https://crbug.com/346546533.
+            if (context != sLastContext) {
+                ServiceInfo serviceInfo;
+                try {
+                    serviceInfo =
+                            context.getPackageManager()
+                                    .getServiceInfo(
+                                            new ComponentName(
+                                                    context, META_DATA_HOLDER_SERVICE_NAME),
+                                            PackageManager.GET_META_DATA
+                                                    | PackageManager.MATCH_DISABLED_COMPONENTS
+                                                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
+                                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
+                } catch (PackageManager.NameNotFoundException | NullPointerException e) {
+                    // TODO(b/331573772): Consider removing this NPE check once we can check for
+                    // CRONET_SOURCE_FAKE when creating logger.
+                    serviceInfo = null;
+                }
+                sMetaData =
+                        serviceInfo != null && serviceInfo.metaData != null
+                                ? serviceInfo.metaData
+                                : new Bundle();
+                sLastContext = context;
+            }
+            assert sMetaData != null;
+            return sMetaData;
         }
-        return serviceInfo != null ? serviceInfo.metaData : new Bundle();
+    }
+
+    @VisibleForTesting
+    public static void resetCache() {
+        sMetaData = null;
+        sLastContext = null;
     }
 }
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestRule.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestRule.java
index 303600c..b1c75f7 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestRule.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestRule.java
@@ -29,6 +29,7 @@
 import org.chromium.base.PathUtils;
 import org.chromium.net.httpflags.Flags;
 import org.chromium.net.httpflags.HttpFlagsInterceptor;
+import org.chromium.net.impl.CronetManifest;
 import org.chromium.net.impl.CronetUrlRequestContext;
 import org.chromium.net.impl.HttpEngineNativeProvider;
 import org.chromium.net.impl.JavaCronetEngine;
@@ -459,6 +460,7 @@
                                 .build());
             }
 
+            CronetManifest.resetCache();
             setHttpFlags(null);
         }
 
diff --git a/components/embedder_support/android/BUILD.gn b/components/embedder_support/android/BUILD.gn
index f6050a5d..374e8fa 100644
--- a/components/embedder_support/android/BUILD.gn
+++ b/components/embedder_support/android/BUILD.gn
@@ -266,6 +266,7 @@
   sources = [
     "contextmenu/context_menu_builder.cc",
     "contextmenu/context_menu_builder.h",
+    "contextmenu/context_menu_image_format.h",
   ]
   deps = [
     ":context_menu_jni_headers",
@@ -280,6 +281,10 @@
   sources = [ "java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuParams.java" ]
 }
 
+java_cpp_enum("context_menu_image_format_enum_javagen") {
+  sources = [ "contextmenu/context_menu_image_format.h" ]
+}
+
 android_library("context_menu_java") {
   deps = [
     "//base:base_java",
@@ -291,8 +296,19 @@
     "//url:gurl_java",
   ]
 
-  srcjar_deps = [ ":context_menu_jni_headers" ]
-  sources = [ "java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuParams.java" ]
+  srcjar_deps = [
+    ":context_menu_jni_headers",
+    ":context_menu_image_format_enum_javagen",
+  ]
+  sources = [
+    "java/src/org/chromium/components/embedder_support/contextmenu/ChipDelegate.java",
+    "java/src/org/chromium/components/embedder_support/contextmenu/ChipRenderParams.java",
+    "java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuItemDelegate.java",
+    "java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuNativeDelegate.java",
+    "java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuParams.java",
+    "java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuPopulator.java",
+    "java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuPopulatorFactory.java",
+  ]
 }
 
 android_library("native_java_unittests_java") {
diff --git a/components/embedder_support/android/contextmenu/context_menu_image_format.h b/components/embedder_support/android/contextmenu/context_menu_image_format.h
new file mode 100644
index 0000000..9794d1e6
--- /dev/null
+++ b/components/embedder_support/android/contextmenu/context_menu_image_format.h
@@ -0,0 +1,15 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_EMBEDDER_SUPPORT_ANDROID_CONTEXTMENU_CONTEXT_MENU_IMAGE_FORMAT_H_
+#define COMPONENTS_EMBEDDER_SUPPORT_ANDROID_CONTEXTMENU_CONTEXT_MENU_IMAGE_FORMAT_H_
+
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.embedder_support.contextmenu
+enum ContextMenuImageFormat {
+  JPEG = 0,
+  PNG = 1,
+  ORIGINAL = 2,
+};
+
+#endif  // COMPONENTS_EMBEDDER_SUPPORT_ANDROID_CONTEXTMENU_CONTEXT_MENU_IMAGE_FORMAT_H_
diff --git a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ChipDelegate.java b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ChipDelegate.java
similarity index 84%
rename from chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ChipDelegate.java
rename to components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ChipDelegate.java
index 1a089d67..c4b6c3f 100644
--- a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ChipDelegate.java
+++ b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ChipDelegate.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.contextmenu;
+package org.chromium.components.embedder_support.contextmenu;
 
 import org.chromium.base.Callback;
 
@@ -10,14 +10,16 @@
 public interface ChipDelegate {
     /**
      * Determines whether the chip delegate is able to support a chip in the chosen context.
+     *
      * @return Whether the chip can be supported and rendered.
      */
     boolean isChipSupported();
 
     /**
      * Retrieves the data for displaying a chip below the context menu.
-     * @param callback The callback will always be called with the retrieved ChipRenderParams.
-     *                 The ChipRenderParams will be null in the event there is no chip to show.
+     *
+     * @param callback The callback will always be called with the retrieved ChipRenderParams. The
+     *     ChipRenderParams will be null in the event there is no chip to show.
      */
     void getChipRenderParams(Callback<ChipRenderParams> callback);
 
@@ -26,6 +28,7 @@
 
     /**
      * Check whether the ChipRenderParams object is valid. Called before displaying the chip.
+     *
      * @param chipRenderParams A wrapper object contains the params used when rendering the chip.
      * @return True if the params are valid.
      */
diff --git a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ChipRenderParams.java b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ChipRenderParams.java
similarity index 95%
rename from chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ChipRenderParams.java
rename to components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ChipRenderParams.java
index 9a49de0..f5a086e 100644
--- a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ChipRenderParams.java
+++ b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ChipRenderParams.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.contextmenu;
+package org.chromium.components.embedder_support.contextmenu;
 
 import androidx.annotation.DrawableRes;
 import androidx.annotation.IntDef;
diff --git a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuItemDelegate.java
similarity index 88%
rename from chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java
rename to components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuItemDelegate.java
index 7f5f040..e9ad0778 100644
--- a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuItemDelegate.java
+++ b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuItemDelegate.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.contextmenu;
+package org.chromium.components.embedder_support.contextmenu;
 
 import android.net.Uri;
 
@@ -32,12 +32,12 @@
     void onDestroy();
 
     /**
-     * @return The title of the current tab associated with this delegate..
+     * @return The title of the current page associated with this delegate..
      */
     String getPageTitle();
 
     /**
-     * @return The web contents of the current tab owned by this delegate.
+     * @return The web contents of the current page owned by this delegate.
      */
     WebContents getWebContents();
 
@@ -47,7 +47,7 @@
     boolean isIncognito();
 
     /**
-     * @return Whether or not the current application can show incognito tabs.
+     * @return Whether or not the current application can show incognito pages.
      */
     boolean isIncognitoSupported();
 
@@ -63,27 +63,30 @@
 
     /**
      * Called when the context menu is trying to start a download.
+     *
      * @param url Url of the download item.
      * @param isLink Whether or not the download is a link (as opposed to an image/video).
-     * @return       Whether or not a download should actually be started.
+     * @return Whether or not a download should actually be started.
      */
     boolean startDownload(GURL url, boolean isLink);
 
     /**
      * Called when the {@code url} should be opened in the other window with the same incognito
-     * state as the current {@link Tab}.
+     * state as the current page.
+     *
      * @param url The URL to open.
      */
     void onOpenInOtherWindow(GURL url, Referrer referrer);
 
     /**
-     * Called when the {@code url} should be opened in a new tab with the same incognito state as
-     * the current {@link Tab}.
+     * Called when the {@code url} should be opened in a new page with the same incognito state as
+     * the current page.
+     *
      * @param url The URL to open.
-     * @param navigateToTab Whether or not to navigate to the new tab.
+     * @param navigateToTab Whether or not to navigate to the new page.
      * @param impression The attribution impression to associate with the navigation.
      * @param additionalNavigationParams Additional information that needs to be passed to the
-     * navigation request.
+     *     navigation request.
      */
     void onOpenInNewTab(
             GURL url,
@@ -92,32 +95,36 @@
             @Nullable AdditionalNavigationParams additionalNavigationParams);
 
     /**
-     * Called when {@code url} should be opened in a new tab in the same group as the current
-     * {@link Tab}.
+     * Called when {@code url} should be opened in a new page in the same group as the current page.
+     *
      * @param url The URL to open.
      */
     void onOpenInNewTabInGroup(GURL url, Referrer referrer);
 
     /**
-     * Called when the {@code url} should be opened in a new incognito tab.
+     * Called when the {@code url} should be opened in a new incognito page.
+     *
      * @param url The URL to open.
      */
     void onOpenInNewIncognitoTab(GURL url);
 
     /**
-     * Called when the {@code url} is of an image and should be opened in the same tab.
+     * Called when the {@code url} is of an image and should be opened in the same page.
+     *
      * @param url The image URL to open.
      */
     void onOpenImageUrl(GURL url, Referrer referrer);
 
     /**
-     * Called when the {@code url} is of an image and should be opened in a new tab.
+     * Called when the {@code url} is of an image and should be opened in a new page.
+     *
      * @param url The image URL to open.
      */
     void onOpenImageInNewTab(GURL url, Referrer referrer);
 
     /**
      * Called when the {@code text} should be saved to the clipboard.
+     *
      * @param text The text to save to the clipboard.
      * @param clipboardType The type of data in {@code text}.
      */
@@ -125,6 +132,7 @@
 
     /**
      * Called when the image should be saved to the clipboard.
+     *
      * @param Uri The (@link Uri) of the image to save to the clipboard.
      */
     void onSaveImageToClipboard(Uri uri);
@@ -136,6 +144,7 @@
 
     /**
      * Called when the {@code url} should be parsed to call a phone number.
+     *
      * @param url The URL to be parsed to call a phone number.
      */
     void onCall(GURL url);
@@ -147,6 +156,7 @@
 
     /**
      * Called when the {@code url} should be parsed to send an email.
+     *
      * @param url The URL to be parsed to send an email.
      */
     void onSendEmailMessage(GURL url);
@@ -158,18 +168,21 @@
 
     /**
      * Called when the {@code url} should be parsed to send a text message.
+     *
      * @param url The URL to be parsed to send a text message.
      */
     void onSendTextMessage(GURL url);
 
     /**
      * Returns whether or not an activity is available to handle intent to add contacts.
+     *
      * @return true if an activity is available to handle intent to add contacts.
      */
     public boolean supportsAddToContacts();
 
     /**
      * Called when the {@code url} should be parsed to add to contacts.
+     *
      * @param url The URL to be parsed to add to contacts.
      */
     void onAddToContacts(GURL url);
@@ -181,15 +194,17 @@
 
     /**
      * Called when a link should be opened in the main Chrome browser.
+     *
      * @param linkUrl URL that should be opened.
      * @param pageUrl URL of the current page.
      */
     void onOpenInChrome(GURL linkUrl, GURL pageUrl);
 
     /**
-     * Called when the {@code url} should be opened in a new Chrome tab from CCT.
+     * Called when the {@code url} should be opened in a new Chrome page from CCT.
+     *
      * @param linkUrl The URL to open.
-     * @param isIncognito true if the {@code url} should be opened in a new incognito tab.
+     * @param isIncognito true if the {@code url} should be opened in a new incognito page.
      */
     void onOpenInNewChromeTabFromCCT(GURL linkUrl, boolean isIncognito);
 
@@ -200,12 +215,14 @@
 
     /**
      * Called when the current Chrome app is not the default to handle a View Intent.
+     *
      * @param url The URL to open.
      */
     void onOpenInDefaultBrowser(GURL url);
 
     /**
-     * Called when the {@code url} should be opened in an ephemeral tab.
+     * Called when the {@code url} should be opened in an ephemeral page.
+     *
      * @param url The URL to open.
      * @param title The title text to show on top control.
      */
@@ -213,6 +230,7 @@
 
     /**
      * Called when Read Later was selected from the context menu.
+     *
      * @param url The URL to be saved to the reading list.
      * @param title The title text to be shown for this item in the reading list.
      */
diff --git a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuNativeDelegate.java b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuNativeDelegate.java
similarity index 90%
rename from chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuNativeDelegate.java
rename to components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuNativeDelegate.java
index 405308e..a44d4e0d 100644
--- a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuNativeDelegate.java
+++ b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuNativeDelegate.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.contextmenu;
+package org.chromium.components.embedder_support.contextmenu;
 
 import android.graphics.Bitmap;
 import android.net.Uri;
@@ -16,8 +16,9 @@
     void destroy();
 
     /**
-     * Retrieves the image bitmap from the current {@link RenderFrameHost} that the context menu
-     * was triggered on to use in the context menu.
+     * Retrieves the image bitmap from the current {@link RenderFrameHost} that the context menu was
+     * triggered on to use in the context menu.
+     *
      * @param maxWidthPx The maximum width for the retrieved bitmap in pixels.
      * @param maxHeightPx The maximum height for the retrieved bitmap in pixels.
      * @param callback The callback to be called with the retrieved bitmap.
@@ -27,6 +28,7 @@
     /**
      * Retrieves the image from the current {@link RenderFrameHost} that the context menu was
      * triggered on, to be shared.
+     *
      * @param imageFormat The image format that will be requested.
      * @param callback The callback to be called with the retrieved image's {@link Uri}.
      */
@@ -34,6 +36,7 @@
 
     /**
      * Starts a download based on the params.
+     *
      * @param isLink Whether the download target is a link.
      */
     void startDownload(boolean isLink);
@@ -43,6 +46,7 @@
 
     /**
      * Get the current {@link RenderFrameHost} that the context menu was triggered on, to be shared.
+     *
      * @return {@link RenderFrameHost}.
      */
     RenderFrameHost getRenderFrameHost();
diff --git a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuPopulator.java b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuPopulator.java
similarity index 72%
rename from chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuPopulator.java
rename to components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuPopulator.java
index b66c31d..bf66693 100644
--- a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuPopulator.java
+++ b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuPopulator.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.contextmenu;
+package org.chromium.components.embedder_support.contextmenu;
 
 import android.util.Pair;
 
@@ -19,18 +19,20 @@
 public interface ContextMenuPopulator {
     /**
      * Should be used to populate {@code menu} with the correct context menu items.
+     *
      * @return A list separate by groups. Each "group" will contain items related to said group as
-     *         well as an integer that is a string resource for the group. Image items will have
-     *         items that belong to that are related to that group and the string resource for the
-     *         group will likely say "IMAGE". If the link pressed is contains multiple items (like
-     *         an image link) the list will have both an image list and a link list.
+     *     well as an integer that is a string resource for the group. Image items will have items
+     *     that belong to that are related to that group and the string resource for the group will
+     *     likely say "IMAGE". If the link pressed is contains multiple items (like an image link)
+     *     the list will have both an image list and a link list.
      */
     List<Pair<Integer, ModelList>> buildContextMenu();
 
     /**
      * Called when a context menu item has been selected.
+     *
      * @param itemId The id of the selected menu item.
-     * @return       Whether or not the selection was handled.
+     * @return Whether or not the selection was handled.
      */
     boolean onItemSelected(int itemId);
 
diff --git a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuPopulatorFactory.java b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuPopulatorFactory.java
similarity index 88%
rename from chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuPopulatorFactory.java
rename to components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuPopulatorFactory.java
index 9d4df2c..9687028 100644
--- a/chrome/browser/contextmenu/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuPopulatorFactory.java
+++ b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/contextmenu/ContextMenuPopulatorFactory.java
@@ -2,12 +2,10 @@
 // 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.contextmenu;
+package org.chromium.components.embedder_support.contextmenu;
 
 import android.content.Context;
 
-import org.chromium.components.embedder_support.contextmenu.ContextMenuParams;
-
 /** Factory interface for creating {@link ContextMenuPopulator}s. */
 public interface ContextMenuPopulatorFactory {
     /**
diff --git a/components/facilitated_payments/android/facilitated_payments_api_client_android.cc b/components/facilitated_payments/android/facilitated_payments_api_client_android.cc
index 809b639..d3dd2813 100644
--- a/components/facilitated_payments/android/facilitated_payments_api_client_android.cc
+++ b/components/facilitated_payments/android/facilitated_payments_api_client_android.cc
@@ -10,7 +10,10 @@
 #include "base/android/jni_android.h"
 #include "base/android/jni_array.h"
 #include "base/check.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "components/signin/public/identity_manager/account_info.h"
+#include "content/public/browser/global_routing_id.h"
 #include "content/public/browser/render_frame_host.h"
 
 // Must come after all headers that specialize FromJniType() / ToJniType().
@@ -18,13 +21,23 @@
 
 namespace payments::facilitated {
 
+std::unique_ptr<FacilitatedPaymentsApiClient>
+LazyInitFacilitatedPaymentsApiClient(
+    content::GlobalRenderFrameHostId render_frame_host_id) {
+  content::RenderFrameHost* render_frame_host =
+      content::RenderFrameHost::FromID(render_frame_host_id);
+  return render_frame_host
+             ? std::make_unique<FacilitatedPaymentsApiClientAndroid>(
+                   render_frame_host)
+             : nullptr;
+}
+
 // Declared in the cross-platform header
 // `facilitated_payments_api_client_factory.h`.
-std::unique_ptr<FacilitatedPaymentsApiClient>
-CreateFacilitatedPaymentsApiClient(
-    content::RenderFrameHost* render_frame_host) {
-  return std::make_unique<FacilitatedPaymentsApiClientAndroid>(
-      render_frame_host);
+FacilitatedPaymentsApiClientCreator GetFacilitatedPaymentsApiClientCreator(
+    content::GlobalRenderFrameHostId render_frame_host_id) {
+  return base::BindOnce(&LazyInitFacilitatedPaymentsApiClient,
+                        render_frame_host_id);
 }
 
 FacilitatedPaymentsApiClientAndroid::FacilitatedPaymentsApiClientAndroid(
diff --git a/components/facilitated_payments/content/browser/content_facilitated_payments_driver.cc b/components/facilitated_payments/content/browser/content_facilitated_payments_driver.cc
index 69102d4..5db38a2 100644
--- a/components/facilitated_payments/content/browser/content_facilitated_payments_driver.cc
+++ b/components/facilitated_payments/content/browser/content_facilitated_payments_driver.cc
@@ -22,9 +22,10 @@
     : FacilitatedPaymentsDriver(std::make_unique<FacilitatedPaymentsManager>(
           /*driver=*/this,
           client,
-          CreateFacilitatedPaymentsApiClient(render_frame_host),
+          GetFacilitatedPaymentsApiClientCreator(
+              render_frame_host->GetGlobalId()),
           optimization_guide_decider)),
-      render_frame_host_(*render_frame_host) {}
+      render_frame_host_id_(render_frame_host->GetGlobalId()) {}
 
 ContentFacilitatedPaymentsDriver::~ContentFacilitatedPaymentsDriver() = default;
 
@@ -36,8 +37,12 @@
 
 const mojo::AssociatedRemote<mojom::FacilitatedPaymentsAgent>&
 ContentFacilitatedPaymentsDriver::GetAgent() {
-  if (!agent_) {
-    render_frame_host_->GetRemoteAssociatedInterfaces()->GetInterface(&agent_);
+  if (!agent_.is_bound()) {
+    content::RenderFrameHost* render_frame_host =
+        content::RenderFrameHost::FromID(render_frame_host_id_);
+    if (render_frame_host && render_frame_host->IsActive()) {
+      render_frame_host->GetRemoteAssociatedInterfaces()->GetInterface(&agent_);
+    }
   }
   return agent_;
 }
diff --git a/components/facilitated_payments/content/browser/content_facilitated_payments_driver.h b/components/facilitated_payments/content/browser/content_facilitated_payments_driver.h
index 5be0180..c0b4e93 100644
--- a/components/facilitated_payments/content/browser/content_facilitated_payments_driver.h
+++ b/components/facilitated_payments/content/browser/content_facilitated_payments_driver.h
@@ -6,8 +6,7 @@
 #define COMPONENTS_FACILITATED_PAYMENTS_CONTENT_BROWSER_CONTENT_FACILITATED_PAYMENTS_DRIVER_H_
 
 #include "components/facilitated_payments/core/browser/facilitated_payments_driver.h"
-
-#include "base/memory/raw_ref.h"
+#include "content/public/browser/global_routing_id.h"
 #include "mojo/public/cpp/bindings/associated_remote.h"
 
 namespace content {
@@ -50,10 +49,8 @@
 
   mojo::AssociatedRemote<mojom::FacilitatedPaymentsAgent> agent_;
 
-  // TODO(b/324987918): Store the `GlobalRenderFrameHostId`, and retrieve the
-  // `RenderFrameHost` when required.
-  // The frame/document to which this driver is associated. Outlives `this`.
-  const raw_ref<content::RenderFrameHost> render_frame_host_;
+  // The ID of the frame to which this driver is associated.
+  const content::GlobalRenderFrameHostId render_frame_host_id_;
 };
 
 }  // namespace payments::facilitated
diff --git a/components/facilitated_payments/content/browser/facilitated_payments_api_client_factory.h b/components/facilitated_payments/content/browser/facilitated_payments_api_client_factory.h
index 79c777bc..5d48e80f 100644
--- a/components/facilitated_payments/content/browser/facilitated_payments_api_client_factory.h
+++ b/components/facilitated_payments/content/browser/facilitated_payments_api_client_factory.h
@@ -5,21 +5,17 @@
 #ifndef COMPONENTS_FACILITATED_PAYMENTS_CONTENT_BROWSER_FACILITATED_PAYMENTS_API_CLIENT_FACTORY_H_
 #define COMPONENTS_FACILITATED_PAYMENTS_CONTENT_BROWSER_FACILITATED_PAYMENTS_API_CLIENT_FACTORY_H_
 
-#include <memory>
-
-namespace content {
-class RenderFrameHost;
-}  // namespace content
+#include "components/facilitated_payments/core/browser/facilitated_payments_api_client.h"
+#include "content/public/browser/global_routing_id.h"
 
 namespace payments::facilitated {
 
-class FacilitatedPaymentsApiClient;
-
-// Creates a platform-specific instance of the API client. This function is
-// defined in platform specific implementation source files, e.g., in
+// Returns a one time use callback that can create a platform-specific instance
+// of the API client. This function is defined in platform specific
+// implementation source files, e.g., in
 // `facilitated_payments_api_client_android.cc`.
-std::unique_ptr<FacilitatedPaymentsApiClient>
-CreateFacilitatedPaymentsApiClient(content::RenderFrameHost* render_frame_host);
+FacilitatedPaymentsApiClientCreator GetFacilitatedPaymentsApiClientCreator(
+    content::GlobalRenderFrameHostId render_frame_host_id);
 
 }  // namespace payments::facilitated
 
diff --git a/components/facilitated_payments/core/browser/facilitated_payments_api_client.h b/components/facilitated_payments/core/browser/facilitated_payments_api_client.h
index 15d95cf..c793b5c 100644
--- a/components/facilitated_payments/core/browser/facilitated_payments_api_client.h
+++ b/components/facilitated_payments/core/browser/facilitated_payments_api_client.h
@@ -75,6 +75,10 @@
       base::OnceCallback<void(PurchaseActionResult)> callback) = 0;
 };
 
+// A one time use factory for the facilitated payment API client.
+using FacilitatedPaymentsApiClientCreator =
+    base::OnceCallback<std::unique_ptr<FacilitatedPaymentsApiClient>()>;
+
 }  // namespace payments::facilitated
 
 #endif  // COMPONENTS_FACILITATED_PAYMENTS_CORE_BROWSER_FACILITATED_PAYMENTS_API_CLIENT_H_
diff --git a/components/facilitated_payments/core/browser/facilitated_payments_manager.cc b/components/facilitated_payments/core/browser/facilitated_payments_manager.cc
index 54332d6..ad1dd9c 100644
--- a/components/facilitated_payments/core/browser/facilitated_payments_manager.cc
+++ b/components/facilitated_payments/core/browser/facilitated_payments_manager.cc
@@ -24,11 +24,11 @@
 FacilitatedPaymentsManager::FacilitatedPaymentsManager(
     FacilitatedPaymentsDriver* driver,
     FacilitatedPaymentsClient* client,
-    std::unique_ptr<FacilitatedPaymentsApiClient> api_client,
+    FacilitatedPaymentsApiClientCreator api_client_creator,
     optimization_guide::OptimizationGuideDecider* optimization_guide_decider)
     : driver_(CHECK_DEREF(driver)),
       client_(CHECK_DEREF(client)),
-      api_client_(std::move(api_client)),
+      api_client_creator_(std::move(api_client_creator)),
       optimization_guide_decider_(optimization_guide_decider),
       initiate_payment_request_details_(
           std::make_unique<
@@ -179,13 +179,28 @@
     return;
   }
 
+  if (!GetApiClient()) {
+    Reset();
+    return;
+  }
+
   initiate_payment_request_details_->pix_code_ = std::move(pix_code);
   api_availability_check_start_time_ = base::TimeTicks::Now();
-  api_client_->IsAvailable(
+  GetApiClient()->IsAvailable(
       base::BindOnce(&FacilitatedPaymentsManager::OnApiAvailabilityReceived,
                      weak_ptr_factory_.GetWeakPtr()));
 }
 
+FacilitatedPaymentsApiClient* FacilitatedPaymentsManager::GetApiClient() {
+  if (!api_client_) {
+    if (api_client_creator_) {
+      api_client_ = std::move(api_client_creator_).Run();
+    }
+  }
+
+  return api_client_.get();
+}
+
 void FacilitatedPaymentsManager::StartPixCodeDetectionLatencyTimer() {
   pix_code_detection_latency_measuring_timestamp_ = base::TimeTicks::Now();
 }
@@ -253,9 +268,10 @@
     Reset();
     return;
   }
+
   initiate_payment_request_details_->instrument_id_ = selected_instrument_id;
   get_client_token_loading_start_time_ = base::TimeTicks::Now();
-  api_client_->GetClientToken(
+  GetApiClient()->GetClientToken(
       base::BindOnce(&FacilitatedPaymentsManager::OnGetClientToken,
                      weak_ptr_factory_.GetWeakPtr()));
 }
@@ -316,7 +332,7 @@
     return;
   }
   purchase_action_start_time_ = base::TimeTicks::Now();
-  api_client_->InvokePurchaseAction(
+  GetApiClient()->InvokePurchaseAction(
       account_info.value(), response_details->action_token_,
       base::BindOnce(&FacilitatedPaymentsManager::OnPurchaseActionResult,
                      weak_ptr_factory_.GetWeakPtr()));
diff --git a/components/facilitated_payments/core/browser/facilitated_payments_manager.h b/components/facilitated_payments/core/browser/facilitated_payments_manager.h
index 4f8ca249..2fec445 100644
--- a/components/facilitated_payments/core/browser/facilitated_payments_manager.h
+++ b/components/facilitated_payments/core/browser/facilitated_payments_manager.h
@@ -9,6 +9,7 @@
 #include <memory>
 #include <vector>
 
+#include "base/functional/callback_forward.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ref.h"
 #include "base/memory/weak_ptr.h"
@@ -40,7 +41,7 @@
   FacilitatedPaymentsManager(
       FacilitatedPaymentsDriver* driver,
       FacilitatedPaymentsClient* client,
-      std::unique_ptr<FacilitatedPaymentsApiClient> api_client,
+      FacilitatedPaymentsApiClientCreator api_client_creator,
       optimization_guide::OptimizationGuideDecider* optimization_guide_decider);
   FacilitatedPaymentsManager(const FacilitatedPaymentsManager&) = delete;
   FacilitatedPaymentsManager& operator=(const FacilitatedPaymentsManager&) =
@@ -190,6 +191,11 @@
                            InvokePurchaseActionCompleted_HistogramLogged);
   FRIEND_TEST_ALL_PREFIXES(FacilitatedPaymentsManagerWithPixPaymentsEnabledTest,
                            OnInitiatePaymentResponseReceived_HistogramLogged);
+  FRIEND_TEST_ALL_PREFIXES(FacilitatedPaymentsManagerWithPixPaymentsEnabledTest,
+                           ApiClientInitializedLazily);
+  FRIEND_TEST_ALL_PREFIXES(FacilitatedPaymentsManagerWithPixPaymentsEnabledTest,
+                           HandlesFailureToLazilyInitializeApiClient);
+
   // Register optimization guide deciders for PIX. It is an allowlist of URLs
   // where we attempt PIX code detection.
   void RegisterPixAllowlist() const;
@@ -220,6 +226,13 @@
   void OnPixCodeValidated(std::string pix_code,
                           base::expected<bool, std::string> is_pix_code_valid);
 
+  // Lazily initializes an API client and returns a pointer to it. Returns a
+  // pointer to the existing API client, if one is already initialized. The
+  // FacilitatedPaymentManager owns this API client. This method can return
+  // `nullptr` if the API client fails to initialize, e.g., if the
+  // `RenderFrameHost` has been destroyed.
+  FacilitatedPaymentsApiClient* GetApiClient();
+
   // Starts `pix_code_detection_latency_measuring_timestamp_`.
   void StartPixCodeDetectionLatencyTimer();
 
@@ -267,6 +280,9 @@
   // Indirect owner.
   const raw_ref<FacilitatedPaymentsClient> client_;
 
+  // The creator of the facilitated payment API client.
+  FacilitatedPaymentsApiClientCreator api_client_creator_;
+
   // The client for the facilitated payment API.
   std::unique_ptr<FacilitatedPaymentsApiClient> api_client_;
 
diff --git a/components/facilitated_payments/core/browser/facilitated_payments_manager_unittest.cc b/components/facilitated_payments/core/browser/facilitated_payments_manager_unittest.cc
index c0ac5066..4a6915c 100644
--- a/components/facilitated_payments/core/browser/facilitated_payments_manager_unittest.cc
+++ b/components/facilitated_payments/core/browser/facilitated_payments_manager_unittest.cc
@@ -76,6 +76,10 @@
 // A mock for the facilitated payment API client interface.
 class MockFacilitatedPaymentsApiClient : public FacilitatedPaymentsApiClient {
  public:
+  static std::unique_ptr<FacilitatedPaymentsApiClient> CreateApiClient() {
+    return std::make_unique<MockFacilitatedPaymentsApiClient>();
+  }
+
   MockFacilitatedPaymentsApiClient() = default;
   ~MockFacilitatedPaymentsApiClient() override = default;
 
@@ -188,15 +192,15 @@
         std::make_unique<MockOptimizationGuideDecider>();
     driver_ = std::make_unique<MockFacilitatedPaymentsDriver>(nullptr);
     client_ = std::make_unique<MockFacilitatedPaymentsClient>();
-    auto api_client = std::make_unique<MockFacilitatedPaymentsApiClient>();
-    api_client_ = api_client.get();
+
     manager_ = std::make_unique<FacilitatedPaymentsManager>(
-        driver_.get(), client_.get(), std::move(api_client),
+        driver_.get(), client_.get(), /*api_client_creator=*/
+        base::BindOnce(&MockFacilitatedPaymentsApiClient::CreateApiClient),
         optimization_guide_decider_.get());
     manager_->is_test_ = true;
 
-    // Using Autofill preferences since we use autofill's infra for syncing bank
-    // accounts.
+    // Using Autofill preferences since we use autofill's infra for syncing
+    // bank accounts.
     pref_service_ = autofill::test::PrefServiceForTesting();
     payments_data_manager_ =
         std::make_unique<autofill::TestPaymentsDataManager>();
@@ -210,7 +214,6 @@
   }
 
   void TearDown() override {
-    api_client_ = nullptr;
     allowlist_decision_timer_.Stop();
     page_load_timer_.Stop();
     payments_data_manager_->ClearAllServerDataForTesting();
@@ -308,6 +311,11 @@
     task_environment_.RunUntilIdle();
   }
 
+  MockFacilitatedPaymentsApiClient& GetApiClient() {
+    return *static_cast<MockFacilitatedPaymentsApiClient*>(
+        manager_->GetApiClient());
+  }
+
  protected:
   base::test::ScopedFeatureList features_;
   optimization_guide::OptimizationGuideDecision allowlist_result_;
@@ -321,9 +329,6 @@
   std::unique_ptr<autofill::TestPaymentsDataManager> payments_data_manager_;
   MockFacilitatedPaymentsNetworkInterface payments_network_interface_;
 
-  // Owned by the `manager_`.
-  raw_ptr<MockFacilitatedPaymentsApiClient> api_client_ = nullptr;
-
  private:
   // Number of attempts at checking the allowlist.
   int check_allowlist_attempt_count_;
@@ -932,7 +937,7 @@
 // retrieve a client token from the facilitated payments API client.
 TEST_F(FacilitatedPaymentsManagerTest,
        DoesNotRetrieveClientTokenIfPixPaymentPromptRejected) {
-  EXPECT_CALL(*api_client_, GetClientToken(testing::_)).Times(0);
+  EXPECT_CALL(GetApiClient(), GetClientToken(testing::_)).Times(0);
 
   manager_->OnPixPaymentPromptResult(/*is_prompt_accepted=*/false,
                                      /*selected_instrument_id=*/-1);
@@ -942,7 +947,7 @@
 // client token from the facilitated payments API client.
 TEST_F(FacilitatedPaymentsManagerTest,
        RetrievesClientTokenIfPixPaymentPromptAccepted) {
-  EXPECT_CALL(*api_client_, GetClientToken(testing::_));
+  EXPECT_CALL(GetApiClient(), GetClientToken(testing::_));
 
   manager_->OnPixPaymentPromptResult(/*is_prompt_accepted=*/true,
                                      /*selected_instrument_id=*/-1);
@@ -954,7 +959,7 @@
 TEST_F(FacilitatedPaymentsManagerTest,
        GetClientTokenHistogram_ClientTokenNotEmpty) {
   base::HistogramTester histogram_tester;
-  EXPECT_CALL(*api_client_, GetClientToken(testing::_));
+  EXPECT_CALL(GetApiClient(), GetClientToken(testing::_));
   manager_->OnPixPaymentPromptResult(/*is_prompt_accepted=*/true,
                                      /*selected_instrument_id=*/-1);
   FastForwardBy(base::Seconds(2));
@@ -977,7 +982,7 @@
 TEST_F(FacilitatedPaymentsManagerTest,
        GetClientTokenHistogram_ClientTokenEmpty) {
   base::HistogramTester histogram_tester;
-  EXPECT_CALL(*api_client_, GetClientToken(testing::_));
+  EXPECT_CALL(GetApiClient(), GetClientToken(testing::_));
   manager_->OnPixPaymentPromptResult(/*is_prompt_accepted=*/true,
                                      /*selected_instrument_id=*/-1);
   FastForwardBy(base::Seconds(2));
@@ -1069,7 +1074,7 @@
        ValidPixCodeDetectionResult_HasPixAccounts_ApiClientNotTriggered) {
   payments_data_manager_->AddMaskedBankAccountForTest(CreatePixBankAccount(1));
 
-  EXPECT_CALL(*api_client_, IsAvailable(testing::_)).Times(0);
+  EXPECT_CALL(GetApiClient(), IsAvailable(testing::_)).Times(0);
 
   manager_->ProcessPixCodeDetectionResult(
       mojom::PixCodeDetectionResult::kValidPixCodeFound, std::string());
@@ -1093,7 +1098,7 @@
        ValidPixCodeDetectionResult_HasPixAccounts_ApiClientTriggered) {
   payments_data_manager_->AddMaskedBankAccountForTest(CreatePixBankAccount(1));
 
-  EXPECT_CALL(*api_client_, IsAvailable(testing::_));
+  EXPECT_CALL(GetApiClient(), IsAvailable(testing::_));
 
   manager_->ProcessPixCodeDetectionResult(
       mojom::PixCodeDetectionResult::kValidPixCodeFound,
@@ -1111,7 +1116,7 @@
        ValidPixCodeDetectionResult_InvalidPixCodeString_ApiClientNotTriggered) {
   payments_data_manager_->AddMaskedBankAccountForTest(CreatePixBankAccount(1));
 
-  EXPECT_CALL(*api_client_, IsAvailable(testing::_)).Times(0);
+  EXPECT_CALL(GetApiClient(), IsAvailable(testing::_)).Times(0);
 
   manager_->ProcessPixCodeDetectionResult(
       mojom::PixCodeDetectionResult::kValidPixCodeFound, std::string());
@@ -1127,7 +1132,7 @@
        InvalidPixCodeDetectionResultDoesNotTriggerApiClient) {
   payments_data_manager_->AddMaskedBankAccountForTest(CreatePixBankAccount(1));
 
-  EXPECT_CALL(*api_client_, IsAvailable(testing::_)).Times(0);
+  EXPECT_CALL(GetApiClient(), IsAvailable(testing::_)).Times(0);
 
   manager_->ProcessPixCodeDetectionResult(
       mojom::PixCodeDetectionResult::kInvalidPixCodeFound, std::string());
@@ -1138,7 +1143,7 @@
        ApiClientTriggeredAfterPixCodeValidation) {
   payments_data_manager_->AddMaskedBankAccountForTest(CreatePixBankAccount(1));
 
-  EXPECT_CALL(*api_client_, IsAvailable(testing::_));
+  EXPECT_CALL(GetApiClient(), IsAvailable(testing::_));
 
   manager_->OnPixCodeValidated(/*pix_code=*/std::string(),
                                /*is_pix_code_valid=*/true);
@@ -1150,7 +1155,7 @@
        PixCodeValidationFailed_NoApiClientTriggered) {
   payments_data_manager_->AddMaskedBankAccountForTest(CreatePixBankAccount(1));
 
-  EXPECT_CALL(*api_client_, IsAvailable(testing::_)).Times(0);
+  EXPECT_CALL(GetApiClient(), IsAvailable(testing::_)).Times(0);
 
   manager_->OnPixCodeValidated(/*pix_code=*/std::string(),
                                /*is_pix_code_valid=*/false);
@@ -1177,7 +1182,7 @@
        PixCodeValidatorTerminatedUnexpectedly_NoApiClientTriggered) {
   payments_data_manager_->AddMaskedBankAccountForTest(CreatePixBankAccount(1));
 
-  EXPECT_CALL(*api_client_, IsAvailable(testing::_)).Times(0);
+  EXPECT_CALL(GetApiClient(), IsAvailable(testing::_)).Times(0);
 
   manager_->OnPixCodeValidated(
       /*pix_code=*/std::string(),
@@ -1210,7 +1215,7 @@
   // Turn off PIX pref.
   autofill::prefs::SetFacilitatedPaymentsPix(pref_service_.get(), false);
 
-  EXPECT_CALL(*api_client_, IsAvailable(testing::_)).Times(0);
+  EXPECT_CALL(GetApiClient(), IsAvailable(testing::_)).Times(0);
 
   manager_->OnPixCodeValidated(/*pix_code=*/std::string(),
                                /*is_pix_code_valid=*/true);
@@ -1220,7 +1225,7 @@
 // whether the facilitated payment API is available.
 TEST_F(FacilitatedPaymentsManagerWithPixPaymentsEnabledTest,
        NoPixAccounts_NoApiClientTriggered) {
-  EXPECT_CALL(*api_client_, IsAvailable(testing::_)).Times(0);
+  EXPECT_CALL(GetApiClient(), IsAvailable(testing::_)).Times(0);
 
   manager_->OnPixCodeValidated(/*pix_code=*/std::string(),
                                /*is_pix_code_valid=*/true);
@@ -1234,7 +1239,7 @@
   ON_CALL(*client_, GetPaymentsDataManager)
       .WillByDefault(testing::Return(nullptr));
 
-  EXPECT_CALL(*api_client_, IsAvailable(testing::_)).Times(0);
+  EXPECT_CALL(GetApiClient(), IsAvailable(testing::_)).Times(0);
 
   manager_->OnPixCodeValidated(/*pix_code=*/std::string(),
                                /*is_pix_code_valid=*/true);
@@ -1251,7 +1256,7 @@
       CreatePixBankAccount(/*instrument_id=*/2);
   payments_data_manager_->AddMaskedBankAccountForTest(pix_account1);
   payments_data_manager_->AddMaskedBankAccountForTest(pix_account2);
-  ON_CALL(*api_client_, IsAvailable)
+  ON_CALL(GetApiClient(), IsAvailable)
       .WillByDefault([](base::OnceCallback<void(bool)> callback) {
         std::move(callback).Run(true);
       });
@@ -1287,7 +1292,7 @@
   ON_CALL(*client_, GetCoreAccountInfo)
       .WillByDefault(testing::Return(CreateLoggedInAccountInfo()));
 
-  EXPECT_CALL(*api_client_, InvokePurchaseAction).Times(0);
+  EXPECT_CALL(GetApiClient(), InvokePurchaseAction).Times(0);
 
   auto response_details =
       std::make_unique<FacilitatedPaymentsInitiatePaymentResponseDetails>();
@@ -1306,7 +1311,7 @@
   ON_CALL(*client_, GetCoreAccountInfo)
       .WillByDefault(testing::Return(CreateLoggedInAccountInfo()));
 
-  EXPECT_CALL(*api_client_, InvokePurchaseAction).Times(0);
+  EXPECT_CALL(GetApiClient(), InvokePurchaseAction).Times(0);
 
   auto response_details =
       std::make_unique<FacilitatedPaymentsInitiatePaymentResponseDetails>();
@@ -1322,7 +1327,7 @@
   ON_CALL(*client_, GetCoreAccountInfo)
       .WillByDefault(testing::Return(std::nullopt));
 
-  EXPECT_CALL(*api_client_, InvokePurchaseAction).Times(0);
+  EXPECT_CALL(GetApiClient(), InvokePurchaseAction).Times(0);
 
   auto response_details =
       std::make_unique<FacilitatedPaymentsInitiatePaymentResponseDetails>();
@@ -1339,7 +1344,7 @@
   ON_CALL(*client_, GetCoreAccountInfo)
       .WillByDefault(testing::Return(CoreAccountInfo()));
 
-  EXPECT_CALL(*api_client_, InvokePurchaseAction).Times(0);
+  EXPECT_CALL(GetApiClient(), InvokePurchaseAction).Times(0);
 
   auto response_details =
       std::make_unique<FacilitatedPaymentsInitiatePaymentResponseDetails>();
@@ -1357,7 +1362,7 @@
   ON_CALL(*client_, GetCoreAccountInfo)
       .WillByDefault(testing::Return(CreateLoggedInAccountInfo()));
 
-  EXPECT_CALL(*api_client_, InvokePurchaseAction);
+  EXPECT_CALL(GetApiClient(), InvokePurchaseAction);
 
   auto response_details =
       std::make_unique<FacilitatedPaymentsInitiatePaymentResponseDetails>();
@@ -1375,7 +1380,7 @@
        ApiAvailabilityHistogram) {
   base::HistogramTester histogram_tester;
   payments_data_manager_->AddMaskedBankAccountForTest(CreatePixBankAccount(1));
-  EXPECT_CALL(*api_client_, IsAvailable(testing::_));
+  EXPECT_CALL(GetApiClient(), IsAvailable(testing::_));
   manager_->OnPixCodeValidated(/*pix_code=*/std::string(),
                                /*is_pix_code_valid=*/true);
   FastForwardBy(base::Seconds(2));
@@ -1414,7 +1419,7 @@
   base::HistogramTester histogram_tester;
   ON_CALL(*client_, GetCoreAccountInfo)
       .WillByDefault(testing::Return(CreateLoggedInAccountInfo()));
-  EXPECT_CALL(*api_client_, InvokePurchaseAction);
+  EXPECT_CALL(GetApiClient(), InvokePurchaseAction);
   auto response_details =
       std::make_unique<FacilitatedPaymentsInitiatePaymentResponseDetails>();
   response_details->action_token_ =
@@ -1463,4 +1468,32 @@
       /*expected_bucket_count=*/1);
 }
 
+// Verify that the API client is initialized lazily, so it does not take up
+// space in memory unless it's being used.
+TEST_F(FacilitatedPaymentsManagerWithPixPaymentsEnabledTest,
+       ApiClientInitializedLazily) {
+  payments_data_manager_->AddMaskedBankAccountForTest(CreatePixBankAccount(1));
+
+  EXPECT_EQ(nullptr, manager_->api_client_.get());
+
+  manager_->OnPixCodeValidated(/*pix_code=*/std::string(),
+                               /*is_pix_code_valid=*/true);
+
+  EXPECT_NE(nullptr, manager_->api_client_.get());
+}
+
+// Verify that a failure to lazily initialize the API client is not fatal.
+TEST_F(FacilitatedPaymentsManagerWithPixPaymentsEnabledTest,
+       HandlesFailureToLazilyInitializeApiClient) {
+  payments_data_manager_->AddMaskedBankAccountForTest(CreatePixBankAccount(1));
+  manager_->api_client_creator_.Reset();
+
+  EXPECT_EQ(nullptr, manager_->api_client_.get());
+
+  manager_->OnPixCodeValidated(/*pix_code=*/std::string(),
+                               /*is_pix_code_valid=*/true);
+
+  EXPECT_EQ(nullptr, manager_->api_client_.get());
+}
+
 }  // namespace payments::facilitated
diff --git a/components/flags_ui/flags_state.h b/components/flags_ui/flags_state.h
index 1987a86..b58adaf4 100644
--- a/components/flags_ui/flags_state.h
+++ b/components/flags_ui/flags_state.h
@@ -17,6 +17,7 @@
 #include "base/feature_list.h"
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_span.h"
 #include "base/values.h"
 
 namespace flags_ui {
@@ -274,7 +275,7 @@
                           const std::string& name,
                           int platform_mask) const;
 
-  const base::span<const FeatureEntry> feature_entries_;
+  const base::raw_span<const FeatureEntry> feature_entries_;
 
   bool needs_restart_;
   std::map<std::string, std::string> flags_switches_;
diff --git a/components/history_embeddings/vector_database.cc b/components/history_embeddings/vector_database.cc
index 26df0b7d..d1fa8ee 100644
--- a/components/history_embeddings/vector_database.cc
+++ b/components/history_embeddings/vector_database.cc
@@ -191,7 +191,7 @@
     search_info.searched_embedding_count += item->embeddings.size();
 
     base::ElapsedTimer scoring_timer;
-    while (q.size() > count) {
+    while (q.size() >= count) {
       q.pop();
     }
     const auto [score, score_index] =
diff --git a/components/input/BUILD.gn b/components/input/BUILD.gn
index bea4568c..23b2b7a6 100644
--- a/components/input/BUILD.gn
+++ b/components/input/BUILD.gn
@@ -35,6 +35,7 @@
     "native_web_keyboard_event.h",
     "passthrough_touch_event_queue.cc",
     "passthrough_touch_event_queue.h",
+    "peak_gpu_memory_tracker.h",
     "switches.cc",
     "switches.h",
     "tap_suppression_controller.cc",
diff --git a/components/input/peak_gpu_memory_tracker.h b/components/input/peak_gpu_memory_tracker.h
new file mode 100644
index 0000000..735bb7e
--- /dev/null
+++ b/components/input/peak_gpu_memory_tracker.h
@@ -0,0 +1,42 @@
+// Copyright 2019 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_INPUT_PEAK_GPU_MEMORY_TRACKER_H_
+#define COMPONENTS_INPUT_PEAK_GPU_MEMORY_TRACKER_H_
+
+#include "base/component_export.h"
+
+namespace input {
+
+// Tracks the peak memory of the GPU service for its lifetime. Upon its
+// destruction a report will be requested from the GPU service. The peak will be
+// reported to UMA Histograms.
+//
+// If the GPU is lost during this objects lifetime, there will be no
+// corresponding report of usage. The same for if there is never a successful
+// GPU connection.
+//
+// See `content::PeakGpuMemoryTrackerFactory::Create` for creation of
+// PeakGpuMemoryTracker in the browser process.
+
+class COMPONENT_EXPORT(INPUT) PeakGpuMemoryTracker {
+ public:
+  // The type of user interaction, for which the GPU Peak Memory Usage is being
+  // observed.
+  enum class Usage {
+    CHANGE_TAB,
+    PAGE_LOAD,
+    SCROLL,
+    USAGE_MAX = SCROLL,
+  };
+
+  virtual ~PeakGpuMemoryTracker() = default;
+
+  // Invalidates this tracker, no UMA Histogram report is generated.
+  virtual void Cancel() = 0;
+};
+
+}  // namespace input
+
+#endif  // COMPONENTS_INPUT_PEAK_GPU_MEMORY_TRACKER_H_
diff --git a/components/ip_protection/BUILD.gn b/components/ip_protection/BUILD.gn
index 4aa97b7..c57974d 100644
--- a/components/ip_protection/BUILD.gn
+++ b/components/ip_protection/BUILD.gn
@@ -28,9 +28,10 @@
     "//net/third_party/quiche:blind_sign_auth",
     "//services/network/public/cpp:cpp",
     "//services/network/public/mojom:mojom",
-    "//third_party/anonymous_tokens:anonymous_tokens_cc_proto",
   ]
 
+  public_deps = [ "//third_party/anonymous_tokens:anonymous_tokens_cc_proto" ]
+
   if (is_android) {
     deps += [
       "//components/ip_protection/android_auth_client_lib/cpp:jni_headers",
@@ -58,7 +59,6 @@
     "//services/network:test_support",
     "//services/network/public/cpp:cpp",
     "//testing/gtest",
-    "//third_party/anonymous_tokens:anonymous_tokens_cc_proto",
   ]
 
   if (is_android) {
diff --git a/components/ip_protection/android_auth_client_lib/cpp/ip_protection_auth_test_natives.cc b/components/ip_protection/android_auth_client_lib/cpp/ip_protection_auth_test_natives.cc
index e4abcd5d..c38a997 100644
--- a/components/ip_protection/android_auth_client_lib/cpp/ip_protection_auth_test_natives.cc
+++ b/components/ip_protection/android_auth_client_lib/cpp/ip_protection_auth_test_natives.cc
@@ -44,6 +44,109 @@
     "org.chromium.components.ip_protection_auth.mock_service."
     "ConstantResponseService$SynchronousError";
 
+// Perform an IpProtectionAuthClient::CreateConnectedInstanceForTesting call in
+// a RunLoop, quitting the RunLoop when either a client is ready or an error
+// occurs. Returns the resulting base::expected value.
+//
+// A task environment must already be set up.
+//
+// Beware that this only wraps the _creation_ of an IpProtectionAuthClient in a
+// RunLoop and not its destruction! If any tasks need to be run as part of
+// client destruction, such as handling unresolved getInitialData/authAndSign
+// callbacks, this is the responsibility of the caller (or client owner).
+base::expected<
+    std::unique_ptr<ip_protection::android::IpProtectionAuthClientInterface>,
+    std::string>
+CreateClientBlocking(const std::string_view mockClassName) {
+  base::expected<
+      std::unique_ptr<ip_protection::android::IpProtectionAuthClientInterface>,
+      std::string>
+      result;
+  base::RunLoop run_loop;
+  ip_protection::android::IpProtectionAuthClient::
+      CreateConnectedInstanceForTesting(
+          kMockPackageName, mockClassName,
+          base::BindPostTask(
+              base::SequencedTaskRunner::GetCurrentDefault(),
+              base::BindLambdaForTesting(
+                  [&run_loop, &result](
+                      base::expected<
+                          std::unique_ptr<ip_protection::android::
+                                              IpProtectionAuthClientInterface>,
+                          std::string> maybe_client) {
+                    result = std::move(maybe_client);
+                    run_loop.Quit();
+                  })));
+  run_loop.Run();
+  return result;
+}
+
+// Same as CreateClientBlocking, but asserts that a client is acquired and
+// returns the unwrapped client from the base::expected.
+//
+// A task environment must already be set up.
+std::unique_ptr<ip_protection::android::IpProtectionAuthClientInterface>
+CreateAndExpectClientBlocking(const std::string_view mockClassName) {
+  base::expected<
+      std::unique_ptr<ip_protection::android::IpProtectionAuthClientInterface>,
+      std::string>
+      client = CreateClientBlocking(mockClassName);
+  CHECK(client.has_value()) << client.error();
+  return std::move(*client);
+}
+
+// Perform an getInitialData request in a RunLoop, quitting the RunLoop when a
+// response is received and returning the base::expected result.
+//
+// A task environment must already be set up.
+base::expected<privacy::ppn::GetInitialDataResponse,
+               ip_protection::android::AuthRequestError>
+GetInitialDataBlocking(
+    ip_protection::android::IpProtectionAuthClientInterface& client,
+    privacy::ppn::GetInitialDataRequest request) {
+  base::expected<privacy::ppn::GetInitialDataResponse,
+                 ip_protection::android::AuthRequestError>
+      result;
+  base::RunLoop run_loop;
+  client.GetInitialData(
+      std::move(request),
+      base::BindLambdaForTesting(
+          [&run_loop,
+           &result](base::expected<privacy::ppn::GetInitialDataResponse,
+                                   ip_protection::android::AuthRequestError>
+                        response) {
+            result = std::move(response);
+            run_loop.Quit();
+          }));
+  run_loop.Run();
+  return result;
+}
+
+// Perform an authAndSign request in a RunLoop, quitting the RunLoop when a
+// response is received and returning the base::expected result.
+base::expected<privacy::ppn::AuthAndSignResponse,
+               ip_protection::android::AuthRequestError>
+AuthAndSignBlocking(
+    ip_protection::android::IpProtectionAuthClientInterface& client,
+    privacy::ppn::AuthAndSignRequest request) {
+  base::expected<privacy::ppn::AuthAndSignResponse,
+                 ip_protection::android::AuthRequestError>
+      result;
+  base::RunLoop run_loop;
+  client.AuthAndSign(
+      std::move(request),
+      base::BindLambdaForTesting(
+          [&run_loop,
+           &result](base::expected<privacy::ppn::AuthAndSignResponse,
+                                   ip_protection::android::AuthRequestError>
+                        response) {
+            result = std::move(response);
+            run_loop.Quit();
+          }));
+  run_loop.Run();
+  return result;
+}
+
 }  // namespace
 
 static void JNI_IpProtectionAuthTestNatives_Initialize(JNIEnv* env) {
@@ -56,397 +159,176 @@
 static void JNI_IpProtectionAuthTestNatives_CreateConnectedInstanceForTesting(
     JNIEnv* env) {
   base::test::SingleThreadTaskEnvironment task_environment;
-  base::RunLoop run_loop;
 
-  ip_protection::android::IpProtectionAuthClient::
-      CreateConnectedInstanceForTesting(
-          kMockPackageName, kMockClassNameForDefault,
-          base::BindPostTask(
-              base::SequencedTaskRunner::GetCurrentDefault(),
-              base::BindLambdaForTesting(
-                  [&run_loop](
-                      base::expected<
-                          std::unique_ptr<ip_protection::android::
-                                              IpProtectionAuthClientInterface>,
-                          std::string> response) {
-                    CHECK(response.has_value()) << response.error();
-                    run_loop.Quit();
-                  })));
-  run_loop.Run();
+  CreateAndExpectClientBlocking(kMockClassNameForDefault);
 }
 
 static void JNI_IpProtectionAuthTestNatives_TestGetInitialData(JNIEnv* env) {
   base::test::SingleThreadTaskEnvironment task_environment;
-  base::RunLoop run_loop;
+  std::unique_ptr<ip_protection::android::IpProtectionAuthClientInterface>
+      client = CreateAndExpectClientBlocking(kMockClassNameForDefault);
+  privacy::ppn::GetInitialDataRequest get_initial_data_request;
+  get_initial_data_request.set_service_type("webviewipblinding");
 
-  ip_protection::android::IpProtectionAuthClient::
-      CreateConnectedInstanceForTesting(
-          kMockPackageName, kMockClassNameForDefault,
-          base::BindPostTask(
-              base::SequencedTaskRunner::GetCurrentDefault(),
-              base::BindLambdaForTesting(
-                  [&run_loop](
-                      base::expected<
-                          std::unique_ptr<ip_protection::android::
-                                              IpProtectionAuthClientInterface>,
-                          std::string> response) {
-                    CHECK(response.has_value()) << response.error();
-                    privacy::ppn::GetInitialDataRequest request;
-                    request.set_service_type("webviewipblinding");
-                    (*response)->GetInitialData(
-                        request,
-                        base::BindLambdaForTesting(
-                            [&run_loop](
-                                base::expected<
-                                    privacy::ppn::GetInitialDataResponse,
-                                    ip_protection::android::AuthRequestError>
-                                    initial_data_response) {
-                              CHECK(initial_data_response.has_value());
-                              CHECK(initial_data_response->privacy_pass_data()
-                                        .token_key_id() == "test")
-                                  << "expected \"test\" for token_key_id, got: "
-                                  << initial_data_response->privacy_pass_data()
-                                         .token_key_id();
-                              run_loop.Quit();
-                            }));
-                  })));
-  run_loop.Run();
+  base::expected<privacy::ppn::GetInitialDataResponse,
+                 ip_protection::android::AuthRequestError>
+      get_initial_data_response =
+          GetInitialDataBlocking(*client, get_initial_data_request);
+
+  CHECK(get_initial_data_response.has_value());
+  CHECK(get_initial_data_response->privacy_pass_data().token_key_id() == "test")
+      << "expected \"test\" for token_key_id, got: "
+      << get_initial_data_response->privacy_pass_data().token_key_id();
 }
 
 static void JNI_IpProtectionAuthTestNatives_TestAuthAndSign(JNIEnv* env) {
   base::test::SingleThreadTaskEnvironment task_environment;
-  base::RunLoop run_loop;
+  std::unique_ptr<ip_protection::android::IpProtectionAuthClientInterface>
+      client = CreateAndExpectClientBlocking(kMockClassNameForDefault);
+  privacy::ppn::AuthAndSignRequest auth_and_sign_request;
+  auth_and_sign_request.set_oauth_token("test");
 
-  ip_protection::android::IpProtectionAuthClient::
-      CreateConnectedInstanceForTesting(
-          kMockPackageName, kMockClassNameForDefault,
-          base::BindPostTask(
-              base::SequencedTaskRunner::GetCurrentDefault(),
-              base::BindLambdaForTesting(
-                  [&run_loop](
-                      base::expected<
-                          std::unique_ptr<ip_protection::android::
-                                              IpProtectionAuthClientInterface>,
-                          std::string> response) {
-                    CHECK(response.has_value()) << response.error();
-                    privacy::ppn::AuthAndSignRequest request;
-                    request.set_oauth_token("test");
-                    (*response)->AuthAndSign(
-                        request,
-                        base::BindLambdaForTesting(
-                            [&run_loop](
-                                base::expected<
-                                    privacy::ppn::AuthAndSignResponse,
-                                    ip_protection::android::AuthRequestError>
-                                    auth_and_sign_response) {
-                              CHECK(auth_and_sign_response.has_value());
-                              CHECK(auth_and_sign_response->apn_type() ==
-                                    "test")
-                                  << "expected \"test\" for apn_type, got: "
-                                  << auth_and_sign_response->apn_type();
-                              run_loop.Quit();
-                            }));
-                  })));
-  run_loop.Run();
+  base::expected<privacy::ppn::AuthAndSignResponse,
+                 ip_protection::android::AuthRequestError>
+      auth_and_sign_response =
+          AuthAndSignBlocking(*client, auth_and_sign_request);
+
+  CHECK(auth_and_sign_response.has_value());
+  CHECK(auth_and_sign_response->apn_type() == "test")
+      << "expected \"test\" for apn_type, got: "
+      << auth_and_sign_response->apn_type();
 }
 
 static void JNI_IpProtectionAuthTestNatives_TestTransientError(JNIEnv* env) {
   base::test::SingleThreadTaskEnvironment task_environment;
-  base::RunLoop run_loop;
+  std::unique_ptr<ip_protection::android::IpProtectionAuthClientInterface>
+      client = CreateAndExpectClientBlocking(kMockClassNameForTransientError);
 
-  ip_protection::android::IpProtectionAuthClient::
-      CreateConnectedInstanceForTesting(
-          kMockPackageName, kMockClassNameForTransientError,
-          base::BindPostTask(
-              base::SequencedTaskRunner::GetCurrentDefault(),
-              base::BindLambdaForTesting(
-                  [&run_loop](
-                      base::expected<
-                          std::unique_ptr<ip_protection::android::
-                                              IpProtectionAuthClientInterface>,
-                          std::string> response) {
-                    CHECK(response.has_value()) << response.error();
+  base::expected<privacy::ppn::GetInitialDataResponse,
+                 ip_protection::android::AuthRequestError>
+      get_initial_data_response = GetInitialDataBlocking(
+          *client, privacy::ppn::GetInitialDataRequest());
+  base::expected<privacy::ppn::AuthAndSignResponse,
+                 ip_protection::android::AuthRequestError>
+      auth_and_sign_response =
+          AuthAndSignBlocking(*client, privacy::ppn::AuthAndSignRequest());
 
-                    (*response)->GetInitialData(
-                        privacy::ppn::GetInitialDataRequest(),
-                        base::BindLambdaForTesting(
-                            [&run_loop](
-                                base::expected<
-                                    privacy::ppn::GetInitialDataResponse,
-                                    ip_protection::android::AuthRequestError>
-                                    initial_data_response) {
-                              CHECK(!initial_data_response.has_value());
-                              CHECK(initial_data_response.error() ==
-                                    ip_protection::android::AuthRequestError::
-                                        kTransient);
-                              run_loop.Quit();
-                            }));
-
-                    (*response)->AuthAndSign(
-                        privacy::ppn::AuthAndSignRequest(),
-                        base::BindLambdaForTesting(
-                            [&run_loop](
-                                base::expected<
-                                    privacy::ppn::AuthAndSignResponse,
-                                    ip_protection::android::AuthRequestError>
-                                    auth_and_sign_response) {
-                              CHECK(!auth_and_sign_response.has_value());
-                              CHECK(auth_and_sign_response.error() ==
-                                    ip_protection::android::AuthRequestError::
-                                        kTransient);
-                              run_loop.Quit();
-                            }));
-                  })));
-  run_loop.Run();
+  CHECK(!get_initial_data_response.has_value());
+  CHECK(get_initial_data_response.error() ==
+        ip_protection::android::AuthRequestError::kTransient);
+  CHECK(!auth_and_sign_response.has_value());
+  CHECK(auth_and_sign_response.error() ==
+        ip_protection::android::AuthRequestError::kTransient);
 }
 
 static void JNI_IpProtectionAuthTestNatives_TestPersistentError(JNIEnv* env) {
   base::test::SingleThreadTaskEnvironment task_environment;
-  base::RunLoop run_loop;
+  std::unique_ptr<ip_protection::android::IpProtectionAuthClientInterface>
+      client = CreateAndExpectClientBlocking(kMockClassNameForPersistentError);
 
-  ip_protection::android::IpProtectionAuthClient::
-      CreateConnectedInstanceForTesting(
-          kMockPackageName, kMockClassNameForPersistentError,
-          base::BindPostTask(
-              base::SequencedTaskRunner::GetCurrentDefault(),
-              base::BindLambdaForTesting(
-                  [&run_loop](
-                      base::expected<
-                          std::unique_ptr<ip_protection::android::
-                                              IpProtectionAuthClientInterface>,
-                          std::string> response) {
-                    CHECK(response.has_value()) << response.error();
+  base::expected<privacy::ppn::GetInitialDataResponse,
+                 ip_protection::android::AuthRequestError>
+      get_initial_data_response = GetInitialDataBlocking(
+          *client, privacy::ppn::GetInitialDataRequest());
+  base::expected<privacy::ppn::AuthAndSignResponse,
+                 ip_protection::android::AuthRequestError>
+      auth_and_sign_response =
+          AuthAndSignBlocking(*client, privacy::ppn::AuthAndSignRequest());
 
-                    (*response)->GetInitialData(
-                        privacy::ppn::GetInitialDataRequest(),
-                        base::BindLambdaForTesting(
-                            [&run_loop](
-                                base::expected<
-                                    privacy::ppn::GetInitialDataResponse,
-                                    ip_protection::android::AuthRequestError>
-                                    initial_data_response) {
-                              CHECK(!initial_data_response.has_value());
-                              CHECK(initial_data_response.error() ==
-                                    ip_protection::android::AuthRequestError::
-                                        kPersistent);
-                              run_loop.Quit();
-                            }));
-
-                    (*response)->AuthAndSign(
-                        privacy::ppn::AuthAndSignRequest(),
-                        base::BindLambdaForTesting(
-                            [&run_loop](
-                                base::expected<
-                                    privacy::ppn::AuthAndSignResponse,
-                                    ip_protection::android::AuthRequestError>
-                                    auth_and_sign_response) {
-                              CHECK(!auth_and_sign_response.has_value());
-                              CHECK(auth_and_sign_response.error() ==
-                                    ip_protection::android::AuthRequestError::
-                                        kPersistent);
-                              run_loop.Quit();
-                            }));
-                  })));
-  run_loop.Run();
+  CHECK(!get_initial_data_response.has_value());
+  CHECK(get_initial_data_response.error() ==
+        ip_protection::android::AuthRequestError::kPersistent);
+  CHECK(!auth_and_sign_response.has_value());
+  CHECK(auth_and_sign_response.error() ==
+        ip_protection::android::AuthRequestError::kPersistent);
 }
 
 static void JNI_IpProtectionAuthTestNatives_TestIllegalErrorCode(JNIEnv* env) {
   base::test::SingleThreadTaskEnvironment task_environment;
-  base::RunLoop run_loop;
+  std::unique_ptr<ip_protection::android::IpProtectionAuthClientInterface>
+      client = CreateAndExpectClientBlocking(kMockClassNameForIllegalErrorCode);
 
-  ip_protection::android::IpProtectionAuthClient::
-      CreateConnectedInstanceForTesting(
-          kMockPackageName, kMockClassNameForIllegalErrorCode,
-          base::BindPostTask(
-              base::SequencedTaskRunner::GetCurrentDefault(),
-              base::BindLambdaForTesting(
-                  [&run_loop](
-                      base::expected<
-                          std::unique_ptr<ip_protection::android::
-                                              IpProtectionAuthClientInterface>,
-                          std::string> client) {
-                    CHECK(client.has_value()) << client.error();
+  base::expected<privacy::ppn::GetInitialDataResponse,
+                 ip_protection::android::AuthRequestError>
+      get_initial_data_response = GetInitialDataBlocking(
+          *client, privacy::ppn::GetInitialDataRequest());
+  base::expected<privacy::ppn::AuthAndSignResponse,
+                 ip_protection::android::AuthRequestError>
+      auth_and_sign_response =
+          AuthAndSignBlocking(*client, privacy::ppn::AuthAndSignRequest());
 
-                    (*client)->GetInitialData(
-                        privacy::ppn::GetInitialDataRequest(),
-                        base::BindLambdaForTesting(
-                            [&run_loop](
-                                base::expected<
-                                    privacy::ppn::GetInitialDataResponse,
-                                    ip_protection::android::AuthRequestError>
-                                    initial_data_response) {
-                              CHECK(!initial_data_response.has_value());
-                              CHECK(initial_data_response.error() ==
-                                    ip_protection::android::AuthRequestError::
-                                        kOther);
-                              run_loop.Quit();
-                            }));
-
-                    (*client)->AuthAndSign(
-                        privacy::ppn::AuthAndSignRequest(),
-                        base::BindLambdaForTesting(
-                            [&run_loop](
-                                base::expected<
-                                    privacy::ppn::AuthAndSignResponse,
-                                    ip_protection::android::AuthRequestError>
-                                    auth_and_sign_response) {
-                              CHECK(!auth_and_sign_response.has_value());
-                              CHECK(auth_and_sign_response.error() ==
-                                    ip_protection::android::AuthRequestError::
-                                        kOther);
-                              run_loop.Quit();
-                            }));
-                  })));
-  run_loop.Run();
+  CHECK(!get_initial_data_response.has_value());
+  CHECK(get_initial_data_response.error() ==
+        ip_protection::android::AuthRequestError::kOther);
+  CHECK(!auth_and_sign_response.has_value());
+  CHECK(auth_and_sign_response.error() ==
+        ip_protection::android::AuthRequestError::kOther);
 }
 
 static void JNI_IpProtectionAuthTestNatives_TestNullResponse(JNIEnv* env) {
   base::test::SingleThreadTaskEnvironment task_environment;
-  base::RunLoop run_loop;
+  std::unique_ptr<ip_protection::android::IpProtectionAuthClientInterface>
+      client = CreateAndExpectClientBlocking(kMockClassNameForNullResponse);
 
-  ip_protection::android::IpProtectionAuthClient::
-      CreateConnectedInstanceForTesting(
-          kMockPackageName, kMockClassNameForNullResponse,
-          base::BindPostTask(
-              base::SequencedTaskRunner::GetCurrentDefault(),
-              base::BindLambdaForTesting(
-                  [&run_loop](
-                      base::expected<
-                          std::unique_ptr<ip_protection::android::
-                                              IpProtectionAuthClientInterface>,
-                          std::string> client) {
-                    CHECK(client.has_value()) << client.error();
+  base::expected<privacy::ppn::GetInitialDataResponse,
+                 ip_protection::android::AuthRequestError>
+      get_initial_data_response = GetInitialDataBlocking(
+          *client, privacy::ppn::GetInitialDataRequest());
+  base::expected<privacy::ppn::AuthAndSignResponse,
+                 ip_protection::android::AuthRequestError>
+      auth_and_sign_response =
+          AuthAndSignBlocking(*client, privacy::ppn::AuthAndSignRequest());
 
-                    (*client)->GetInitialData(
-                        privacy::ppn::GetInitialDataRequest(),
-                        base::BindLambdaForTesting(
-                            [&run_loop](
-                                base::expected<
-                                    privacy::ppn::GetInitialDataResponse,
-                                    ip_protection::android::AuthRequestError>
-                                    initial_data_response) {
-                              CHECK(!initial_data_response.has_value());
-                              CHECK(initial_data_response.error() ==
-                                    ip_protection::android::AuthRequestError::
-                                        kOther);
-                              run_loop.Quit();
-                            }));
-
-                    (*client)->AuthAndSign(
-                        privacy::ppn::AuthAndSignRequest(),
-                        base::BindLambdaForTesting(
-                            [&run_loop](
-                                base::expected<
-                                    privacy::ppn::AuthAndSignResponse,
-                                    ip_protection::android::AuthRequestError>
-                                    auth_and_sign_response) {
-                              CHECK(!auth_and_sign_response.has_value());
-                              CHECK(auth_and_sign_response.error() ==
-                                    ip_protection::android::AuthRequestError::
-                                        kOther);
-                              run_loop.Quit();
-                            }));
-                  })));
-  run_loop.Run();
+  CHECK(!get_initial_data_response.has_value());
+  CHECK(get_initial_data_response.error() ==
+        ip_protection::android::AuthRequestError::kOther);
+  CHECK(!auth_and_sign_response.has_value());
+  CHECK(auth_and_sign_response.error() ==
+        ip_protection::android::AuthRequestError::kOther);
 }
 
 static void JNI_IpProtectionAuthTestNatives_TestUnparsableResponse(
     JNIEnv* env) {
   base::test::SingleThreadTaskEnvironment task_environment;
-  base::RunLoop run_loop;
+  std::unique_ptr<ip_protection::android::IpProtectionAuthClientInterface>
+      client =
+          CreateAndExpectClientBlocking(kMockClassNameForUnparsableResponse);
 
-  ip_protection::android::IpProtectionAuthClient::
-      CreateConnectedInstanceForTesting(
-          kMockPackageName, kMockClassNameForUnparsableResponse,
-          base::BindPostTask(
-              base::SequencedTaskRunner::GetCurrentDefault(),
-              base::BindLambdaForTesting(
-                  [&run_loop](
-                      base::expected<
-                          std::unique_ptr<ip_protection::android::
-                                              IpProtectionAuthClientInterface>,
-                          std::string> client) {
-                    CHECK(client.has_value()) << client.error();
+  base::expected<privacy::ppn::GetInitialDataResponse,
+                 ip_protection::android::AuthRequestError>
+      get_initial_data_response = GetInitialDataBlocking(
+          *client, privacy::ppn::GetInitialDataRequest());
+  base::expected<privacy::ppn::AuthAndSignResponse,
+                 ip_protection::android::AuthRequestError>
+      auth_and_sign_response =
+          AuthAndSignBlocking(*client, privacy::ppn::AuthAndSignRequest());
 
-                    (*client)->GetInitialData(
-                        privacy::ppn::GetInitialDataRequest(),
-                        base::BindLambdaForTesting(
-                            [&run_loop](
-                                base::expected<
-                                    privacy::ppn::GetInitialDataResponse,
-                                    ip_protection::android::AuthRequestError>
-                                    initial_data_response) {
-                              CHECK(!initial_data_response.has_value());
-                              CHECK(initial_data_response.error() ==
-                                    ip_protection::android::AuthRequestError::
-                                        kOther);
-                              run_loop.Quit();
-                            }));
-
-                    (*client)->AuthAndSign(
-                        privacy::ppn::AuthAndSignRequest(),
-                        base::BindLambdaForTesting(
-                            [&run_loop](
-                                base::expected<
-                                    privacy::ppn::AuthAndSignResponse,
-                                    ip_protection::android::AuthRequestError>
-                                    auth_and_sign_response) {
-                              CHECK(!auth_and_sign_response.has_value());
-                              CHECK(auth_and_sign_response.error() ==
-                                    ip_protection::android::AuthRequestError::
-                                        kOther);
-                              run_loop.Quit();
-                            }));
-                  })));
-  run_loop.Run();
+  CHECK(!get_initial_data_response.has_value());
+  CHECK(get_initial_data_response.error() ==
+        ip_protection::android::AuthRequestError::kOther);
+  CHECK(!auth_and_sign_response.has_value());
+  CHECK(auth_and_sign_response.error() ==
+        ip_protection::android::AuthRequestError::kOther);
 }
 
 static void JNI_IpProtectionAuthTestNatives_TestSynchronousError(JNIEnv* env) {
   base::test::SingleThreadTaskEnvironment task_environment;
-  base::RunLoop run_loop;
+  std::unique_ptr<ip_protection::android::IpProtectionAuthClientInterface>
+      client = CreateAndExpectClientBlocking(kMockClassNameForSynchronousError);
 
-  ip_protection::android::IpProtectionAuthClient::
-      CreateConnectedInstanceForTesting(
-          kMockPackageName, kMockClassNameForSynchronousError,
-          base::BindPostTask(
-              base::SequencedTaskRunner::GetCurrentDefault(),
-              base::BindLambdaForTesting(
-                  [&run_loop](
-                      base::expected<
-                          std::unique_ptr<ip_protection::android::
-                                              IpProtectionAuthClientInterface>,
-                          std::string> client) {
-                    CHECK(client.has_value()) << client.error();
+  base::expected<privacy::ppn::GetInitialDataResponse,
+                 ip_protection::android::AuthRequestError>
+      get_initial_data_response = GetInitialDataBlocking(
+          *client, privacy::ppn::GetInitialDataRequest());
+  base::expected<privacy::ppn::AuthAndSignResponse,
+                 ip_protection::android::AuthRequestError>
+      auth_and_sign_response =
+          AuthAndSignBlocking(*client, privacy::ppn::AuthAndSignRequest());
 
-                    (*client)->GetInitialData(
-                        privacy::ppn::GetInitialDataRequest(),
-                        base::BindLambdaForTesting(
-                            [&run_loop](
-                                base::expected<
-                                    privacy::ppn::GetInitialDataResponse,
-                                    ip_protection::android::AuthRequestError>
-                                    initial_data_response) {
-                              CHECK(!initial_data_response.has_value());
-                              CHECK(initial_data_response.error() ==
-                                    ip_protection::android::AuthRequestError::
-                                        kOther);
-                              run_loop.Quit();
-                            }));
-
-                    (*client)->AuthAndSign(
-                        privacy::ppn::AuthAndSignRequest(),
-                        base::BindLambdaForTesting(
-                            [&run_loop](
-                                base::expected<
-                                    privacy::ppn::AuthAndSignResponse,
-                                    ip_protection::android::AuthRequestError>
-                                    auth_and_sign_response) {
-                              CHECK(!auth_and_sign_response.has_value());
-                              CHECK(auth_and_sign_response.error() ==
-                                    ip_protection::android::AuthRequestError::
-                                        kOther);
-                              run_loop.Quit();
-                            }));
-                  })));
-  run_loop.Run();
+  CHECK(!get_initial_data_response.has_value());
+  CHECK(get_initial_data_response.error() ==
+        ip_protection::android::AuthRequestError::kOther);
+  CHECK(!auth_and_sign_response.has_value());
+  CHECK(auth_and_sign_response.error() ==
+        ip_protection::android::AuthRequestError::kOther);
 }
diff --git a/components/ip_protection/android_auth_client_lib/javatests/src/org/chromium/components/ip_protection_auth/test/IpProtectionAuthTest.java b/components/ip_protection/android_auth_client_lib/javatests/src/org/chromium/components/ip_protection_auth/test/IpProtectionAuthTest.java
index 638fff6e..a3a7b83 100644
--- a/components/ip_protection/android_auth_client_lib/javatests/src/org/chromium/components/ip_protection_auth/test/IpProtectionAuthTest.java
+++ b/components/ip_protection/android_auth_client_lib/javatests/src/org/chromium/components/ip_protection_auth/test/IpProtectionAuthTest.java
@@ -28,29 +28,38 @@
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.Batch;
-import org.chromium.base.test.util.DisabledTest;
 import org.chromium.components.ip_protection_auth.IpProtectionAuthClient;
 import org.chromium.components.ip_protection_auth.IpProtectionAuthServiceCallback;
 import org.chromium.components.ip_protection_auth.IpProtectionByteArrayCallback;
 
+/**
+ * Tests for IpProtectionAuthClient and associated classes.
+ *
+ * <p>These tests mostly call into native code (ip_protection_auth_test_natives.cc) and interact
+ * with "mock" services hosted in a secondary APK.
+ *
+ * <p>The usage of native test code for Java-hosted tests along with using native functionality like
+ * RunLoop and CHECK has the potential to make any test failures more confusing, including native
+ * crashes rather than Java AssertionErrors and global task state contamination across unrelated
+ * test suites. As such, these tests are batched PER_CLASS to isolate such failures.
+ */
 @MediumTest
 @RunWith(BaseJUnit4ClassRunner.class)
-@Batch(Batch.UNIT_TESTS)
-@DisabledTest(message = "crbug.com/347020821")
+@Batch(Batch.PER_CLASS)
 public final class IpProtectionAuthTest {
     private static final String ACTION = "android.net.http.IpProtectionAuthService";
     private static final String MOCK_PACKAGE_NAME = "org.chromium.components.ip_protection_auth";
 
     private static final String MOCK_CLASS_NAME_FOR_DEFAULT =
-            "org.chromium.components.ip_protection_auth.mock_service.IpProtectionAuthServiceMock";
+            MOCK_PACKAGE_NAME + ".mock_service.IpProtectionAuthServiceMock";
     private static final String MOCK_CLASS_NAME_FOR_NONEXISTANT =
-            "org.chromium.components.ip_protection_auth.mock_service.IntentionallyNonexistantClass";
+            MOCK_PACKAGE_NAME + ".mock_service.IntentionallyNonexistantClass";
     private static final String MOCK_CLASS_NAME_FOR_NULL_BINDING =
-            "org.chromium.components.ip_protection_auth.mock_service.NullBindingService";
+            MOCK_PACKAGE_NAME + ".mock_service.NullBindingService";
     private static final String MOCK_CLASS_NAME_FOR_DISABLED =
-            "org.chromium.components.ip_protection_auth.mock_service.NullBindingService$DisabledService";
+            MOCK_PACKAGE_NAME + ".mock_service.NullBindingService$DisabledService";
     private static final String MOCK_CLASS_NAME_FOR_RESTRICTED =
-            "org.chromium.components.ip_protection_auth.mock_service.NullBindingService$RestrictedService";
+            MOCK_PACKAGE_NAME + ".mock_service.NullBindingService$RestrictedService";
 
     private static final int TIMEOUT_MS = 10000;
 
diff --git a/components/ip_protection/ip_protection_config_provider_helper.cc b/components/ip_protection/ip_protection_config_provider_helper.cc
index c1bdc50..6a74c4f 100644
--- a/components/ip_protection/ip_protection_config_provider_helper.cc
+++ b/components/ip_protection/ip_protection_config_provider_helper.cc
@@ -7,6 +7,7 @@
 #include <string>
 #include <vector>
 
+#include "base/base64.h"
 #include "base/logging.h"
 #include "base/strings/strcat.h"
 #include "base/time/time.h"
@@ -101,3 +102,54 @@
   return network::mojom::BlindSignedAuthToken::New(
       std::move(token_header_value), expiration);
 }
+
+// static
+privacy::ppn::PrivacyPassTokenData
+IpProtectionConfigProviderHelper::CreatePrivacyPassTokenForTesting(
+    std::string token_value) {
+  privacy::ppn::PrivacyPassTokenData privacy_pass_token_data;
+
+  // The PrivacyPassTokenData values get base64-encoded by BSA, so simulate that
+  // here.
+  std::string encoded_token_value = base::Base64Encode(token_value);
+  std::string encoded_extension_value =
+      base::Base64Encode("mock-extension-value");
+
+  privacy_pass_token_data.set_token(std::move(encoded_token_value));
+  privacy_pass_token_data.set_encoded_extensions(
+      std::move(encoded_extension_value));
+
+  return privacy_pass_token_data;
+}
+
+quiche::BlindSignToken
+IpProtectionConfigProviderHelper::CreateBlindSignTokenForTesting(
+    std::string token_value,
+    base::Time expiration) {
+  privacy::ppn::PrivacyPassTokenData privacy_pass_token_data =
+      CreatePrivacyPassTokenForTesting(std::move(token_value));
+  quiche::BlindSignToken blind_sign_token;
+  blind_sign_token.token = privacy_pass_token_data.SerializeAsString();
+  blind_sign_token.expiration = absl::FromTimeT(expiration.ToTimeT());
+  return blind_sign_token;
+}
+
+net::ProxyChain IpProtectionConfigProviderHelper::MakeChainForTesting(
+    std::vector<std::string> hostnames,
+    int chain_id) {
+  std::vector<net::ProxyServer> servers;
+  for (auto& hostname : hostnames) {
+    servers.push_back(net::ProxyServer::FromSchemeHostAndPort(
+        net::ProxyServer::SCHEME_HTTPS, hostname, std::nullopt));
+  }
+  return net::ProxyChain::ForIpProtection(servers, chain_id);
+}
+
+network::mojom::BlindSignedAuthTokenPtr
+IpProtectionConfigProviderHelper::CreateMockBlindSignedAuthTokenForTesting(
+    std::string token_value,
+    base::Time expiration) {
+  quiche::BlindSignToken blind_sign_token =
+      CreateBlindSignTokenForTesting(token_value, expiration);
+  return CreateBlindSignedAuthToken(std::move(blind_sign_token));
+}
diff --git a/components/ip_protection/ip_protection_config_provider_helper.h b/components/ip_protection/ip_protection_config_provider_helper.h
index 1cc7c040..e130ee6b 100644
--- a/components/ip_protection/ip_protection_config_provider_helper.h
+++ b/components/ip_protection/ip_protection_config_provider_helper.h
@@ -6,57 +6,19 @@
 #define COMPONENTS_IP_PROTECTION_IP_PROTECTION_CONFIG_PROVIDER_HELPER_H_
 
 #include <memory>
-#include <optional>
 #include <string>
 #include <vector>
 
-#include "base/functional/callback.h"
 #include "base/time/time.h"
 #include "components/ip_protection/get_proxy_config.pb.h"
 #include "net/base/proxy_chain.h"
+#include "net/third_party/quiche/src/quiche/blind_sign_auth/proto/spend_token_data.pb.h"
 #include "services/network/public/mojom/network_context.mojom.h"
 
 namespace quiche {
 struct BlindSignToken;
 }  // namespace quiche
 
-// The result of a fetch of tokens from the IP Protection auth token server.
-//
-// These values are persisted to logs. Entries should not be renumbered and
-// numeric values should never be reused. Keep this in sync with
-// IpProtectionTokenBatchRequestResult in enums.xml.
-enum class IpProtectionTryGetAuthTokensResult {
-  // The request was successful and resulted in new tokens.
-  kSuccess = 0,
-  // No primary account is set.
-  kFailedNoAccount = 1,
-  // Chrome determined the primary account is not eligible.
-  kFailedNotEligible = 2,
-  // There was a failure fetching an OAuth token for the primary account.
-  // Deprecated in favor of `kFailedOAuthToken{Transient,Persistent}`.
-  kFailedOAuthTokenDeprecated = 3,
-  // There was a failure in BSA with the given status code.
-  kFailedBSA400 = 4,
-  kFailedBSA401 = 5,
-  kFailedBSA403 = 6,
-
-  // Any other issue calling BSA.
-  kFailedBSAOther = 7,
-
-  // There was a transient failure fetching an OAuth token for the primary
-  // account.
-  kFailedOAuthTokenTransient = 8,
-  // There was a persistent failure fetching an OAuth token for the primary
-  // account.
-  kFailedOAuthTokenPersistent = 9,
-
-  // The attempt to request tokens failed because IP Protection was disabled by
-  // the user.
-  kFailedDisabledByUser = 10,
-
-  kMaxValue = kFailedDisabledByUser,
-};
-
 // Contains static variables and methods for IpProtectionConfigProviders.
 //
 // It is the implementation's job to actually get the IP protection tokens on
@@ -79,6 +41,26 @@
   static network::mojom::BlindSignedAuthTokenPtr CreateBlindSignedAuthToken(
       const quiche::BlindSignToken& bsa_token);
 
+  // Creates a `quiche::BlindSignToken()` in the format that the BSA library
+  // will return them.
+  static quiche::BlindSignToken CreateBlindSignTokenForTesting(
+      std::string token_value,
+      base::Time expiration);
+
+  static privacy::ppn::PrivacyPassTokenData CreatePrivacyPassTokenForTesting(
+      std::string token_value);
+
+  // Shortcut to create a ProxyChain from hostnames for unit tests.
+  static net::ProxyChain MakeChainForTesting(
+      std::vector<std::string> hostnames,
+      int chain_id = net::ProxyChain::kDefaultIpProtectionChainId);
+
+  // Converts a mock token value and expiration time into the struct that will
+  // be passed to the network service.
+  static network::mojom::BlindSignedAuthTokenPtr
+  CreateMockBlindSignedAuthTokenForTesting(std::string token_value,
+                                           base::Time expiration);
+
   // Service types used for GetProxyConfigRequest.
   static constexpr char kChromeIpBlinding[] = "chromeipblinding";
   static constexpr char kWebViewIpBlinding[] = "webviewipblinding";
diff --git a/components/lens/lens_features.cc b/components/lens/lens_features.cc
index caccf21..5abb0a0 100644
--- a/components/lens/lens_features.cc
+++ b/components/lens/lens_features.cc
@@ -101,7 +101,7 @@
 const base::FeatureParam<bool> kLensOverlayEnableShimmer{
     &kLensOverlay, "enable-shimmer", true};
 const base::FeatureParam<bool> kLensOverlayEnableShimmerSparkles{
-    &kLensOverlay, "enable-shimmer-sparkles", false};
+    &kLensOverlay, "enable-shimmer-sparkles", true};
 const base::FeatureParam<bool> kLensOverlaySelectionDraggingEnabled{
     &kLensOverlay, "enable-selection-dragging", false};
 const base::FeatureParam<std::string> kResultsSearchLoadingUrl{
diff --git a/components/metrics/expired_histograms_checker.h b/components/metrics/expired_histograms_checker.h
index 52d9c170..555f1a8 100644
--- a/components/metrics/expired_histograms_checker.h
+++ b/components/metrics/expired_histograms_checker.h
@@ -6,9 +6,11 @@
 #define COMPONENTS_METRICS_EXPIRED_HISTOGRAMS_CHECKER_H_
 
 #include <stdint.h>
+
 #include <set>
 
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "base/metrics/record_histogram_checker.h"
 #include "base/strings/string_piece.h"
 
@@ -39,7 +41,7 @@
   void InitAllowlist(const std::string& allowlist_str);
 
   // Array of expired histogram hashes.
-  const base::span<const uint32_t> expired_histogram_hashes_;
+  const base::raw_span<const uint32_t> expired_histogram_hashes_;
 
   // Set of expired histogram hashes that should be recorded.
   std::set<uint32_t> allowlist_;
diff --git a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/AutocompleteMatch.java b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/AutocompleteMatch.java
index ce11dcee5..679e0d9 100644
--- a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/AutocompleteMatch.java
+++ b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/AutocompleteMatch.java
@@ -73,6 +73,7 @@
     private List<MatchClassification> mDescriptionClassifications;
     private SuggestionAnswer mAnswer;
     private @Nullable RichAnswerTemplate mAnswerTemplate;
+    private final int mAnswerType;
     private final String mFillIntoEdit;
     private GURL mUrl;
     private final GURL mImageUrl;
@@ -103,6 +104,7 @@
             List<MatchClassification> descriptionClassifications,
             SuggestionAnswer answer,
             byte[] serializedAnswerTemplate,
+            int answerType,
             String fillIntoEdit,
             GURL url,
             GURL imageUrl,
@@ -137,6 +139,7 @@
                 // When parsing error occurs, leave template as null.
             }
         }
+        mAnswerType = answerType;
         mFillIntoEdit = TextUtils.isEmpty(fillIntoEdit) ? displayText : fillIntoEdit;
         assert url != null;
         mUrl = url;
@@ -171,6 +174,7 @@
             int[] descriptionClassificationStyles,
             SuggestionAnswer answer,
             byte[] serializedAnswerTemplate,
+            int answerType,
             String fillIntoEdit,
             GURL url,
             GURL imageUrl,
@@ -211,6 +215,7 @@
                         new ArrayList<>(),
                         answer,
                         serializedAnswerTemplate,
+                        answerType,
                         fillIntoEdit,
                         url,
                         imageUrl,
@@ -338,6 +343,10 @@
         return mAnswerTemplate;
     }
 
+    public @AnswerType int getAnswerType() {
+        return mAnswerType;
+    }
+
     public @NonNull String getFillIntoEdit() {
         return mFillIntoEdit;
     }
diff --git a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/AutocompleteMatchBuilder.java b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/AutocompleteMatchBuilder.java
index 193ba3fb..e07d77d 100644
--- a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/AutocompleteMatchBuilder.java
+++ b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/AutocompleteMatchBuilder.java
@@ -31,6 +31,7 @@
     private List<AutocompleteMatch.MatchClassification> mDescriptionClassifications;
     private SuggestionAnswer mAnswer;
     private byte[] mSerializedAnswerTemplate;
+    private @AnswerType int mAnswerType;
     private String mFillIntoEdit;
     private GURL mUrl;
     private GURL mImageUrl;
@@ -58,6 +59,7 @@
                 .setIsSearch(true)
                 .setDisplayText("Placeholder Suggestion")
                 .setDescription("Placeholder Description")
+                .setAnswerType(AnswerType.INVALID)
                 .setUrl(JUnitTestGURLs.SEARCH_URL);
     }
 
@@ -81,6 +83,7 @@
         mDescriptionClassifications = new ArrayList<>();
         mAnswer = null;
         mSerializedAnswerTemplate = null;
+        mAnswerType = AnswerType.INVALID;
         mFillIntoEdit = null;
         mUrl = GURL.emptyGURL();
         mImageUrl = GURL.emptyGURL();
@@ -123,6 +126,7 @@
                 mDescriptionClassifications,
                 mAnswer,
                 mSerializedAnswerTemplate,
+                mAnswerType,
                 mFillIntoEdit,
                 mUrl,
                 mImageUrl,
@@ -239,6 +243,15 @@
     }
 
     /**
+     * @param answer The type of answer in the Omnibox suggestion.
+     * @return Omnibox suggestion builder.
+     */
+    public AutocompleteMatchBuilder setAnswerType(@AnswerType int answerType) {
+        mAnswerType = answerType;
+        return this;
+    }
+
+    /**
      * @param clipboardImageData Image data to set for this suggestion.
      * @return Omnibox suggestion builder.
      */
diff --git a/components/omnibox/browser/autocomplete_match_android.cc b/components/omnibox/browser/autocomplete_match_android.cc
index 6100be17..7fa8a52f 100644
--- a/components/omnibox/browser/autocomplete_match_android.cc
+++ b/components/omnibox/browser/autocomplete_match_android.cc
@@ -106,7 +106,8 @@
           ConvertUTF16ToJavaString(env, description),
           ToJavaIntArray(env, description_class_offsets),
           ToJavaIntArray(env, description_class_styles), janswer,
-          j_answer_template, ConvertUTF16ToJavaString(env, fill_into_edit),
+          j_answer_template, answer_type,
+          ConvertUTF16ToJavaString(env, fill_into_edit),
           url::GURLAndroid::FromNativeGURL(env, destination_url),
           url::GURLAndroid::FromNativeGURL(env, image_url),
           j_image_dominant_color, SupportsDeletion(), j_post_content_type,
diff --git a/components/omnibox/browser/base_search_provider.cc b/components/omnibox/browser/base_search_provider.cc
index 7069027..9741b94e 100644
--- a/components/omnibox/browser/base_search_provider.cc
+++ b/components/omnibox/browser/base_search_provider.cc
@@ -634,6 +634,7 @@
         existing_match.duplicate_matches.back();
     if (less_relevant_duplicate_match.answer && !existing_match.answer) {
       existing_match.answer = less_relevant_duplicate_match.answer;
+      existing_match.answer_type = less_relevant_duplicate_match.answer_type;
       if (OmniboxFieldTrial::kAnswerActionsShowRichCard.Get()) {
         existing_match.suggestion_group_id =
             less_relevant_duplicate_match.suggestion_group_id;
@@ -644,6 +645,7 @@
         !existing_match.answer_template) {
       existing_match.answer_template =
           less_relevant_duplicate_match.answer_template;
+      existing_match.answer_type = less_relevant_duplicate_match.answer_type;
       if (OmniboxFieldTrial::kAnswerActionsShowRichCard.Get()) {
         existing_match.suggestion_group_id =
             less_relevant_duplicate_match.suggestion_group_id;
diff --git a/components/omnibox/browser/history_embeddings_provider.cc b/components/omnibox/browser/history_embeddings_provider.cc
index 7d9da795c..a9ef480 100644
--- a/components/omnibox/browser/history_embeddings_provider.cc
+++ b/components/omnibox/browser/history_embeddings_provider.cc
@@ -75,20 +75,20 @@
   for (const history_embeddings::ScoredUrlRow& scored_url_row :
        result.scored_url_rows) {
     AutocompleteMatch match(this, scored_url_row.scored_url.score * kMaxScore,
-                            false, AutocompleteMatchType::HISTORY_BODY);
+                            false, AutocompleteMatchType::HISTORY_EMBEDDINGS);
     match.destination_url = scored_url_row.row.url();
 
-    match.contents =
+    match.description =
         AutocompleteMatch::SanitizeString(scored_url_row.row.title());
-    match.contents_class = ClassifyTermMatches(
-        FindTermMatches(input_text, match.contents), match.contents.size(),
-        ACMatchClassification::MATCH, ACMatchClassification::NONE);
-
-    match.description = base::UTF8ToUTF16(scored_url_row.row.url().spec());
     match.description_class = ClassifyTermMatches(
         FindTermMatches(input_text, match.description),
         match.description.size(), ACMatchClassification::MATCH,
-        ACMatchClassification::URL);
+        ACMatchClassification::NONE);
+
+    match.contents = base::UTF8ToUTF16(scored_url_row.row.url().spec());
+    match.contents_class = ClassifyTermMatches(
+        FindTermMatches(input_text, match.contents), match.contents.size(),
+        ACMatchClassification::MATCH, ACMatchClassification::URL);
 
     if (starter_pack_engine_) {
       match.keyword = starter_pack_engine_->keyword();
diff --git a/components/omnibox/browser/history_embeddings_provider_unittest.cc b/components/omnibox/browser/history_embeddings_provider_unittest.cc
index 022b12c..77cc9d3 100644
--- a/components/omnibox/browser/history_embeddings_provider_unittest.cc
+++ b/components/omnibox/browser/history_embeddings_provider_unittest.cc
@@ -65,11 +65,11 @@
   EXPECT_EQ(history_embeddings_provider_->matches_[0].relevance, 500);
   EXPECT_EQ(history_embeddings_provider_->matches_[0].deletable, false);
   EXPECT_EQ(history_embeddings_provider_->matches_[0].type,
-            AutocompleteMatchType::HISTORY_BODY);
+            AutocompleteMatchType::HISTORY_EMBEDDINGS);
   EXPECT_EQ(history_embeddings_provider_->matches_[0].destination_url.spec(),
             "https://url.com/");
-  EXPECT_EQ(history_embeddings_provider_->matches_[0].contents, u"title");
-  EXPECT_EQ(history_embeddings_provider_->matches_[0].description,
+  EXPECT_EQ(history_embeddings_provider_->matches_[0].description, u"title");
+  EXPECT_EQ(history_embeddings_provider_->matches_[0].contents,
             u"https://url.com/");
   EXPECT_EQ(history_embeddings_provider_->matches_[0].keyword, u"");
   EXPECT_TRUE(PageTransitionCoreTypeIs(
diff --git a/components/password_manager/core/browser/password_store/BUILD.gn b/components/password_manager/core/browser/password_store/BUILD.gn
index 7e554a96..8410a57 100644
--- a/components/password_manager/core/browser/password_store/BUILD.gn
+++ b/components/password_manager/core/browser/password_store/BUILD.gn
@@ -29,6 +29,7 @@
 
 source_set("password_store_impl") {
   sources = [
+    "encrypt_decrypt_intrface.h",
     "get_logins_with_affiliations_request_handler.cc",
     "get_logins_with_affiliations_request_handler.h",
     "insecure_credentials_table.cc",
diff --git a/components/password_manager/core/browser/password_store/encrypt_decrypt_intrface.h b/components/password_manager/core/browser/password_store/encrypt_decrypt_intrface.h
new file mode 100644
index 0000000..251e457
--- /dev/null
+++ b/components/password_manager/core/browser/password_store/encrypt_decrypt_intrface.h
@@ -0,0 +1,47 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_ENCRYPT_DECRYPT_INTRFACE_H_
+#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_ENCRYPT_DECRYPT_INTRFACE_H_
+
+#include <string>
+
+namespace password_manager {
+
+// Result values for encryption/decryption actions.
+enum class EncryptionResult {
+  // Success.
+  kSuccess,
+  // Failure for a specific item (e.g., the encrypted value was manually
+  // moved from another machine, and can't be decrypted on this machine).
+  // This is presumed to be a permanent failure.
+  kItemFailure,
+  // A service-level failure (e.g., on a platform using a keyring, the keyring
+  // is temporarily unavailable).
+  // This is presumed to be a temporary failure.
+  kServiceFailure,
+};
+
+class EncryptDecryptInterface {
+ public:
+  // Encrypts plain_text, setting the value of cipher_text and returning true if
+  // successful, or returning false and leaving cipher_text unchanged if
+  // encryption fails (e.g., if the underlying OS encryption system is
+  // temporarily unavailable).
+  [[nodiscard]] virtual EncryptionResult EncryptedString(
+      const std::u16string& plain_text,
+      std::string* cipher_text) const = 0;
+
+  // Decrypts cipher_text, setting the value of plain_text and returning true if
+  // successful, or returning false and leaving plain_text unchanged if
+  // decryption fails (e.g., if the underlying OS encryption system is
+  // temporarily unavailable).
+  [[nodiscard]] virtual EncryptionResult DecryptedString(
+      const std::string& cipher_text,
+      std::u16string* plain_text) const = 0;
+};
+
+}  // namespace password_manager
+
+#endif  // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_ENCRYPT_DECRYPT_INTRFACE_H_
diff --git a/components/password_manager/core/browser/password_store/login_database.cc b/components/password_manager/core/browser/password_store/login_database.cc
index 3923ba9..71ac8efb 100644
--- a/components/password_manager/core/browser/password_store/login_database.cc
+++ b/components/password_manager/core/browser/password_store/login_database.cc
@@ -744,7 +744,9 @@
   return password_value_update.Run();
 }
 
-bool MigrateToOSCrypt(IsAccountStore is_account_store, sql::Database* db) {
+bool MigrateToOSCrypt(IsAccountStore is_account_store,
+                      sql::Database* db,
+                      EncryptDecryptInterface* encryptor) {
   sql::Statement get_passwords_statement(
       db->GetUniqueStatement("SELECT id, password_value FROM logins"));
   // Update each password_value with the new BLOB.
@@ -767,9 +769,8 @@
     } else {
       // Encrypt password using OSCrypt.
       std::string encrypted_password;
-      if (LoginDatabase::EncryptedString(plaintext_password,
-                                         &encrypted_password) !=
-          LoginDatabase::ENCRYPTION_RESULT_SUCCESS) {
+      if (encryptor->EncryptedString(plaintext_password, &encrypted_password) !=
+          EncryptionResult::kSuccess) {
         return false;
       }
       // Updated password_value in the database.
@@ -788,7 +789,8 @@
 bool MigrateDatabase(unsigned current_version,
                      SQLTableBuilders builders,
                      IsAccountStore is_account_store,
-                     sql::Database* db) {
+                     sql::Database* db,
+                     EncryptDecryptInterface* encryptor) {
   if (!builders.logins->MigrateFrom(
           current_version, db,
           base::BindRepeating(&LoginsTablePostMigrationStepCallback))) {
@@ -901,7 +903,7 @@
       return false;
     }
 
-    return MigrateToOSCrypt(is_account_store, db);
+    return MigrateToOSCrypt(is_account_store, db, encryptor);
   }
 #endif
 
@@ -997,17 +999,18 @@
   return entity_metadata;
 }
 
-LoginDatabase::EncryptionResult DecryptPasswordFromStatement(
+EncryptionResult DecryptPasswordFromStatement(
     sql::Statement& s,
-    std::u16string* plaintext_password) {
+    std::u16string* plaintext_password,
+    EncryptDecryptInterface* decryptor) {
   CHECK(plaintext_password);
   std::string encrypted_password;
   s.ColumnBlobAsString(COLUMN_PASSWORD_VALUE, &encrypted_password);
-  LoginDatabase::EncryptionResult encryption_result =
-      LoginDatabase::DecryptedString(encrypted_password, plaintext_password);
-  if (encryption_result != LoginDatabase::ENCRYPTION_RESULT_SUCCESS) {
+  EncryptionResult encryption_result =
+      decryptor->DecryptedString(encrypted_password, plaintext_password);
+  if (encryption_result != EncryptionResult::kSuccess) {
     DLOG(WARNING) << "Password decryption failed, encryption_result is "
-                  << encryption_result;
+                  << static_cast<int>(encryption_result);
   }
   return encryption_result;
 }
@@ -1154,7 +1157,7 @@
 
   stats_table_.Init(&db_);
   insecure_credentials_table_.Init(&db_);
-  password_notes_table_.Init(&db_);
+  password_notes_table_.Init(&db_, this);
 
   int current_version = meta_table_.GetVersionNumber();
   bool migration_success = FixVersionIfNeeded(&db_, &current_version);
@@ -1163,7 +1166,7 @@
   if (migration_success && current_version < kCurrentVersionNumber) {
     migration_success =
         MigrateDatabase(base::checked_cast<unsigned>(current_version), builders,
-                        is_account_store_, &db_);
+                        is_account_store_, &db_, this);
   }
   // Enforce that 'insecure_credentials' is created only after the 'logins'
   // table was created and migrated to the latest version. This guarantees the
@@ -1266,7 +1269,7 @@
   while (get_passwords_statement.Step()) {
     std::u16string decrypted_password;
     if (DecryptedString(get_passwords_statement.ColumnString(0),
-                        &decrypted_password) != ENCRYPTION_RESULT_SUCCESS) {
+                        &decrypted_password) != EncryptionResult::kSuccess) {
       ++failed_encryption;
     }
   }
@@ -1348,7 +1351,7 @@
 #endif  // BUILDFLAG(IS_IOS)
   std::string encrypted_password;
   if (EncryptedString(form_to_add.password_value, &encrypted_password) !=
-      ENCRYPTION_RESULT_SUCCESS) {
+      EncryptionResult::kSuccess) {
     if (error) {
       *error = AddCredentialError::kEncryptionServiceFailure;
     }
@@ -1419,7 +1422,7 @@
   }
   std::string encrypted_password;
   if (EncryptedString(form.password_value, &encrypted_password) !=
-      ENCRYPTION_RESULT_SUCCESS) {
+      EncryptionResult::kSuccess) {
     if (error) {
       *error = UpdateCredentialError::kEncryptionServiceFailure;
     }
@@ -1937,7 +1940,7 @@
     s.ColumnBlobAsString(COLUMN_PASSWORD_VALUE, &encrypted_password);
     std::u16string decrypted_password;
     if (DecryptedString(encrypted_password, &decrypted_password) ==
-        ENCRYPTION_RESULT_SUCCESS) {
+        EncryptionResult::kSuccess) {
       continue;
     }
 
@@ -2291,7 +2294,7 @@
     s.ColumnBlobAsString(1, &encrypted_password);
     s.ColumnBlobAsString(2, &result.keychain_identifier);
     if (DecryptedString(encrypted_password, &result.decrypted_password) !=
-        ENCRYPTION_RESULT_SUCCESS) {
+        EncryptionResult::kSuccess) {
       result.decrypted_password.clear();
     }
     return result;
@@ -2320,14 +2323,14 @@
   while (statement->Step()) {
     std::u16string plaintext_password;
     EncryptionResult result =
-        DecryptPasswordFromStatement(*statement, &plaintext_password);
-    if (result == ENCRYPTION_RESULT_SERVICE_FAILURE ||
-        result == ENCRYPTION_RESULT_ITEM_FAILURE) {
+        DecryptPasswordFromStatement(*statement, &plaintext_password, this);
+    if (result == EncryptionResult::kItemFailure ||
+        result == EncryptionResult::kServiceFailure) {
       failed = true;
       continue;
     }
 
-    DCHECK_EQ(ENCRYPTION_RESULT_SUCCESS, result);
+    DCHECK_EQ(EncryptionResult::kSuccess, result);
 
     PasswordForm form = GetFormWithoutPasswordFromStatement(*statement);
     form.password_value = std::move(plaintext_password);
diff --git a/components/password_manager/core/browser/password_store/login_database.h b/components/password_manager/core/browser/password_store/login_database.h
index d0befca..1e239fa 100644
--- a/components/password_manager/core/browser/password_store/login_database.h
+++ b/components/password_manager/core/browser/password_store/login_database.h
@@ -15,6 +15,7 @@
 #include "base/pickle.h"
 #include "build/build_config.h"
 #include "components/password_manager/core/browser/password_form.h"
+#include "components/password_manager/core/browser/password_store/encrypt_decrypt_intrface.h"
 #include "components/password_manager/core/browser/password_store/insecure_credentials_table.h"
 #include "components/password_manager/core/browser/password_store/password_notes_table.h"
 #include "components/password_manager/core/browser/password_store/password_store.h"
@@ -46,7 +47,7 @@
 // Interface to the database storage of login information, intended as a helper
 // for PasswordStore on platforms that need internal storage of some or all of
 // the login information.
-class LoginDatabase {
+class LoginDatabase : public EncryptDecryptInterface {
  public:
   struct LoginDatabaseEmptinessState {
     // True if the login database has 0 passwords stored.
@@ -205,36 +206,6 @@
     return password_sync_metadata_store_;
   }
 
-  // Result values for encryption/decryption actions.
-  enum EncryptionResult {
-    // Success.
-    ENCRYPTION_RESULT_SUCCESS,
-    // Failure for a specific item (e.g., the encrypted value was manually
-    // moved from another machine, and can't be decrypted on this machine).
-    // This is presumed to be a permanent failure.
-    ENCRYPTION_RESULT_ITEM_FAILURE,
-    // A service-level failure (e.g., on a platform using a keyring, the keyring
-    // is temporarily unavailable).
-    // This is presumed to be a temporary failure.
-    ENCRYPTION_RESULT_SERVICE_FAILURE,
-  };
-
-  // Encrypts plain_text, setting the value of cipher_text and returning true if
-  // successful, or returning false and leaving cipher_text unchanged if
-  // encryption fails (e.g., if the underlying OS encryption system is
-  // temporarily unavailable).
-  [[nodiscard]] static EncryptionResult EncryptedString(
-      const std::u16string& plain_text,
-      std::string* cipher_text);
-
-  // Decrypts cipher_text, setting the value of plain_text and returning true if
-  // successful, or returning false and leaving plain_text unchanged if
-  // decryption fails (e.g., if the underlying OS encryption system is
-  // temporarily unavailable).
-  [[nodiscard]] static EncryptionResult DecryptedString(
-      const std::string& cipher_text,
-      std::u16string* plain_text);
-
   // After `were_undecryptable_logins_deleted_` is used by the
   // `PasswordSyncBridge` it should be cleared to avoid unnecessary sync calls.
   void clear_were_undecryptable_logins_deleted() {
@@ -248,6 +219,14 @@
   }
 
  private:
+  // EncryptDecryptInterface implementation.
+  [[nodiscard]] EncryptionResult EncryptedString(
+      const std::u16string& plain_text,
+      std::string* cipher_text) const override;
+  [[nodiscard]] EncryptionResult DecryptedString(
+      const std::string& cipher_text,
+      std::u16string* plain_text) const override;
+
   struct PrimaryKeyAndPassword;
   class SyncMetadataStore : public PasswordStoreSync::MetadataStore {
    public:
diff --git a/components/password_manager/core/browser/password_store/login_database_ios.cc b/components/password_manager/core/browser/password_store/login_database_ios.cc
index 6c7e2ab..3297dce 100644
--- a/components/password_manager/core/browser/password_store/login_database_ios.cc
+++ b/components/password_manager/core/browser/password_store/login_database_ios.cc
@@ -39,20 +39,20 @@
 // stored as an attribute along with the password in the keychain.
 // A side effect of this approach is that the same password saved multiple
 // times will have different "encrypted" values.
-LoginDatabase::EncryptionResult LoginDatabase::EncryptedString(
+EncryptionResult LoginDatabase::EncryptedString(
     const std::u16string& plain_text,
-    std::string* cipher_text) {
+    std::string* cipher_text) const {
   return OSCrypt::EncryptString16(plain_text, cipher_text)
-             ? ENCRYPTION_RESULT_SUCCESS
-             : ENCRYPTION_RESULT_SERVICE_FAILURE;
+             ? EncryptionResult::kSuccess
+             : EncryptionResult::kServiceFailure;
 }
 
-LoginDatabase::EncryptionResult LoginDatabase::DecryptedString(
+EncryptionResult LoginDatabase::DecryptedString(
     const std::string& cipher_text,
-    std::u16string* plain_text) {
+    std::u16string* plain_text) const {
   return OSCrypt::DecryptString16(cipher_text, plain_text)
-             ? ENCRYPTION_RESULT_SUCCESS
-             : ENCRYPTION_RESULT_SERVICE_FAILURE;
+             ? EncryptionResult::kSuccess
+             : EncryptionResult::kServiceFailure;
 }
 
 bool CreateKeychainIdentifier(const std::u16string& plain_text,
diff --git a/components/password_manager/core/browser/password_store/login_database_ios_unittest.cc b/components/password_manager/core/browser/password_store/login_database_ios_unittest.cc
index 87ad78d..9ec7522 100644
--- a/components/password_manager/core/browser/password_store/login_database_ios_unittest.cc
+++ b/components/password_manager/core/browser/password_store/login_database_ios_unittest.cc
@@ -65,12 +65,13 @@
   };
 
   for (unsigned int i = 0; i < std::size(test_passwords); i++) {
+    EncryptDecryptInterface* encryptor_decryptor = login_db_.get();
     std::string encrypted;
-    EXPECT_EQ(LoginDatabase::ENCRYPTION_RESULT_SUCCESS,
-              login_db_->EncryptedString(test_passwords[i], &encrypted));
+    EXPECT_EQ(EncryptionResult::kSuccess, encryptor_decryptor->EncryptedString(
+                                              test_passwords[i], &encrypted));
     std::u16string decrypted;
-    EXPECT_EQ(LoginDatabase::ENCRYPTION_RESULT_SUCCESS,
-              login_db_->DecryptedString(encrypted, &decrypted));
+    EXPECT_EQ(EncryptionResult::kSuccess,
+              encryptor_decryptor->DecryptedString(encrypted, &decrypted));
     EXPECT_STREQ(UTF16ToUTF8(test_passwords[i]).c_str(),
                  UTF16ToUTF8(decrypted).c_str());
   }
diff --git a/components/password_manager/core/browser/password_store/login_database_mac.cc b/components/password_manager/core/browser/password_store/login_database_mac.cc
index 3efcfe3..50ae207 100644
--- a/components/password_manager/core/browser/password_store/login_database_mac.cc
+++ b/components/password_manager/core/browser/password_store/login_database_mac.cc
@@ -8,20 +8,20 @@
 
 namespace password_manager {
 
-LoginDatabase::EncryptionResult LoginDatabase::EncryptedString(
+EncryptionResult LoginDatabase::EncryptedString(
     const std::u16string& plain_text,
-    std::string* cipher_text) {
+    std::string* cipher_text) const {
   return OSCrypt::EncryptString16(plain_text, cipher_text)
-             ? ENCRYPTION_RESULT_SUCCESS
-             : ENCRYPTION_RESULT_SERVICE_FAILURE;
+             ? EncryptionResult::kSuccess
+             : EncryptionResult::kServiceFailure;
 }
 
-LoginDatabase::EncryptionResult LoginDatabase::DecryptedString(
+EncryptionResult LoginDatabase::DecryptedString(
     const std::string& cipher_text,
-    std::u16string* plain_text) {
+    std::u16string* plain_text) const {
   return OSCrypt::DecryptString16(cipher_text, plain_text)
-             ? ENCRYPTION_RESULT_SUCCESS
-             : ENCRYPTION_RESULT_SERVICE_FAILURE;
+             ? EncryptionResult::kSuccess
+             : EncryptionResult::kServiceFailure;
 }
 
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store/login_database_posix.cc b/components/password_manager/core/browser/password_store/login_database_posix.cc
index c16243d..3baf8ea 100644
--- a/components/password_manager/core/browser/password_store/login_database_posix.cc
+++ b/components/password_manager/core/browser/password_store/login_database_posix.cc
@@ -28,17 +28,17 @@
 
 }  // namespace
 
-LoginDatabase::EncryptionResult LoginDatabase::EncryptedString(
+EncryptionResult LoginDatabase::EncryptedString(
     const std::u16string& plain_text,
-    std::string* cipher_text) {
+    std::string* cipher_text) const {
   return OSCrypt::EncryptString16(plain_text, cipher_text)
-             ? ENCRYPTION_RESULT_SUCCESS
-             : ENCRYPTION_RESULT_SERVICE_FAILURE;
+             ? EncryptionResult::kSuccess
+             : EncryptionResult::kServiceFailure;
 }
 
-LoginDatabase::EncryptionResult LoginDatabase::DecryptedString(
+EncryptionResult LoginDatabase::DecryptedString(
     const std::string& cipher_text,
-    std::u16string* plain_text) {
+    std::u16string* plain_text) const {
 #if !BUILDFLAG(IS_FUCHSIA)
 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH)
   // On Android and ChromeOS, we have a mix of obfuscated and plain-text
@@ -55,7 +55,7 @@
     *plain_text = base::UTF8ToUTF16(cipher_text);
     RecordPasswordDecryptionResult(
         PasswordDecryptionResult::kSucceededBySkipping);
-    return ENCRYPTION_RESULT_SUCCESS;
+    return EncryptionResult::kSuccess;
   }
 #endif  // !BUILDFLAG(IS_FUCHSIA)
 
@@ -69,14 +69,14 @@
     *plain_text = base::UTF8ToUTF16(cipher_text);
     RecordPasswordDecryptionResult(
         PasswordDecryptionResult::kSucceededByIgnoringFailure);
-    return ENCRYPTION_RESULT_SUCCESS;
+    return EncryptionResult::kSuccess;
   }
 #endif
   RecordPasswordDecryptionResult(decryption_success
                                      ? PasswordDecryptionResult::kSucceeded
                                      : PasswordDecryptionResult::kFailed);
-  return decryption_success ? ENCRYPTION_RESULT_SUCCESS
-                            : ENCRYPTION_RESULT_SERVICE_FAILURE;
+  return decryption_success ? EncryptionResult::kSuccess
+                            : EncryptionResult::kServiceFailure;
 }
 
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store/login_database_win.cc b/components/password_manager/core/browser/password_store/login_database_win.cc
index 083f2c88..ce0987fa 100644
--- a/components/password_manager/core/browser/password_store/login_database_win.cc
+++ b/components/password_manager/core/browser/password_store/login_database_win.cc
@@ -9,18 +9,18 @@
 
 namespace password_manager {
 
-LoginDatabase::EncryptionResult LoginDatabase::EncryptedString(
+EncryptionResult LoginDatabase::EncryptedString(
     const std::u16string& plain_text,
-    std::string* cipher_text) {
+    std::string* cipher_text) const {
   if (OSCrypt::EncryptString16(plain_text, cipher_text)) {
-    return ENCRYPTION_RESULT_SUCCESS;
+    return EncryptionResult::kSuccess;
   }
-  return ENCRYPTION_RESULT_ITEM_FAILURE;
+  return EncryptionResult::kItemFailure;
 }
 
-LoginDatabase::EncryptionResult LoginDatabase::DecryptedString(
+EncryptionResult LoginDatabase::DecryptedString(
     const std::string& cipher_text,
-    std::u16string* plain_text) {
+    std::u16string* plain_text) const {
   // Unittests need to read sample database entries. If these entries had real
   // passwords, their encoding would need to be different for every platform.
   // To avoid the need for that, the entries have empty passwords. OSCrypt on
@@ -32,12 +32,12 @@
   // discussion.
   if (cipher_text.empty()) {
     plain_text->clear();
-    return ENCRYPTION_RESULT_SUCCESS;
+    return EncryptionResult::kSuccess;
   }
   if (OSCrypt::DecryptString16(cipher_text, plain_text)) {
-    return ENCRYPTION_RESULT_SUCCESS;
+    return EncryptionResult::kSuccess;
   }
-  return ENCRYPTION_RESULT_ITEM_FAILURE;
+  return EncryptionResult::kItemFailure;
 }
 
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store/password_notes_table.cc b/components/password_manager/core/browser/password_store/password_notes_table.cc
index bcb770af..894b172 100644
--- a/components/password_manager/core/browser/password_store/password_notes_table.cc
+++ b/components/password_manager/core/browser/password_store/password_notes_table.cc
@@ -15,13 +15,15 @@
 #include "components/affiliations/core/browser/sql_table_builder.h"
 #include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
-#include "components/password_manager/core/browser/password_store/login_database.h"
+#include "components/password_manager/core/browser/password_store/encrypt_decrypt_intrface.h"
 #include "components/password_manager/core/browser/sync/password_store_sync.h"
 #include "sql/database.h"
 #include "sql/statement.h"
 
 #if BUILDFLAG(IS_IOS)
 #import <Security/Security.h>
+
+#include "components/password_manager/core/browser/password_store/login_database.h"
 #endif  // BUILDFLAG(IS_IOS)
 
 namespace password_manager {
@@ -29,15 +31,16 @@
 
 // Helper function to return a password notes map from the SQL statement.
 std::map<FormPrimaryKey, std::vector<PasswordNote>> StatementToPasswordNotes(
-    sql::Statement* s) {
+    sql::Statement* s,
+    EncryptDecryptInterface* decryptor) {
   std::map<FormPrimaryKey, std::vector<PasswordNote>> results;
   while (s->Step()) {
     std::u16string unique_display_name = s->ColumnString16(1);
     std::string encrypted_value;
     s->ColumnBlobAsString(2, &encrypted_value);
     std::u16string decrypted_value;
-    if (LoginDatabase::DecryptedString(encrypted_value, &decrypted_value) !=
-        LoginDatabase::ENCRYPTION_RESULT_SUCCESS) {
+    if (decryptor->DecryptedString(encrypted_value, &decrypted_value) !=
+        EncryptionResult::kSuccess) {
       continue;
     }
 
@@ -57,8 +60,11 @@
 
 const char PasswordNotesTable::kTableName[] = "password_notes";
 
-void PasswordNotesTable::Init(sql::Database* db) {
+void PasswordNotesTable::Init(
+    sql::Database* db,
+    EncryptDecryptInterface* encrypt_decrypt_intrface) {
   db_ = db;
+  encrypt_decrypt_intrface_ = encrypt_decrypt_intrface;
 }
 
 bool PasswordNotesTable::MigrateTable(int current_version,
@@ -102,8 +108,9 @@
       } else {
         // Encrypt note using OSCrypt.
         std::string encrypted_note;
-        if (LoginDatabase::EncryptedString(plaintext_note, &encrypted_note) !=
-            LoginDatabase::ENCRYPTION_RESULT_SUCCESS) {
+        if (encrypt_decrypt_intrface_->EncryptedString(plaintext_note,
+                                                       &encrypted_note) !=
+            EncryptionResult::kSuccess) {
           return false;
         }
 
@@ -126,8 +133,8 @@
                                          const PasswordNote& note) {
   DCHECK(db_);
   std::string encrypted_value;
-  if (LoginDatabase::EncryptedString(note.value, &encrypted_value) !=
-      LoginDatabase::ENCRYPTION_RESULT_SUCCESS) {
+  if (encrypt_decrypt_intrface_->EncryptedString(
+          note.value, &encrypted_value) != EncryptionResult::kSuccess) {
     return false;
   }
 
@@ -166,7 +173,8 @@
           "FROM %s WHERE parent_id = ? ",
           kTableName)));
   s.BindInt(0, parent_id.value());
-  return StatementToPasswordNotes(&s)[parent_id];
+  return StatementToPasswordNotes(&s,
+                                  encrypt_decrypt_intrface_.get())[parent_id];
 }
 
 std::map<FormPrimaryKey, std::vector<PasswordNote>>
@@ -178,6 +186,6 @@
           "SELECT parent_id, key, value, date_created, confidential "
           "FROM %s",
           kTableName)));
-  return StatementToPasswordNotes(&s);
+  return StatementToPasswordNotes(&s, encrypt_decrypt_intrface_.get());
 }
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store/password_notes_table.h b/components/password_manager/core/browser/password_store/password_notes_table.h
index 4b516c2..1d7a7f2 100644
--- a/components/password_manager/core/browser/password_store/password_notes_table.h
+++ b/components/password_manager/core/browser/password_store/password_notes_table.h
@@ -17,6 +17,8 @@
 
 namespace password_manager {
 
+class EncryptDecryptInterface;
+
 // Represents the 'password_notes' table in the Login Database.
 class PasswordNotesTable {
  public:
@@ -30,7 +32,8 @@
   ~PasswordNotesTable() = default;
 
   // Initializes `db_`. `db_` should not be null and outlive this class.
-  void Init(sql::Database* db);
+  void Init(sql::Database* db,
+            EncryptDecryptInterface* encrypt_decrypt_intrface);
 
   // Migrates this table from `current_version` to `kCurrentVersionNumber`
   // defined in the login db.
@@ -51,6 +54,7 @@
 
  private:
   raw_ptr<sql::Database> db_ = nullptr;
+  raw_ptr<EncryptDecryptInterface> encrypt_decrypt_intrface_ = nullptr;
 };
 
 }  // namespace password_manager
diff --git a/components/password_manager/ios/password_suggestion_helper.mm b/components/password_manager/ios/password_suggestion_helper.mm
index b25cf163..d72e56b 100644
--- a/components/password_manager/ios/password_suggestion_helper.mm
+++ b/components/password_manager/ios/password_suggestion_helper.mm
@@ -174,7 +174,7 @@
                                suggestionWithValue:username
                                 displayDescription:realm
                                               icon:nil
-                                       popupItemId:autofill::SuggestionType::
+                                              type:autofill::SuggestionType::
                                                        kAutocompleteEntry
                                  backendIdentifier:nil
                                     requiresReauth:YES
diff --git a/components/password_manager/ios/shared_password_controller.mm b/components/password_manager/ios/shared_password_controller.mm
index 5e1235e9..edde70c 100644
--- a/components/password_manager/ios/shared_password_controller.mm
+++ b/components/password_manager/ios/shared_password_controller.mm
@@ -561,7 +561,7 @@
                suggestionWithValue:value
                 displayDescription:rawSuggestion.displayDescription
                               icon:nil
-                       popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                              type:autofill::SuggestionType::kAutocompleteEntry
                  backendIdentifier:nil
                     requiresReauth:YES
         acceptanceA11yAnnouncement:nil
@@ -582,7 +582,7 @@
         suggestionWithValue:suggestPassword
          displayDescription:nil
                        icon:nil
-                popupItemId:autofill::SuggestionType::kGeneratePasswordEntry
+                       type:autofill::SuggestionType::kGeneratePasswordEntry
           backendIdentifier:nil
              requiresReauth:NO];
 
@@ -614,7 +614,7 @@
     return;
   }
 
-  switch (suggestion.popupItemId) {
+  switch (suggestion.type) {
     case autofill::SuggestionType::kAllSavedPasswordsEntry: {
       completion();
       password_manager::metrics_util::LogPasswordDropdownItemSelected(
diff --git a/components/password_manager/ios/shared_password_controller_unittest.mm b/components/password_manager/ios/shared_password_controller_unittest.mm
index 968bcf3..5e0ec02 100644
--- a/components/password_manager/ios/shared_password_controller_unittest.mm
+++ b/components/password_manager/ios/shared_password_controller_unittest.mm
@@ -444,7 +444,7 @@
              suggestionWithValue:@"value"
               displayDescription:@"display-description"
                             icon:nil
-                     popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                            type:autofill::SuggestionType::kAutocompleteEntry
                backendIdentifier:nil
                   requiresReauth:NO
       acceptanceA11yAnnouncement:nil
@@ -527,7 +527,7 @@
                  ASSERT_EQ(1UL, suggestions.count);
                  FormSuggestion* suggestion = suggestions.firstObject;
                  EXPECT_EQ(autofill::SuggestionType::kGeneratePasswordEntry,
-                           suggestion.popupItemId);
+                           suggestion.type);
                  EXPECT_EQ(delegate, controller_);
                  completion_was_called = YES;
                }];
@@ -576,7 +576,7 @@
       suggestionWithValue:@"test-value"
        displayDescription:@"test-description"
                      icon:nil
-              popupItemId:autofill::SuggestionType::kGeneratePasswordEntry
+                     type:autofill::SuggestionType::kGeneratePasswordEntry
         backendIdentifier:nil
            requiresReauth:NO];
 
@@ -646,7 +646,7 @@
       suggestionWithValue:@"test-value"
        displayDescription:@"test-description"
                      icon:nil
-              popupItemId:autofill::SuggestionType::kGeneratePasswordEntry
+                     type:autofill::SuggestionType::kGeneratePasswordEntry
         backendIdentifier:nil
            requiresReauth:NO];
 
@@ -1382,7 +1382,7 @@
       suggestionWithValue:@"test-value"
        displayDescription:@"test-description"
                      icon:nil
-              popupItemId:autofill::SuggestionType::kGeneratePasswordEntry
+                     type:autofill::SuggestionType::kGeneratePasswordEntry
         backendIdentifier:nil
            requiresReauth:NO];
 
diff --git a/components/pdf_strings.grdp b/components/pdf_strings.grdp
index 19de542..38fc8d2 100644
--- a/components/pdf_strings.grdp
+++ b/components/pdf_strings.grdp
@@ -360,7 +360,7 @@
   </if>
   <if expr="enable_screen_ai_service">
     <message name="IDS_PDF_OCR_FEATURE_ALERT" is_accessibility_with_no_ui="true" desc="Notification of the PDF OCR feature when the user encounters an inaccessible PDF.">
-          This PDF is inaccessible. Couldn't download text extraction files. Please try again later.
+      This PDF is inaccessible. Couldn't download text extraction files. Please try again later.
     </message>
     <message name="IDS_PDF_OCR_IN_PROGRESS" is_accessibility_with_no_ui="true" desc="Notification to inform the user that OCR is in progress.">
       This PDF is inaccessible. Extracting text, powered by Google AI
diff --git a/components/performance_manager/decorators/process_metrics_decorator.cc b/components/performance_manager/decorators/process_metrics_decorator.cc
index 283df3a8d..6a4024c 100644
--- a/components/performance_manager/decorators/process_metrics_decorator.cc
+++ b/components/performance_manager/decorators/process_metrics_decorator.cc
@@ -21,6 +21,7 @@
 #include "components/performance_manager/graph/system_node_impl.h"
 #include "components/performance_manager/graph/worker_node_impl.h"
 #include "components/performance_manager/public/features.h"
+#include "components/performance_manager/public/graph/graph.h"
 #include "components/performance_manager/public/graph/node_data_describer_registry.h"
 #include "components/performance_manager/public/graph/node_data_describer_util.h"
 #include "components/performance_manager/resource_attribution/attribution_impl_helpers.h"
@@ -83,17 +84,14 @@
 void ProcessMetricsDecorator::OnPassedToGraph(Graph* graph) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   CHECK_EQ(state_, State::kStopped);
-  graph_ = graph;
-  graph_->GetNodeDataDescriberRegistry()->RegisterDescriber(
+  graph->GetNodeDataDescriberRegistry()->RegisterDescriber(
       this, "ProcessMetricsDecorator");
 }
 
 void ProcessMetricsDecorator::OnTakenFromGraph(Graph* graph) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  CHECK_EQ(graph, graph_);
   StopTimer();
-  graph_->GetNodeDataDescriberRegistry()->UnregisterDescriber(this);
-  graph_ = nullptr;
+  graph->GetNodeDataDescriberRegistry()->UnregisterDescriber(this);
   CHECK_EQ(state_, State::kStopped);
 }
 
@@ -109,12 +107,6 @@
   return ret;
 }
 
-void ProcessMetricsDecorator::SetGraphForTesting(Graph* graph) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  CHECK_EQ(state_, State::kStopped);
-  graph_ = graph;
-}
-
 bool ProcessMetricsDecorator::IsTimerRunningForTesting() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return refresh_timer_.IsRunning();
@@ -253,7 +245,7 @@
   }
 
   CHECK(process_dumps);
-  auto* graph_impl = GraphImpl::FromGraph(graph_);
+  auto* graph_impl = GraphImpl::FromGraph(GetOwningGraph());
 
   // Refresh the process nodes with the data contained in |process_dumps|.
   // Processes for which we don't receive any data will retain the previously
@@ -284,7 +276,7 @@
         &WorkerNodeImpl::SetPrivateFootprintKbEstimate);
   }
 
-  GraphImpl::FromGraph(graph_)
+  GraphImpl::FromGraph(GetOwningGraph())
       ->GetSystemNodeImpl()
       ->OnProcessMemoryMetricsAvailable();
 }
diff --git a/components/performance_manager/graph/graph.cc b/components/performance_manager/graph/graph.cc
index 24e5b51e..1b45d45 100644
--- a/components/performance_manager/graph/graph.cc
+++ b/components/performance_manager/graph/graph.cc
@@ -4,6 +4,7 @@
 
 #include "components/performance_manager/public/graph/graph.h"
 
+#include "base/check_op.h"
 #include "base/dcheck_is_on.h"
 
 namespace performance_manager {
@@ -12,14 +13,22 @@
 Graph::~Graph() = default;
 
 GraphOwned::GraphOwned() = default;
-GraphOwned::~GraphOwned() = default;
+
+GraphOwned::~GraphOwned() {
+  // Must be removed from the graph before destruction.
+  CHECK_EQ(graph_, nullptr);
+}
 
 void GraphOwned::PassToGraphImpl(Graph* graph) {
+  CHECK_EQ(graph_, nullptr);
+  graph_ = graph;
   OnPassedToGraph(graph);
 }
 
 void GraphOwned::TakeFromGraphImpl(Graph* graph) {
+  CHECK_EQ(graph_, graph);
   OnTakenFromGraph(graph);
+  graph_ = nullptr;
 }
 
 GraphOwnedDefaultImpl::GraphOwnedDefaultImpl() = default;
diff --git a/components/performance_manager/graph/graph_impl_unittest.cc b/components/performance_manager/graph/graph_impl_unittest.cc
index 7356a94..f16886ae 100644
--- a/components/performance_manager/graph/graph_impl_unittest.cc
+++ b/components/performance_manager/graph/graph_impl_unittest.cc
@@ -172,8 +172,14 @@
   ~Foo() override { (*destructor_count_)++; }
 
   // GraphOwned implementation:
-  void OnPassedToGraph(Graph* graph) override { passed_to_called_ = true; }
-  void OnTakenFromGraph(Graph* graph) override { taken_from_called_ = true; }
+  void OnPassedToGraph(Graph* graph) override {
+    EXPECT_EQ(GetOwningGraph(), graph);
+    passed_to_called_ = true;
+  }
+  void OnTakenFromGraph(Graph* graph) override {
+    EXPECT_EQ(GetOwningGraph(), graph);
+    taken_from_called_ = true;
+  }
 
   bool passed_to_called() const { return passed_to_called_; }
   bool taken_from_called() const { return taken_from_called_; }
@@ -198,19 +204,26 @@
   std::unique_ptr<GraphImpl> graph = std::make_unique<GraphImpl>();
   graph->SetUp();
   EXPECT_EQ(0u, graph->GraphOwnedCountForTesting());
+
   EXPECT_FALSE(raw1->passed_to_called());
+  EXPECT_EQ(raw1->GetOwningGraph(), nullptr);
   graph->PassToGraph(std::move(foo1));
   EXPECT_TRUE(raw1->passed_to_called());
+  EXPECT_EQ(raw1->GetOwningGraph(), graph.get());
   EXPECT_EQ(1u, graph->GraphOwnedCountForTesting());
+
   EXPECT_FALSE(raw2->passed_to_called());
+  EXPECT_EQ(raw2->GetOwningGraph(), nullptr);
   graph->PassToGraph(std::move(foo2));
   EXPECT_TRUE(raw2->passed_to_called());
+  EXPECT_EQ(raw2->GetOwningGraph(), graph.get());
   EXPECT_EQ(2u, graph->GraphOwnedCountForTesting());
 
   // Take one back.
   EXPECT_FALSE(raw1->taken_from_called());
   foo1 = graph->TakeFromGraphAs<Foo>(raw1);
   EXPECT_TRUE(raw1->taken_from_called());
+  EXPECT_EQ(raw1->GetOwningGraph(), nullptr);
   EXPECT_EQ(1u, graph->GraphOwnedCountForTesting());
 
   // Destroy that object and expect its destructor to have been invoked.
diff --git a/components/performance_manager/graph/graph_registered_unittest.cc b/components/performance_manager/graph/graph_registered_unittest.cc
index da66da5..2cdc198 100644
--- a/components/performance_manager/graph/graph_registered_unittest.cc
+++ b/components/performance_manager/graph/graph_registered_unittest.cc
@@ -127,34 +127,45 @@
 TEST_F(GraphRegisteredTest, GraphOwnedAndRegistered) {
   // Insertion works.
   EXPECT_FALSE(graph()->GetRegisteredObjectAs<OwnedFoo>());
-  OwnedFoo* foo = graph()->PassToGraph(std::make_unique<OwnedFoo>());
+  auto unique_foo = std::make_unique<OwnedFoo>();
+  EXPECT_EQ(unique_foo->GetOwningGraph(), nullptr);
+  OwnedFoo* foo = graph()->PassToGraph(std::move(unique_foo));
   EXPECT_EQ(foo, graph()->GetRegisteredObjectAs<OwnedFoo>());
+  EXPECT_EQ(foo->GetOwningGraph(), graph());
 
   EXPECT_FALSE(graph()->GetRegisteredObjectAs<OwnedBar>());
-  OwnedBar* bar = graph()->PassToGraph(std::make_unique<OwnedBar>());
+  auto unique_bar = std::make_unique<OwnedBar>();
+  EXPECT_EQ(unique_bar->GetOwningGraph(), nullptr);
+  OwnedBar* bar = graph()->PassToGraph(std::move(unique_bar));
   EXPECT_EQ(bar, graph()->GetRegisteredObjectAs<OwnedBar>());
   EXPECT_TRUE(bar->on_passed_called());
+  EXPECT_EQ(bar->GetOwningGraph(), graph());
 
   // Inserting again fails.
   EXPECT_CHECK_DEATH(graph()->RegisterObject(foo));
   EXPECT_CHECK_DEATH(graph()->PassToGraph(std::make_unique<OwnedFoo>()));
 
   // Unregistering works.
-  std::unique_ptr<OwnedFoo> foo2 = graph()->TakeFromGraphAs<OwnedFoo>(foo);
-  EXPECT_EQ(foo, foo2.get());
+  std::unique_ptr<OwnedFoo> unique_foo2 =
+      graph()->TakeFromGraphAs<OwnedFoo>(foo);
+  EXPECT_EQ(foo, unique_foo2.get());
   EXPECT_EQ(nullptr, graph()->GetRegisteredObjectAs<OwnedFoo>());
+  EXPECT_EQ(foo->GetOwningGraph(), nullptr);
 
-  std::unique_ptr<OwnedBar> bar2 = graph()->TakeFromGraphAs<OwnedBar>(bar);
-  EXPECT_EQ(bar, bar2.get());
+  std::unique_ptr<OwnedBar> unique_bar2 =
+      graph()->TakeFromGraphAs<OwnedBar>(bar);
+  EXPECT_EQ(bar, unique_bar2.get());
   EXPECT_EQ(nullptr, graph()->GetRegisteredObjectAs<OwnedBar>());
   EXPECT_TRUE(bar->on_taken_called());
+  EXPECT_EQ(bar->GetOwningGraph(), nullptr);
 
   // Unregistering again fails.
   EXPECT_CHECK_DEATH(graph()->UnregisterObject(foo));
 
   // Passing back an object that was taken should re-register it.
-  graph()->PassToGraph(std::move(foo2));
+  graph()->PassToGraph(std::move(unique_foo2));
   EXPECT_EQ(foo, graph()->GetRegisteredObjectAs<OwnedFoo>());
+  EXPECT_EQ(foo->GetOwningGraph(), graph());
 
   // At this point the graph can be safely torn down because
   // GraphOwnedAndRegistered objects will be deleted and unregistered.
diff --git a/components/performance_manager/graph/page_node_impl.cc b/components/performance_manager/graph/page_node_impl.cc
index 9f8521c..3b4bdcc 100644
--- a/components/performance_manager/graph/page_node_impl.cc
+++ b/components/performance_manager/graph/page_node_impl.cc
@@ -53,7 +53,6 @@
   DCHECK_EQ(EmbeddingType::kInvalid, embedding_type_);
   DCHECK(!page_load_tracker_data_);
   DCHECK(!site_data_);
-  DCHECK(!tab_connectedness_data_);
   DCHECK(!frozen_frame_data_);
   DCHECK(!page_aggregator_data_);
 }
@@ -503,7 +502,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   page_load_tracker_data_.reset();
   site_data_.reset();
-  tab_connectedness_data_.reset();
   frozen_frame_data_.Reset();
   page_aggregator_data_.Reset();
 }
diff --git a/components/performance_manager/graph/page_node_impl.h b/components/performance_manager/graph/page_node_impl.h
index 294be7d..803d6f31 100644
--- a/components/performance_manager/graph/page_node_impl.h
+++ b/components/performance_manager/graph/page_node_impl.h
@@ -28,7 +28,6 @@
 class PageAggregatorAccess;
 class PageLoadTrackerAccess;
 class SiteDataAccess;
-class TabConnectednessAccess;
 
 // The starting state of various boolean properties of the PageNode.
 enum class PagePropertyFlag {
@@ -176,10 +175,6 @@
       base::PassKey<PageLoadTrackerAccess>) {
     return page_load_tracker_data_;
   }
-  std::unique_ptr<NodeAttachedData>& GetTabConnectednessData(
-      base::PassKey<TabConnectednessAccess>) {
-    return tab_connectedness_data_;
-  }
   FrozenFrameDataStorage& GetFrozenFrameData(
       base::PassKey<FrozenFrameAggregatorAccess>) {
     return frozen_frame_data_;
@@ -385,10 +380,6 @@
   std::unique_ptr<NodeAttachedData> site_data_
       GUARDED_BY_CONTEXT(sequence_checker_);
 
-  // Storage for TabConnectednessDecorator user data.
-  std::unique_ptr<NodeAttachedData> tab_connectedness_data_
-      GUARDED_BY_CONTEXT(sequence_checker_);
-
   // Inline storage for FrozenFrameAggregator user data.
   FrozenFrameDataStorage frozen_frame_data_
       GUARDED_BY_CONTEXT(sequence_checker_);
diff --git a/components/performance_manager/graph/policies/bfcache_policy.cc b/components/performance_manager/graph/policies/bfcache_policy.cc
index e2716a26..af6cd5e25 100644
--- a/components/performance_manager/graph/policies/bfcache_policy.cc
+++ b/components/performance_manager/graph/policies/bfcache_policy.cc
@@ -125,13 +125,11 @@
 
 void BFCachePolicy::OnPassedToGraph(Graph* graph) {
   DCHECK(graph->HasOnlySystemNode());
-  graph_ = graph;
-  graph_->AddSystemNodeObserver(this);
+  graph->AddSystemNodeObserver(this);
 }
 
 void BFCachePolicy::OnTakenFromGraph(Graph* graph) {
-  graph_->RemoveSystemNodeObserver(this);
-  graph_ = nullptr;
+  graph->RemoveSystemNodeObserver(this);
 }
 
 void BFCachePolicy::OnMemoryPressure(MemoryPressureLevel new_level) {
@@ -141,7 +139,7 @@
   }
 
   // Apply the cache limit to all pages.
-  for (const PageNode* page_node : graph_->GetAllPageNodes()) {
+  for (const PageNode* page_node : GetOwningGraph()->GetAllPageNodes()) {
     if (PageMightHaveFramesInBFCache(page_node)) {
       MaybeFlushBFCache(page_node, new_level);
     }
diff --git a/components/performance_manager/graph/policies/bfcache_policy.h b/components/performance_manager/graph/policies/bfcache_policy.h
index 994c106..b877546 100644
--- a/components/performance_manager/graph/policies/bfcache_policy.h
+++ b/components/performance_manager/graph/policies/bfcache_policy.h
@@ -5,7 +5,6 @@
 #ifndef COMPONENTS_PERFORMANCE_MANAGER_GRAPH_POLICIES_BFCACHE_POLICY_H_
 #define COMPONENTS_PERFORMANCE_MANAGER_GRAPH_POLICIES_BFCACHE_POLICY_H_
 
-#include "base/memory/raw_ptr.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "components/performance_manager/public/graph/graph.h"
@@ -40,8 +39,6 @@
 
   // SystemNodeObserver:
   void OnMemoryPressure(MemoryPressureLevel new_level) override;
-
-  raw_ptr<Graph> graph_;
 };
 
 }  // namespace performance_manager::policies
diff --git a/components/performance_manager/metrics/metrics_collector.cc b/components/performance_manager/metrics/metrics_collector.cc
index c6071ea..d0fb5ec7 100644
--- a/components/performance_manager/metrics/metrics_collector.cc
+++ b/components/performance_manager/metrics/metrics_collector.cc
@@ -4,14 +4,21 @@
 
 #include "components/performance_manager/public/metrics/metrics_collector.h"
 
+#include <array>
+#include <optional>
 #include <set>
 #include <string>
 
+#include "base/check_op.h"
+#include "base/containers/contains.h"
+#include "base/functional/bind.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
 #include "base/notreached.h"
+#include "base/numerics/clamped_math.h"
+#include "base/strings/strcat.h"
 #include "base/time/time.h"
+#include "base/timer/timer.h"
 #include "components/performance_manager/public/graph/graph_operations.h"
 #include "components/performance_manager/public/graph/node_attached_data.h"
 #include "content/public/common/process_type.h"
@@ -59,6 +66,19 @@
   }
 }
 
+bool LoadingStateIsQuiescent(PageNode::LoadingState loading_state) {
+  switch (loading_state) {
+    case PageNode::LoadingState::kLoadingNotStarted:
+    case PageNode::LoadingState::kLoadingTimedOut:
+    case PageNode::LoadingState::kLoadedIdle:
+      return true;
+    case PageNode::LoadingState::kLoading:
+    case PageNode::LoadingState::kLoadedBusy:
+      return false;
+  }
+  NOTREACHED_NORETURN();
+}
+
 }  // namespace
 
 class MetricsReportRecordHolder
@@ -91,13 +111,88 @@
 MetricsCollector::~MetricsCollector() = default;
 
 void MetricsCollector::OnPassedToGraph(Graph* graph) {
-  graph_ = graph;
   RegisterObservers(graph);
+
+  loading_page_counts_.fill(0);
+
+  // Unretained is safe because `this` owns the timer.
+  page_loading_state_timer_.Start(
+      FROM_HERE, base::Seconds(30),
+      base::BindRepeating(&MetricsCollector::RecordLoadingAndQuiescentPageCount,
+                          base::Unretained(this)));
 }
 
 void MetricsCollector::OnTakenFromGraph(Graph* graph) {
+  page_loading_state_timer_.Stop();
   UnregisterObservers(graph);
-  graph_ = nullptr;
+}
+
+void MetricsCollector::OnPageNodeAdded(const PageNode* page_node) {
+  // Record the initial state of the page.
+  DCHECK(!base::Contains(mixed_state_pages_, page_node));
+  const auto loading_state =
+      LoadingStateIsQuiescent(page_node->GetLoadingState())
+          ? PageLoadingState::kQuiescent
+          : (page_node->IsVisible() ? PageLoadingState::kLoadingVisible
+                                    : PageLoadingState::kLoadingHidden);
+  UpdateLoadingPageCounts(std::nullopt, loading_state);
+}
+
+void MetricsCollector::OnBeforePageNodeRemoved(const PageNode* page_node) {
+  // Remove the page from all counts.
+  PageLoadingState previous_state;
+  if (LoadingStateIsQuiescent(page_node->GetLoadingState())) {
+    DCHECK(!base::Contains(mixed_state_pages_, page_node));
+    previous_state = PageLoadingState::kQuiescent;
+  } else {
+    size_t erased = mixed_state_pages_.erase(page_node);
+    previous_state =
+        erased ? PageLoadingState::kLoadingMixed
+               : (page_node->IsVisible() ? PageLoadingState::kLoadingVisible
+                                         : PageLoadingState::kLoadingHidden);
+  }
+  UpdateLoadingPageCounts(previous_state, std::nullopt);
+}
+
+void MetricsCollector::OnIsVisibleChanged(const PageNode* page_node) {
+  if (LoadingStateIsQuiescent(page_node->GetLoadingState())) {
+    return;
+  }
+  // Change of visibility makes the state kLoadingMixed if it wasn't already.
+  const auto [_, inserted] = mixed_state_pages_.insert(page_node);
+  if (inserted) {
+    const auto previous_state = page_node->IsVisible()
+                                    ? PageLoadingState::kLoadingHidden
+                                    : PageLoadingState::kLoadingVisible;
+    UpdateLoadingPageCounts(previous_state, PageLoadingState::kLoadingMixed);
+  }
+}
+
+void MetricsCollector::OnLoadingStateChanged(
+    const PageNode* page_node,
+    PageNode::LoadingState previous_state) {
+  const bool is_quiescent =
+      LoadingStateIsQuiescent(page_node->GetLoadingState());
+  const bool was_quiescent = LoadingStateIsQuiescent(previous_state);
+  if (is_quiescent == was_quiescent) {
+    return;
+  }
+  PageLoadingState old_state;
+  PageLoadingState new_state;
+  if (is_quiescent) {
+    size_t erased = mixed_state_pages_.erase(page_node);
+    old_state =
+        erased ? PageLoadingState::kLoadingMixed
+               : (page_node->IsVisible() ? PageLoadingState::kLoadingVisible
+                                         : PageLoadingState::kLoadingHidden);
+    new_state = PageLoadingState::kQuiescent;
+  } else {
+    DCHECK(!base::Contains(mixed_state_pages_, page_node));
+    old_state = PageLoadingState::kQuiescent;
+    new_state = page_node->IsVisible() ? PageLoadingState::kLoadingVisible
+                                       : PageLoadingState::kLoadingHidden;
+  }
+  UpdateLoadingPageCounts(old_state, new_state);
 }
 
 void MetricsCollector::OnUkmSourceIdChanged(const PageNode* page_node) {
@@ -115,7 +210,7 @@
     return;
   }
 
-  for (const PageNode* page : graph_->GetAllPageNodes()) {
+  for (const PageNode* page : GetOwningGraph()->GetAllPageNodes()) {
     if (page != page_node) {
       if (page->GetBrowserContextID() == page_node->GetBrowserContextID() &&
           url::IsSameOriginWith(page->GetMainFrameUrl(),
@@ -133,8 +228,9 @@
 void MetricsCollector::OnProcessLifetimeChange(
     const ProcessNode* process_node) {
   // Ignore process creation.
-  if (!process_node->GetExitStatus().has_value())
+  if (!process_node->GetExitStatus().has_value()) {
     return;
+  }
 
   OnProcessDestroyed(process_node);
 }
@@ -143,8 +239,9 @@
     const ProcessNode* process_node) {
   // If the ProcessNode is destroyed with a valid process handle, consider this
   // the end of the process' life.
-  if (process_node->GetProcess().IsValid())
+  if (process_node->GetProcess().IsValid()) {
     OnProcessDestroyed(process_node);
+  }
 }
 
 // static
@@ -215,4 +312,54 @@
   }
 }
 
+void MetricsCollector::UpdateLoadingPageCounts(
+    std::optional<PageLoadingState> old_state,
+    std::optional<PageLoadingState> new_state) {
+  CHECK(old_state != new_state);
+  if (old_state.has_value()) {
+    loading_page_counts_.at(static_cast<size_t>(old_state.value())) -= 1;
+  }
+  if (new_state.has_value()) {
+    loading_page_counts_.at(static_cast<size_t>(new_state.value())) += 1;
+  }
+}
+
+void MetricsCollector::RecordLoadingAndQuiescentPageCount() const {
+  // Record all loading state counts.
+  constexpr char kLoadingPageCountHistogram[] =
+      "PerformanceManager.LoadingNotQuiescentPageCount";
+  base::ClampedNumeric<size_t> total_count = 0;
+  for (size_t i = 0; i < loading_page_counts_.size(); ++i) {
+    const auto loading_state = static_cast<PageLoadingState>(i);
+    CHECK_LE(loading_state, PageLoadingState::kMaxValue);
+    const auto count = loading_page_counts_.at(i);
+    const char* visibility_string = [loading_state]() -> const char* {
+      switch (loading_state) {
+        case PageLoadingState::kLoadingVisible:
+          return ".Visible";
+        case PageLoadingState::kLoadingHidden:
+          return ".Hidden";
+        case PageLoadingState::kLoadingMixed:
+          return ".MixedVisibility";
+        case PageLoadingState::kQuiescent:
+          // Don't log here, not loading.
+          return nullptr;
+      }
+      NOTREACHED_NORETURN();
+    }();
+    if (visibility_string) {
+      base::UmaHistogramCounts1000(
+          base::StrCat({kLoadingPageCountHistogram, visibility_string}), count);
+      total_count += count;
+    }
+  }
+  base::UmaHistogramCounts1000(
+      base::StrCat({kLoadingPageCountHistogram, ".All"}), total_count);
+
+  // Record quiescent state count.
+  base::UmaHistogramCounts1000("PerformanceManager.QuiescentPageCount",
+                               loading_page_counts_.at(static_cast<size_t>(
+                                   PageLoadingState::kQuiescent)));
+}
+
 }  // namespace performance_manager
diff --git a/components/performance_manager/public/decorators/process_metrics_decorator.h b/components/performance_manager/public/decorators/process_metrics_decorator.h
index 2e6a2e1..81d166b 100644
--- a/components/performance_manager/public/decorators/process_metrics_decorator.h
+++ b/components/performance_manager/public/decorators/process_metrics_decorator.h
@@ -5,12 +5,10 @@
 #ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_DECORATORS_PROCESS_METRICS_DECORATOR_H_
 #define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_DECORATORS_PROCESS_METRICS_DECORATOR_H_
 
-#include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "base/values.h"
-#include "components/performance_manager/public/graph/graph.h"
 #include "components/performance_manager/public/graph/graph_registered.h"
 #include "components/performance_manager/public/graph/node_data_describer.h"
 
@@ -20,6 +18,7 @@
 
 namespace performance_manager {
 
+class Graph;
 class SystemNode;
 
 // The ProcessMetricsDecorator is responsible for adorning process nodes with
@@ -65,7 +64,6 @@
   base::Value::Dict DescribeSystemNodeData(
       const SystemNode* node) const override;
 
-  void SetGraphForTesting(Graph* graph);
   bool IsTimerRunningForTesting() const;
   base::TimeDelta GetTimerDelayForTesting() const;
 
@@ -131,9 +129,6 @@
   // The timer responsible for refreshing the metrics.
   base::OneShotTimer refresh_timer_ GUARDED_BY_CONTEXT(sequence_checker_);
 
-  // The Graph instance owning this decorator.
-  raw_ptr<Graph> graph_ GUARDED_BY_CONTEXT(sequence_checker_);
-
   // The number of clients currently interested by the metrics tracked by this
   // class.
   size_t metrics_interest_token_count_ GUARDED_BY_CONTEXT(sequence_checker_) =
diff --git a/components/performance_manager/public/graph/graph.h b/components/performance_manager/public/graph/graph.h
index 97352643..b762fbc 100644
--- a/components/performance_manager/public/graph/graph.h
+++ b/components/performance_manager/public/graph/graph.h
@@ -11,6 +11,7 @@
 
 #include "base/dcheck_is_on.h"
 #include "base/memory/ptr_util.h"
+#include "base/memory/raw_ptr.h"
 #include "base/observer_list_types.h"
 #include "components/performance_manager/public/graph/node_set_view.h"
 
@@ -183,6 +184,11 @@
   // call to Graph::TakeFromGraph, or prior to the Graph being destroyed.
   virtual void OnTakenFromGraph(Graph* graph) = 0;
 
+  // Returns a pointer to the owning Graph. The will return nullptr before
+  // OnPassedToGraph() and after OnTakenFromGraph(), and a valid pointer at all
+  // other times.
+  Graph* GetOwningGraph() const { return graph_.get(); }
+
  private:
   // GraphImpl is allowed to call PassToGraphImpl and TakeFromGraphImpl.
   friend class GraphImpl;
@@ -198,6 +204,9 @@
   // without having to remember to call the inherited methods.
   virtual void PassToGraphImpl(Graph* graph);
   virtual void TakeFromGraphImpl(Graph* graph);
+
+  // Pointer back to the owning graph.
+  raw_ptr<Graph> graph_ = nullptr;
 };
 
 // A default implementation of GraphOwned.
diff --git a/components/performance_manager/public/metrics/metrics_collector.h b/components/performance_manager/public/metrics/metrics_collector.h
index 3264c04f..a9e83de 100644
--- a/components/performance_manager/public/metrics/metrics_collector.h
+++ b/components/performance_manager/public/metrics/metrics_collector.h
@@ -5,8 +5,13 @@
 #ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_METRICS_METRICS_COLLECTOR_H_
 #define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_METRICS_METRICS_COLLECTOR_H_
 
-#include "base/memory/raw_ptr.h"
+#include <array>
+#include <optional>
+#include <set>
+
+#include "base/numerics/clamped_math.h"
 #include "base/time/time.h"
+#include "base/timer/timer.h"
 #include "components/performance_manager/public/graph/frame_node.h"
 #include "components/performance_manager/public/graph/graph.h"
 #include "components/performance_manager/public/graph/page_node.h"
@@ -37,6 +42,11 @@
   void OnTakenFromGraph(Graph* graph) override;
 
   // PageNodeObserver implementation:
+  void OnPageNodeAdded(const PageNode* page_node) override;
+  void OnBeforePageNodeRemoved(const PageNode* page_node) override;
+  void OnIsVisibleChanged(const PageNode* page_node) override;
+  void OnLoadingStateChanged(const PageNode* page_node,
+                             PageNode::LoadingState previous_state) override;
   void OnUkmSourceIdChanged(const PageNode* page_node) override;
   void OnMainFrameDocumentChanged(const PageNode* page_node) override;
 
@@ -62,6 +72,20 @@
   static MetricsReportRecord* GetMetricsReportRecord(const PageNode* page_node);
   static UkmCollectionState* GetUkmCollectionState(const PageNode* page_node);
 
+  enum class PageLoadingState : size_t {
+    // Loading, visible for the whole load.
+    kLoadingVisible = 0,
+    // Loading, hidden for the whole load.
+    kLoadingHidden,
+    // Loading, mix of visible and hidden.
+    kLoadingMixed,
+    // Not loading or reached quiescence after load.
+    kQuiescent,
+    kMaxValue = kQuiescent,
+  };
+  static constexpr size_t kNumLoadingStates =
+      static_cast<size_t>(PageLoadingState::kMaxValue) + 1;
+
   // (Un)registers the various node observer flavors of this object with the
   // graph. These are invoked by OnPassedToGraph and OnTakenFromGraph, but
   // hoisted to their own functions for testing.
@@ -74,8 +98,23 @@
 
   void OnProcessDestroyed(const ProcessNode* process_node);
 
-  // The graph to which this object belongs.
-  raw_ptr<Graph> graph_ = nullptr;
+  // Decrements the count for `old_state` (which should be nullopt for a new
+  // page with no previous state), and increments the count for `new_state`
+  // (nullopt for pages being destroyed).
+  void UpdateLoadingPageCounts(std::optional<PageLoadingState> old_state,
+                               std::optional<PageLoadingState> new_state);
+  void RecordLoadingAndQuiescentPageCount() const;
+
+  // Timer used to schedule QuiescentPageCount metrics.
+  base::RepeatingTimer page_loading_state_timer_;
+
+  // Count of PageNodes, split by loading state.
+  std::array<base::ClampedNumeric<size_t>, kNumLoadingStates>
+      loading_page_counts_;
+
+  // Nodes in visibility state kMixed, since this can't be calculated from the
+  // PageNode alone.
+  std::set<const PageNode*> mixed_state_pages_;
 };
 
 }  // namespace performance_manager
diff --git a/components/performance_manager/resource_attribution/query_scheduler.cc b/components/performance_manager/resource_attribution/query_scheduler.cc
index 1a4f21c..86eff28c 100644
--- a/components/performance_manager/resource_attribution/query_scheduler.cc
+++ b/components/performance_manager/resource_attribution/query_scheduler.cc
@@ -14,6 +14,7 @@
 #include "base/containers/enum_set.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
+#include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/no_destructor.h"
 #include "base/notreached.h"
@@ -22,6 +23,7 @@
 #include "base/types/optional_util.h"
 #include "base/types/pass_key.h"
 #include "base/types/variant_util.h"
+#include "components/performance_manager/public/graph/graph.h"
 #include "components/performance_manager/public/graph/node_data_describer_registry.h"
 #include "components/performance_manager/public/performance_manager.h"
 #include "components/performance_manager/public/resource_attribution/resource_types.h"
@@ -239,8 +241,6 @@
 
 void QueryScheduler::OnPassedToGraph(Graph* graph) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  CHECK_EQ(graph_, nullptr);
-  graph_ = graph;
   memory_provider_.emplace(graph);
   graph->GetNodeDataDescriberRegistry()->RegisterDescriber(
       base::OptionalToPtr(memory_provider_), "ResourceAttr.Memory");
@@ -251,8 +251,6 @@
 
 void QueryScheduler::OnTakenFromGraph(Graph* graph) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  CHECK_EQ(graph_, graph);
-  graph_ = nullptr;
   SchedulerTaskRunner::GetInstance()->OnSchedulerTakenFromGraph(graph);
   graph->GetNodeDataDescriberRegistry()->UnregisterDescriber(&cpu_monitor_);
   if (cpu_query_count_ > 0) {
@@ -292,19 +290,17 @@
 
 void QueryScheduler::AddCPUQuery() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  CHECK_NE(graph_, nullptr);
   cpu_query_count_ += 1;
   // Check for overflow.
   CHECK_GT(cpu_query_count_, 0U);
   if (cpu_query_count_ == 1) {
     CHECK(!cpu_monitor_.IsMonitoring());
-    cpu_monitor_.StartMonitoring(graph_);
+    cpu_monitor_.StartMonitoring(GetOwningGraph());
   }
 }
 
 void QueryScheduler::RemoveCPUQuery() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  CHECK_NE(graph_, nullptr);
   CHECK_GE(cpu_query_count_, 1U);
   cpu_query_count_ -= 1;
   if (cpu_query_count_ == 0) {
@@ -315,7 +311,6 @@
 
 void QueryScheduler::AddMemoryQuery() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  CHECK_NE(graph_, nullptr);
   memory_query_count_ += 1;
   // Check for overflow.
   CHECK_GT(memory_query_count_, 0U);
@@ -323,7 +318,6 @@
 
 void QueryScheduler::RemoveMemoryQuery() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  CHECK_NE(graph_, nullptr);
   CHECK_GE(memory_query_count_, 1U);
   memory_query_count_ -= 1;
 }
diff --git a/components/performance_manager/resource_attribution/query_scheduler.h b/components/performance_manager/resource_attribution/query_scheduler.h
index 36c99fb8..111e540 100644
--- a/components/performance_manager/resource_attribution/query_scheduler.h
+++ b/components/performance_manager/resource_attribution/query_scheduler.h
@@ -11,10 +11,8 @@
 
 #include "base/functional/callback_forward.h"
 #include "base/location.h"
-#include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
-#include "components/performance_manager/public/graph/graph.h"
 #include "components/performance_manager/public/graph/graph_registered.h"
 #include "components/performance_manager/public/resource_attribution/query_results.h"
 #include "components/performance_manager/public/resource_attribution/resource_contexts.h"
@@ -23,6 +21,10 @@
 #include "components/performance_manager/resource_attribution/memory_measurement_provider.h"
 #include "components/performance_manager/resource_attribution/performance_manager_aliases.h"
 
+namespace performance_manager {
+class Graph;
+}
+
 namespace resource_attribution {
 class ContextCollection;
 }
@@ -109,8 +111,6 @@
 
   SEQUENCE_CHECKER(sequence_checker_);
 
-  raw_ptr<Graph> graph_ GUARDED_BY_CONTEXT(sequence_checker_);
-
   // CPU measurement machinery.
   CPUMeasurementMonitor cpu_monitor_ GUARDED_BY_CONTEXT(sequence_checker_);
   uint32_t cpu_query_count_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
diff --git a/components/performance_manager/v8_memory/v8_detailed_memory_decorator.cc b/components/performance_manager/v8_memory/v8_detailed_memory_decorator.cc
index 5cfb6e0..5a0aabe 100644
--- a/components/performance_manager/v8_memory/v8_detailed_memory_decorator.cc
+++ b/components/performance_manager/v8_memory/v8_detailed_memory_decorator.cc
@@ -20,6 +20,7 @@
 #include "components/performance_manager/public/execution_context/execution_context.h"
 #include "components/performance_manager/public/execution_context/execution_context_attached_data.h"
 #include "components/performance_manager/public/graph/frame_node.h"
+#include "components/performance_manager/public/graph/graph.h"
 #include "components/performance_manager/public/graph/node_attached_data.h"
 #include "components/performance_manager/public/graph/node_data_describer_registry.h"
 #include "components/performance_manager/public/graph/worker_node.h"
@@ -665,9 +666,6 @@
 
 void V8DetailedMemoryDecorator::OnPassedToGraph(Graph* graph) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK_EQ(nullptr, graph_);
-  graph_ = graph;
-
   // Iterate over the existing process nodes to put them under observation.
   for (const ProcessNode* process_node : graph->GetAllProcessNodes()) {
     OnProcessNodeAdded(process_node);
@@ -680,14 +678,11 @@
 
 void V8DetailedMemoryDecorator::OnTakenFromGraph(Graph* graph) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK_EQ(graph, graph_);
-
   ApplyToAllRequestQueues(&V8DetailedMemoryRequestQueue::OnOwnerUnregistered);
   UpdateProcessMeasurementSchedules();
 
   graph->GetNodeDataDescriberRegistry()->UnregisterDescriber(this);
   graph->RemoveProcessNodeObserver(this);
-  graph_ = nullptr;
 }
 
 void V8DetailedMemoryDecorator::OnProcessNodeAdded(
@@ -794,17 +789,16 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   func(measurement_requests_.get());
   NodeAttachedProcessData::ApplyToAllRenderers(
-      graph_, [func](NodeAttachedProcessData* process_data) {
+      GetOwningGraph(), [func](NodeAttachedProcessData* process_data) {
         func(&process_data->process_measurement_requests());
       });
 }
 
 void V8DetailedMemoryDecorator::UpdateProcessMeasurementSchedules() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(graph_);
   measurement_requests_->Validate();
   NodeAttachedProcessData::ApplyToAllRenderers(
-      graph_, &NodeAttachedProcessData::ScheduleNextMeasurement);
+      GetOwningGraph(), &NodeAttachedProcessData::ScheduleNextMeasurement);
 }
 
 void V8DetailedMemoryDecorator::NotifyObserversOnMeasurementAvailable(
diff --git a/components/performance_manager/v8_memory/v8_detailed_memory_decorator.h b/components/performance_manager/v8_memory/v8_detailed_memory_decorator.h
index 68e1bbb..fe822e8 100644
--- a/components/performance_manager/v8_memory/v8_detailed_memory_decorator.h
+++ b/components/performance_manager/v8_memory/v8_detailed_memory_decorator.h
@@ -9,10 +9,8 @@
 
 #include "base/functional/callback_forward.h"
 #include "base/functional/function_ref.h"
-#include "base/memory/raw_ptr.h"
 #include "base/sequence_checker.h"
 #include "base/types/pass_key.h"
-#include "components/performance_manager/public/graph/graph.h"
 #include "components/performance_manager/public/graph/graph_registered.h"
 #include "components/performance_manager/public/graph/node_data_describer.h"
 #include "components/performance_manager/public/graph/process_node.h"
@@ -23,6 +21,7 @@
 namespace performance_manager {
 
 class FrameNode;
+class Graph;
 
 namespace v8_memory {
 
@@ -106,8 +105,6 @@
 
   void UpdateProcessMeasurementSchedules() const;
 
-  raw_ptr<Graph> graph_ GUARDED_BY_CONTEXT(sequence_checker_) = nullptr;
-
   std::unique_ptr<V8DetailedMemoryRequestQueue> measurement_requests_
       GUARDED_BY_CONTEXT(sequence_checker_);
 
diff --git a/components/plus_addresses/resources/internal b/components/plus_addresses/resources/internal
index e59966e..a91fba0 160000
--- a/components/plus_addresses/resources/internal
+++ b/components/plus_addresses/resources/internal
@@ -1 +1 @@
-Subproject commit e59966e228d0bf01a05ed48efb828a2900d639d0
+Subproject commit a91fba0741b48a257081ec7f3ca3ec0f72101b4d
diff --git a/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc b/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc
index 3ee417a2..bbc5141 100644
--- a/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc
+++ b/components/safe_browsing/android/safe_browsing_api_handler_bridge.cc
@@ -739,9 +739,14 @@
   base::UmaHistogramBoolean("SafeBrowsing.GmsSafeBrowsingApi.IsAvailable" +
                                 GetSafeBrowsingJavaProtocolUmaSuffix(protocol),
                             is_safe_browsing_api_available_);
+
   if (!is_safe_browsing_api_available_) {
-    // Fall back to SafetyNet if SafeBrowsing API is not available.
-    StartUrlCheckBySafetyNet(std::move(callback), url, threat_types);
+    // Mark all requests as safe. Only users who have an old, broken GMSCore or
+    // have sideloaded Chrome w/o PlayStore should land here.
+    content::GetUIThreadTaskRunner({})->PostTask(
+        FROM_HERE,
+        base::BindOnce(std::move(*callback), SBThreatType::SB_THREAT_TYPE_SAFE,
+                       ThreatMetadata()));
     return;
   }
 
diff --git a/components/safe_browsing/android/safe_browsing_api_handler_bridge_unittest.cc b/components/safe_browsing/android/safe_browsing_api_handler_bridge_unittest.cc
index b0fd8c0..9dfeaf2 100644
--- a/components/safe_browsing/android/safe_browsing_api_handler_bridge_unittest.cc
+++ b/components/safe_browsing/android/safe_browsing_api_handler_bridge_unittest.cc
@@ -708,8 +708,9 @@
 }
 
 TEST_F(SafeBrowsingApiHandlerBridgeTest,
-       HashRealTimeUrlCheck_NonRecoverableLookupResultAndFallback) {
+       HashRealTimeUrlCheck_NonRecoverableLookupResult) {
   GURL url1("https://example1.com");
+  // FAILURE_API_UNSUPPORTED is a non-recoverable error.
   AddSafeBrowsingResponse(
       url1, SafeBrowsingApiLookupResult::FAILURE_API_UNSUPPORTED,
       SafeBrowsingJavaThreatType::POTENTIALLY_HARMFUL_APPLICATION, {},
@@ -728,20 +729,14 @@
       /*expected_count=*/1);
 
   GURL url2("https://example2.com");
-  std::string metadata = "{\"matches\":[{\"threat_type\":\"3\"}]}";
-  AddSafetyNetBlocklistResponse(url2, metadata,
-                                GetAllSafetyNetThreatsOfInterest());
 
-  // The response should come from SafetyNet because FAILURE_API_UNSUPPORTED is
-  // a non-recoverable failure.
   RunHashRealTimeUrlCheck(url2,
                           /*threat_types=*/GetAllThreatTypes(),
-                          /*expected_threat_type=*/SB_THREAT_TYPE_URL_UNWANTED);
+                          /*expected_threat_type=*/SB_THREAT_TYPE_SAFE);
   histogram_tester_.ExpectBucketCount(
       "SafeBrowsing.GmsSafeBrowsingApi.IsAvailable", /*sample=*/false,
       /*expected_count=*/1);
-  // No additional histogram because the check doesn't go through SafeBrowsing
-  // API.
+  // No additional histogram because SafeBrowsing API is not available.
   histogram_tester_.ExpectTotalCount(
       "SafeBrowsing.GmsSafeBrowsingApi.JavaValidationResult",
       /*expected_count=*/1);
diff --git a/components/safe_browsing/content/browser/BUILD.gn b/components/safe_browsing/content/browser/BUILD.gn
index 5a45f14..e538086 100644
--- a/components/safe_browsing/content/browser/BUILD.gn
+++ b/components/safe_browsing/content/browser/BUILD.gn
@@ -99,8 +99,6 @@
     "unsafe_resource_util.h",
     "url_checker_on_sb.cc",
     "url_checker_on_sb.h",
-    "web_api_handshake_checker.cc",
-    "web_api_handshake_checker.h",
     "web_contents_key.cc",
     "web_contents_key.h",
   ]
@@ -168,7 +166,6 @@
     "client_report_util_unittest.cc",
     "client_side_detection_feature_cache_unittest.cc",
     "client_side_phishing_model_unittest.cc",
-    "web_api_handshake_checker_unittest.cc",
   ]
 
   deps = [
diff --git a/components/safe_browsing/content/browser/base_ui_manager.h b/components/safe_browsing/content/browser/base_ui_manager.h
index a43a5f52..6c9ce65c 100644
--- a/components/safe_browsing/content/browser/base_ui_manager.h
+++ b/components/safe_browsing/content/browser/base_ui_manager.h
@@ -49,7 +49,7 @@
   // With committed interstitials:
   // -For pre-commit navigations this will only cancel the load, the
   // interstitial will then be shown from a navigation throttle.
-  // -For post-commit this will cancel the load, then call
+  // -For post-commit navigations this will cancel the load, then call
   // LoadPostCommitErrorPage, which will show the interstitial.
   virtual void DisplayBlockingPage(const UnsafeResource& resource);
 
diff --git a/components/safe_browsing/content/browser/browser_url_loader_throttle_unittest.cc b/components/safe_browsing/content/browser/browser_url_loader_throttle_unittest.cc
index 2f02c60f..d1b6ecb 100644
--- a/components/safe_browsing/content/browser/browser_url_loader_throttle_unittest.cc
+++ b/components/safe_browsing/content/browser/browser_url_loader_throttle_unittest.cc
@@ -45,14 +45,13 @@
 
   MOCK_METHOD1(MaybeDestroyNoStatePrefetchContents,
                void(base::OnceCallback<content::WebContents*()>));
-  MOCK_METHOD5(StartDisplayingBlockingPageHelper,
+  MOCK_METHOD4(StartDisplayingBlockingPageHelper,
                void(const security_interstitials::UnsafeResource&,
                     const std::string&,
                     const net::HttpRequestHeaders&,
-                    bool,
                     bool));
-  MOCK_METHOD2(StartObservingInteractionsForDelayedBlockingPageHelper,
-               void(const security_interstitials::UnsafeResource&, bool));
+  MOCK_METHOD1(StartObservingInteractionsForDelayedBlockingPageHelper,
+               void(const security_interstitials::UnsafeResource&));
   MOCK_METHOD1(NotifySuspiciousSiteDetected,
                void(const base::RepeatingCallback<content::WebContents*()>&));
   MOCK_METHOD0(GetUIManager, BaseUIManager*());
diff --git a/components/safe_browsing/content/browser/web_api_handshake_checker.cc b/components/safe_browsing/content/browser/web_api_handshake_checker.cc
deleted file mode 100644
index cce29ef..0000000
--- a/components/safe_browsing/content/browser/web_api_handshake_checker.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2021 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/safe_browsing/content/browser/web_api_handshake_checker.h"
-
-#include "base/memory/weak_ptr.h"
-#include "base/metrics/histogram_functions.h"
-#include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h"
-#include "components/safe_browsing/core/browser/safe_browsing_url_checker_impl.h"
-#include "components/safe_browsing/core/browser/url_checker_delegate.h"
-#include "components/safe_browsing/core/common/features.h"
-#include "components/safe_browsing/core/common/scheme_logger.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/web_contents.h"
-#include "net/http/http_request_headers.h"
-
-namespace safe_browsing {
-
-class WebApiHandshakeChecker::CheckerOnSB {
- public:
-  CheckerOnSB(base::WeakPtr<WebApiHandshakeChecker> handshake_checker,
-              GetDelegateCallback delegate_getter,
-              const GetWebContentsCallback& web_contents_getter,
-              int frame_tree_node_id)
-      : handshake_checker_(std::move(handshake_checker)),
-        delegate_getter_(std::move(delegate_getter)),
-        web_contents_getter_(web_contents_getter),
-        frame_tree_node_id_(frame_tree_node_id) {
-    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-    DCHECK(handshake_checker_);
-    DCHECK(delegate_getter_);
-    DCHECK(web_contents_getter_);
-  }
-
-  void Check(const GURL& url) {
-    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-    DCHECK(delegate_getter_);
-    DCHECK(web_contents_getter_);
-
-    scoped_refptr<UrlCheckerDelegate> url_checker_delegate =
-        std::move(delegate_getter_).Run();
-    bool skip_checks =
-        !url_checker_delegate ||
-        url_checker_delegate->ShouldSkipRequestCheck(
-            url, frame_tree_node_id_,
-            /*render_process_id=*/content::ChildProcessHost::kInvalidUniqueID,
-            /*render_frame_token=*/std::nullopt,
-            /*originated_from_service_worker=*/false);
-    if (skip_checks) {
-      OnCompleteCheckInternal(/*proceed=*/true);
-      return;
-    }
-
-    scheme_logger::LogScheme(url,
-                             "SafeBrowsing.WebApiHandshakeCheck.UrlScheme");
-    // If |kSafeBrowsingSkipSubresources2| is enabled, skip Safe Browsing checks
-    // for WebTransport.
-    if (base::FeatureList::IsEnabled(kSafeBrowsingSkipSubresources2)) {
-      base::UmaHistogramBoolean("SafeBrowsing.WebApiHandshakeCheck.Skipped",
-                                true);
-      OnCompleteCheckInternal(/*proceed=*/true);
-      return;
-    }
-
-    base::UmaHistogramBoolean("SafeBrowsing.WebApiHandshakeCheck.Skipped",
-                              false);
-    url_checker_ = std::make_unique<SafeBrowsingUrlCheckerImpl>(
-        net::HttpRequestHeaders(), /*load_flags=*/0, /*has_user_gesture=*/false,
-        url_checker_delegate, web_contents_getter_, /*weak_web_state=*/nullptr,
-        /*render_process_id=*/content::ChildProcessHost::kInvalidUniqueID,
-        /*render_frame_token=*/std::nullopt, frame_tree_node_id_,
-        /*navigation_id=*/std::nullopt,
-        /*url_real_time_lookup_enabled=*/false,
-        /*can_check_db=*/true, /*can_check_high_confidence_allowlist=*/true,
-        /*url_lookup_service_metric_suffix=*/".None",
-        content::GetUIThreadTaskRunner({}),
-        /*url_lookup_service=*/nullptr,
-        /*hash_realtime_service_on_ui=*/nullptr,
-        /*hash_realtime_selection=*/
-        hash_realtime_utils::HashRealTimeSelection::kNone,
-        /*is_async_check=*/false, SessionID::InvalidValue());
-    url_checker_->CheckUrl(
-        url, "GET",
-        base::BindOnce(&WebApiHandshakeChecker::CheckerOnSB::OnCheckUrlResult,
-                       base::Unretained(this)));
-  }
-
-  base::WeakPtr<CheckerOnSB> AsWeakPtr() { return weak_factory_.GetWeakPtr(); }
-
- private:
-  // See comments in BrowserUrlLoaderThrottle::OnCheckUrlResult().
-  void OnCheckUrlResult(
-      SafeBrowsingUrlCheckerImpl::NativeUrlCheckNotifier* slow_check_notifier,
-      bool proceed,
-      bool showed_interstitial,
-      bool has_post_commit_interstitial_skipped,
-      SafeBrowsingUrlCheckerImpl::PerformedCheck performed_check) {
-    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-    if (!slow_check_notifier) {
-      OnCompleteCheckInternal(proceed);
-      return;
-    }
-
-    *slow_check_notifier =
-        base::BindOnce(&WebApiHandshakeChecker::CheckerOnSB::OnCompleteCheck,
-                       base::Unretained(this));
-  }
-
-  void OnCompleteCheck(
-      bool proceed,
-      bool showed_interstitial,
-      bool has_post_commit_interstitial_skipped,
-      SafeBrowsingUrlCheckerImpl::PerformedCheck performed_check) {
-    OnCompleteCheckInternal(proceed);
-  }
-
-  void OnCompleteCheckInternal(bool proceed) {
-    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-    handshake_checker_->OnCompleteCheck(proceed);
-  }
-
-  base::WeakPtr<WebApiHandshakeChecker> handshake_checker_;
-  GetDelegateCallback delegate_getter_;
-  GetWebContentsCallback web_contents_getter_;
-  const int frame_tree_node_id_;
-  std::unique_ptr<SafeBrowsingUrlCheckerImpl> url_checker_;
-  base::WeakPtrFactory<CheckerOnSB> weak_factory_{this};
-};
-
-WebApiHandshakeChecker::WebApiHandshakeChecker(
-    GetDelegateCallback delegate_getter,
-    const GetWebContentsCallback& web_contents_getter,
-    int frame_tree_node_id) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  sb_checker_ = std::make_unique<CheckerOnSB>(
-      weak_factory_.GetWeakPtr(), std::move(delegate_getter),
-      web_contents_getter, frame_tree_node_id);
-}
-
-WebApiHandshakeChecker::~WebApiHandshakeChecker() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-}
-
-void WebApiHandshakeChecker::Check(const GURL& url, CheckCallback callback) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK(!check_callback_);
-  check_callback_ = std::move(callback);
-  sb_checker_->Check(url);
-}
-
-void WebApiHandshakeChecker::OnCompleteCheck(bool proceed) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DCHECK(check_callback_);
-
-  CheckResult result = proceed ? CheckResult::kProceed : CheckResult::kBlocked;
-  std::move(check_callback_).Run(result);
-}
-
-}  // namespace safe_browsing
diff --git a/components/safe_browsing/content/browser/web_api_handshake_checker.h b/components/safe_browsing/content/browser/web_api_handshake_checker.h
deleted file mode 100644
index c8031ac..0000000
--- a/components/safe_browsing/content/browser/web_api_handshake_checker.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2021 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_WEB_API_HANDSHAKE_CHECKER_H_
-#define COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_WEB_API_HANDSHAKE_CHECKER_H_
-
-#include <memory>
-
-#include "base/functional/callback.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/memory/weak_ptr.h"
-#include "url/gurl.h"
-
-namespace content {
-class WebContents;
-}  // namespace content
-
-namespace safe_browsing {
-
-class UrlCheckerDelegate;
-
-// Performs SafeBrowsing checks for Web API handshakes such as WebTransport.
-class WebApiHandshakeChecker {
- public:
-  using GetDelegateCallback =
-      base::OnceCallback<scoped_refptr<UrlCheckerDelegate>()>;
-  using GetWebContentsCallback =
-      base::RepeatingCallback<content::WebContents*()>;
-
-  enum class CheckResult {
-    kProceed,
-    kBlocked,
-  };
-  using CheckCallback = base::OnceCallback<void(CheckResult)>;
-
-  WebApiHandshakeChecker(GetDelegateCallback delegate_getter,
-                         const GetWebContentsCallback& web_contents_getter,
-                         int frame_tree_node_id);
-  ~WebApiHandshakeChecker();
-
-  WebApiHandshakeChecker(const WebApiHandshakeChecker&) = delete;
-  WebApiHandshakeChecker& operator=(const WebApiHandshakeChecker&) = delete;
-  WebApiHandshakeChecker(WebApiHandshakeChecker&&) = delete;
-  WebApiHandshakeChecker& operator=(WebApiHandshakeChecker&&) = delete;
-
-  void Check(const GURL& url, CheckCallback callback);
-
- private:
-  // Performs checks on the SB thread by using SafeBrowsingUrlCheckerImpl, which
-  // must live on the SB thread.
-  class CheckerOnSB;
-
-  void OnCompleteCheck(bool proceed);
-
-  std::unique_ptr<CheckerOnSB> sb_checker_;
-  CheckCallback check_callback_;
-
-  base::WeakPtrFactory<WebApiHandshakeChecker> weak_factory_{this};
-};
-
-}  // namespace safe_browsing
-
-#endif  // COMPONENTS_SAFE_BROWSING_CONTENT_BROWSER_WEB_API_HANDSHAKE_CHECKER_H_
diff --git a/components/safe_browsing/content/browser/web_api_handshake_checker_unittest.cc b/components/safe_browsing/content/browser/web_api_handshake_checker_unittest.cc
deleted file mode 100644
index 705af2d4..0000000
--- a/components/safe_browsing/content/browser/web_api_handshake_checker_unittest.cc
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2021 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/safe_browsing/content/browser/web_api_handshake_checker.h"
-
-#include "base/memory/scoped_refptr.h"
-#include "base/test/bind.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_feature_list.h"
-#include "components/safe_browsing/core/browser/db/fake_database_manager.h"
-#include "components/safe_browsing/core/browser/url_checker_delegate.h"
-#include "components/safe_browsing/core/common/features.h"
-#include "components/security_interstitials/core/unsafe_resource.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/test/browser_task_environment.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace safe_browsing {
-
-class FakeUrlCheckerDelegate : public UrlCheckerDelegate {
- public:
-  explicit FakeUrlCheckerDelegate(
-      scoped_refptr<SafeBrowsingDatabaseManager> database_manager)
-      : database_manager_(database_manager),
-        threat_types_(SBThreatTypeSet(
-            {safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING})) {}
-
-  // UrlCheckerDelegate overrides:
-  void MaybeDestroyNoStatePrefetchContents(
-      base::OnceCallback<content::WebContents*()> web_contents_getter)
-      override {}
-
-  void StartDisplayingBlockingPageHelper(
-      const security_interstitials::UnsafeResource& resource,
-      const std::string& method,
-      const net::HttpRequestHeaders& headers,
-      bool is_main_frame,
-      bool has_user_gesture) override {
-    security_interstitials::UnsafeResource::UrlCheckResult result(
-        /*proceed=*/false, /*showed_interstitial=*/false,
-        /*has_post_commit_interstitial_skipped=*/false);
-    resource.callback.Run(result);
-  }
-
-  void StartObservingInteractionsForDelayedBlockingPageHelper(
-      const security_interstitials::UnsafeResource& resource,
-      bool is_main_frame) override {}
-
-  bool IsUrlAllowlisted(const GURL& url) override { return false; }
-
-  void SetPolicyAllowlistDomains(
-      const std::vector<std::string>& allowlist_domains) override {}
-
-  bool ShouldSkipRequestCheck(
-      const GURL& original_url,
-      int frame_tree_node_id,
-      int render_process_id,
-      base::optional_ref<const base::UnguessableToken> render_frame_token,
-      bool originated_from_service_worker) override {
-    return false;
-  }
-
-  void NotifySuspiciousSiteDetected(
-      const base::RepeatingCallback<content::WebContents*()>&
-          web_contents_getter) override {}
-
-  const SBThreatTypeSet& GetThreatTypes() override { return threat_types_; }
-
-  SafeBrowsingDatabaseManager* GetDatabaseManager() override {
-    return database_manager_.get();
-  }
-
-  BaseUIManager* GetUIManager() override { return nullptr; }
-
- protected:
-  friend class base::RefCountedThreadSafe<FakeUrlCheckerDelegate>;
-  ~FakeUrlCheckerDelegate() override = default;
-
- private:
-  scoped_refptr<SafeBrowsingDatabaseManager> database_manager_;
-  SBThreatTypeSet threat_types_;
-};
-
-class WebApiHandshakeCheckerTest : public testing::Test,
-                                   public testing::WithParamInterface<bool> {
- protected:
-  void SetUp() override {
-    if (GetParam()) {
-      feature_list_.InitAndEnableFeature(kSafeBrowsingSkipSubresources2);
-    } else {
-      feature_list_.InitAndDisableFeature(kSafeBrowsingSkipSubresources2);
-    }
-    database_manager_ = base::MakeRefCounted<FakeSafeBrowsingDatabaseManager>(
-        content::GetUIThreadTaskRunner({}), content::GetIOThreadTaskRunner({}));
-    delegate_ = base::MakeRefCounted<FakeUrlCheckerDelegate>(database_manager_);
-    handshake_checker_ = std::make_unique<WebApiHandshakeChecker>(
-        base::BindOnce(&WebApiHandshakeCheckerTest::GetDelegate,
-                       base::Unretained(this)),
-        base::BindRepeating(&WebApiHandshakeCheckerTest::GetWebContents,
-                            base::Unretained(this)),
-        /*frame_tree_node_id=*/-1);
-  }
-
-  FakeSafeBrowsingDatabaseManager* database_manager() {
-    return database_manager_.get();
-  }
-
-  WebApiHandshakeChecker::CheckResult Check(const GURL& url) {
-    WebApiHandshakeChecker::CheckResult out;
-    base::RunLoop loop;
-    handshake_checker_->Check(
-        url, base::BindLambdaForTesting(
-                 [&](WebApiHandshakeChecker::CheckResult result) {
-                   out = result;
-                   loop.Quit();
-                 }));
-    loop.Run();
-    return out;
-  }
-
- private:
-  scoped_refptr<UrlCheckerDelegate> GetDelegate() { return delegate_; }
-
-  content::WebContents* GetWebContents() { return nullptr; }
-
-  content::BrowserTaskEnvironment task_environment_;
-  scoped_refptr<FakeSafeBrowsingDatabaseManager> database_manager_;
-  scoped_refptr<FakeUrlCheckerDelegate> delegate_;
-  std::unique_ptr<WebApiHandshakeChecker> handshake_checker_;
-  base::test::ScopedFeatureList feature_list_;
-};
-
-INSTANTIATE_TEST_SUITE_P(All, WebApiHandshakeCheckerTest, testing::Bool());
-
-TEST_P(WebApiHandshakeCheckerTest, CheckSafeUrl) {
-  base::HistogramTester histogram_tester;
-  const GURL kUrl("https://example.test");
-  EXPECT_EQ(Check(kUrl), WebApiHandshakeChecker::CheckResult::kProceed);
-  histogram_tester.ExpectUniqueSample(
-      "SafeBrowsing.WebApiHandshakeCheck.Skipped", GetParam(), 1);
-}
-
-TEST_P(WebApiHandshakeCheckerTest, CheckDangerousUrl) {
-  base::HistogramTester histogram_tester;
-  const GURL kUrl("https://example.test");
-  database_manager()->AddDangerousUrl(
-      kUrl, SBThreatType::SB_THREAT_TYPE_URL_PHISHING);
-  if (GetParam()) {
-    EXPECT_EQ(Check(kUrl), WebApiHandshakeChecker::CheckResult::kProceed);
-  } else {
-    EXPECT_EQ(Check(kUrl), WebApiHandshakeChecker::CheckResult::kBlocked);
-  }
-  histogram_tester.ExpectUniqueSample(
-      "SafeBrowsing.WebApiHandshakeCheck.Skipped", GetParam(), 1);
-}
-
-}  // namespace safe_browsing
diff --git a/components/safe_browsing/content/renderer/websocket_sb_handshake_throttle.cc b/components/safe_browsing/content/renderer/websocket_sb_handshake_throttle.cc
index 37a361d..7a8107e7 100644
--- a/components/safe_browsing/content/renderer/websocket_sb_handshake_throttle.cc
+++ b/components/safe_browsing/content/renderer/websocket_sb_handshake_throttle.cc
@@ -11,23 +11,24 @@
 #include "base/functional/callback_helpers.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
-#include "base/strings/stringprintf.h"
-#include "components/safe_browsing/core/common/features.h"
 #include "components/safe_browsing/core/common/scheme_logger.h"
 #include "content/public/renderer/render_frame.h"
 #include "ipc/ipc_message.h"
 #include "net/http/http_request_headers.h"
 #include "services/network/public/mojom/fetch_api.mojom.h"
 #include "third_party/blink/public/platform/web_security_origin.h"
-#include "third_party/blink/public/platform/web_string.h"
 #include "third_party/blink/public/platform/web_url.h"
 
+// TODO(crbug.com/40934395) [Also TODO(thefrog)]: Move entire file to
+// ENABLE_EXTENSIONS-only build and remove in-code build checks.
 #if BUILDFLAG(ENABLE_EXTENSIONS)
 #include "extensions/common/constants.h"
 #endif
 
 namespace safe_browsing {
 
+// TODO(crbug.com/40934395) [Also TODO(thefrog)]: Remove constructor,
+// `frame_token_`, and `safe_browsing_`.
 WebSocketSBHandshakeThrottle::WebSocketSBHandshakeThrottle(
     mojom::SafeBrowsing* safe_browsing,
     base::optional_ref<const blink::LocalFrameToken> local_frame_token)
@@ -52,86 +53,18 @@
     const blink::WebSecurityOrigin& creator_origin,
     const blink::WebSecurityOrigin& isolated_world_origin,
     blink::WebSocketHandshakeThrottle::OnCompletion completion_callback) {
-  DCHECK(!url_checker_);
   DCHECK(!completion_callback_);
   completion_callback_ = std::move(completion_callback);
   url_ = url;
-  int load_flags = 0;
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   MaybeSendExtensionWebRequestData(url, creator_origin, isolated_world_origin);
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
 
-  DCHECK_EQ(state_, State::kInitial);
-  state_ = State::kStarted;
-
+  // TODO(crbug.com/40934395) [Also TODO(thefrog)]: Remove histogram.
   scheme_logger::LogScheme(url, "SafeBrowsing.WebSocketCheck.UrlScheme");
-  // If |kSafeBrowsingSkipSubresources2| is enabled, skip Safe Browsing checks
-  // on WebSockets. Note that we still want to perform the extensions telemetry
-  // code above.
-  if (base::FeatureList::IsEnabled(kSafeBrowsingSkipSubresources2)) {
-    base::UmaHistogramBoolean("SafeBrowsing.WebSocketCheck.Skipped", true);
-    OnCompleteCheck(/*proceed=*/true, /*showed_interstitial=*/false);
-    return;
-  }
-
-  base::UmaHistogramBoolean("SafeBrowsing.WebSocketCheck.Skipped", false);
-  safe_browsing_->CreateCheckerAndCheck(
-      frame_token_, url_checker_.BindNewPipeAndPassReceiver(), url, "GET",
-      net::HttpRequestHeaders(), load_flags, false /* has_user_gesture */,
-      false /* originated_from_service_worker */,
-      base::BindOnce(&WebSocketSBHandshakeThrottle::OnCheckResult,
-                     weak_factory_.GetWeakPtr()));
-
-  // This use of base::Unretained() is safe because the handler will not be
-  // called after |url_checker_| is destroyed, and it is owned by this object.
-  url_checker_.set_disconnect_handler(base::BindOnce(
-      &WebSocketSBHandshakeThrottle::OnMojoDisconnect, base::Unretained(this)));
-}
-
-void WebSocketSBHandshakeThrottle::OnCompleteCheck(bool proceed,
-                                                   bool showed_interstitial) {
-  DCHECK_EQ(state_, State::kStarted);
-  if (proceed) {
-    state_ = State::kSafe;
-    std::move(completion_callback_).Run(std::nullopt);
-  } else {
-    // When the insterstitial is dismissed the page is navigated and this object
-    // is destroyed before reaching here.
-    state_ = State::kBlocked;
-    std::move(completion_callback_)
-        .Run(blink::WebString::FromUTF8(base::StringPrintf(
-            "WebSocket connection to %s failed safe browsing check",
-            url_.spec().c_str())));
-  }
-  // |this| is destroyed here.
-}
-
-void WebSocketSBHandshakeThrottle::OnCheckResult(
-    mojo::PendingReceiver<mojom::UrlCheckNotifier> slow_check_notifier,
-    bool proceed,
-    bool showed_interstitial) {
-  if (!slow_check_notifier.is_valid()) {
-    OnCompleteCheck(proceed, showed_interstitial);
-    return;
-  }
-
-  // TODO(yzshen): Notify the network service to stop reading from the
-  // WebSocket.
-  if (!notifier_receiver_) {
-    notifier_receiver_ =
-        std::make_unique<mojo::Receiver<mojom::UrlCheckNotifier>>(this);
-  }
-  notifier_receiver_->Bind(std::move(slow_check_notifier));
-}
-
-void WebSocketSBHandshakeThrottle::OnMojoDisconnect() {
-  DCHECK(state_ == State::kStarted);
-
-  url_checker_.reset();
-  notifier_receiver_.reset();
-
-  state_ = State::kNotSupported;
+  // TODO(crbug.com/40934395) [Also TODO(thefrog)]: Remove histogram.
+  base::UmaHistogramBoolean("SafeBrowsing.WebSocketCheck.Skipped", true);
   std::move(completion_callback_).Run(std::nullopt);
   // |this| is destroyed here.
 }
diff --git a/components/safe_browsing/content/renderer/websocket_sb_handshake_throttle.h b/components/safe_browsing/content/renderer/websocket_sb_handshake_throttle.h
index 8702308..569024d 100644
--- a/components/safe_browsing/content/renderer/websocket_sb_handshake_throttle.h
+++ b/components/safe_browsing/content/renderer/websocket_sb_handshake_throttle.h
@@ -15,19 +15,14 @@
 #include "base/memory/raw_ptr.h"
 #include "base/types/optional_ref.h"
 #include "components/safe_browsing/content/common/safe_browsing.mojom.h"
-#include "components/safe_browsing/core/common/safe_browsing_url_checker.mojom.h"
 #include "extensions/buildflags/buildflags.h"
-#include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "mojo/public/cpp/bindings/receiver.h"
-#include "mojo/public/cpp/bindings/remote.h"
 #include "third_party/blink/public/common/tokens/tokens.h"
 #include "third_party/blink/public/platform/websocket_handshake_throttle.h"
 #include "url/gurl.h"
 
 namespace safe_browsing {
 
-class WebSocketSBHandshakeThrottle : public blink::WebSocketHandshakeThrottle,
-                                     public mojom::UrlCheckNotifier {
+class WebSocketSBHandshakeThrottle : public blink::WebSocketHandshakeThrottle {
  public:
   WebSocketSBHandshakeThrottle(
       mojom::SafeBrowsing* safe_browsing,
@@ -54,29 +49,10 @@
                              completion_callback) override;
 
  private:
-  enum class State {
-    kInitial,
-    kStarted,
-    kSafe,
-    kBlocked,
-    kNotSupported,
-  };
-
-  // mojom::UrlCheckNotifier implementation.
-  void OnCompleteCheck(bool proceed, bool showed_interstitial) override;
-
-  void OnCheckResult(
-      mojo::PendingReceiver<mojom::UrlCheckNotifier> slow_check_notifier,
-      bool proceed,
-      bool showed_interstitial);
-  void OnMojoDisconnect();
-
   const std::optional<const blink::LocalFrameToken> frame_token_;
   GURL url_;
   blink::WebSocketHandshakeThrottle::OnCompletion completion_callback_;
-  mojo::Remote<mojom::SafeBrowsingUrlChecker> url_checker_;
   raw_ptr<mojom::SafeBrowsing> safe_browsing_;
-  std::unique_ptr<mojo::Receiver<mojom::UrlCheckNotifier>> notifier_receiver_;
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   // Send web request data to the browser if the request
@@ -88,12 +64,6 @@
 
   raw_ptr<mojom::ExtensionWebRequestReporter> extension_web_request_reporter_;
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
-
-  // |state_| is used to validate that events happen in the right order. It
-  // isn't used to control the behaviour of the class.
-  State state_ = State::kInitial;
-
-  base::WeakPtrFactory<WebSocketSBHandshakeThrottle> weak_factory_{this};
 };
 
 }  // namespace safe_browsing
diff --git a/components/safe_browsing/content/renderer/websocket_sb_handshake_throttle_unittest.cc b/components/safe_browsing/content/renderer/websocket_sb_handshake_throttle_unittest.cc
index 45e5f1d..a78e470 100644
--- a/components/safe_browsing/content/renderer/websocket_sb_handshake_throttle_unittest.cc
+++ b/components/safe_browsing/content/renderer/websocket_sb_handshake_throttle_unittest.cc
@@ -10,10 +10,8 @@
 #include "base/functional/callback.h"
 #include "base/run_loop.h"
 #include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "components/safe_browsing/content/common/safe_browsing.mojom.h"
-#include "components/safe_browsing/core/common/features.h"
 #include "components/safe_browsing/core/common/safe_browsing_url_checker.mojom.h"
 #include "ipc/ipc_message.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -168,10 +166,6 @@
   }
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
 
-  void SetUp() override {
-    feature_list_.InitAndEnableFeature(kSafeBrowsingSkipSubresources2);
-  }
-
   base::test::TaskEnvironment message_loop_;
   FakeSafeBrowsing safe_browsing_;
   mojo::Receiver<mojom::SafeBrowsing> safe_browsing_receiver_;
@@ -185,11 +179,11 @@
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
   std::unique_ptr<WebSocketSBHandshakeThrottle> throttle_;
   FakeCallback fake_callback_;
-  base::test::ScopedFeatureList feature_list_;
 };
 
 TEST_F(WebSocketSBHandshakeThrottleTest, Construction) {}
 
+// TODO(crbug.com/40934395) [Also TODO(thefrog)]: Remove test case.
 TEST_F(WebSocketSBHandshakeThrottleTest, DoesNotRunCheck) {
   base::HistogramTester histogram_tester;
   throttle_->ThrottleHandshake(
@@ -202,6 +196,8 @@
                                       true, 1);
 }
 
+// TODO(crbug.com/40934395) [Also TODO(thefrog)]: Move entire file to
+// ENABLE_EXTENSIONS-only build and remove in-code build checks.
 #if BUILDFLAG(ENABLE_EXTENSIONS)
 TEST_F(WebSocketSBHandshakeThrottleTest, SendExtensionWebRequestData) {
   base::HistogramTester histogram_tester;
@@ -254,105 +250,6 @@
 }
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
 
-class WebSocketSBHandshakeThrottleWithSafeBrowsingCheckTest
-    : public WebSocketSBHandshakeThrottleTest {
-  void SetUp() override {
-    feature_list_.InitAndDisableFeature(kSafeBrowsingSkipSubresources2);
-  }
-};
-
-TEST_F(WebSocketSBHandshakeThrottleWithSafeBrowsingCheckTest, CheckArguments) {
-  base::HistogramTester histogram_tester;
-  throttle_->ThrottleHandshake(
-      GURL(kTestUrl), blink::WebSecurityOrigin::CreateFromString(kTestUrl),
-      blink::WebSecurityOrigin(),
-      base::BindOnce(&FakeCallback::OnCompletion,
-                     base::Unretained(&fake_callback_)));
-  safe_browsing_.RunUntilCalled();
-  EXPECT_FALSE(safe_browsing_.frame_token_);
-  EXPECT_EQ(GURL(kTestUrl), safe_browsing_.url_);
-  EXPECT_EQ("GET", safe_browsing_.method_);
-  EXPECT_TRUE(safe_browsing_.headers_.GetHeaderVector().empty());
-  EXPECT_EQ(0, safe_browsing_.load_flags_);
-  EXPECT_FALSE(safe_browsing_.has_user_gesture_);
-  EXPECT_FALSE(safe_browsing_.originated_from_service_worker_);
-  EXPECT_TRUE(safe_browsing_.callback_);
-  histogram_tester.ExpectUniqueSample("SafeBrowsing.WebSocketCheck.Skipped",
-                                      false, 1);
-}
-
-TEST_F(WebSocketSBHandshakeThrottleWithSafeBrowsingCheckTest, Safe) {
-  base::HistogramTester histogram_tester;
-  throttle_->ThrottleHandshake(
-      GURL(kTestUrl), blink::WebSecurityOrigin::CreateFromString(kTestUrl),
-      blink::WebSecurityOrigin(),
-      base::BindOnce(&FakeCallback::OnCompletion,
-                     base::Unretained(&fake_callback_)));
-  safe_browsing_.RunUntilCalled();
-  std::move(safe_browsing_.callback_).Run(mojo::NullReceiver(), true, false);
-  fake_callback_.RunUntilCalled();
-  EXPECT_EQ(FakeCallback::RESULT_SUCCESS, fake_callback_.result_);
-  histogram_tester.ExpectUniqueSample("SafeBrowsing.WebSocketCheck.Skipped",
-                                      false, 1);
-}
-
-TEST_F(WebSocketSBHandshakeThrottleWithSafeBrowsingCheckTest, Unsafe) {
-  base::HistogramTester histogram_tester;
-  throttle_->ThrottleHandshake(
-      GURL(kTestUrl), blink::WebSecurityOrigin::CreateFromString(kTestUrl),
-      blink::WebSecurityOrigin(),
-      base::BindOnce(&FakeCallback::OnCompletion,
-                     base::Unretained(&fake_callback_)));
-  safe_browsing_.RunUntilCalled();
-  std::move(safe_browsing_.callback_).Run(mojo::NullReceiver(), false, false);
-  fake_callback_.RunUntilCalled();
-  EXPECT_EQ(FakeCallback::RESULT_ERROR, fake_callback_.result_);
-  EXPECT_EQ(
-      blink::WebString(
-          "WebSocket connection to wss://test/ failed safe browsing check"),
-      fake_callback_.message_);
-  histogram_tester.ExpectUniqueSample("SafeBrowsing.WebSocketCheck.Skipped",
-                                      false, 1);
-}
-
-TEST_F(WebSocketSBHandshakeThrottleWithSafeBrowsingCheckTest,
-       SlowCheckNotifier) {
-  base::HistogramTester histogram_tester;
-  throttle_->ThrottleHandshake(
-      GURL(kTestUrl), blink::WebSecurityOrigin::CreateFromString(kTestUrl),
-      blink::WebSecurityOrigin(),
-      base::BindOnce(&FakeCallback::OnCompletion,
-                     base::Unretained(&fake_callback_)));
-  safe_browsing_.RunUntilCalled();
-
-  mojo::Remote<mojom::UrlCheckNotifier> slow_check_notifier;
-  std::move(safe_browsing_.callback_)
-      .Run(slow_check_notifier.BindNewPipeAndPassReceiver(), false, false);
-  fake_callback_.RunUntilIdle();
-  EXPECT_EQ(FakeCallback::RESULT_NOT_CALLED, fake_callback_.result_);
-
-  slow_check_notifier->OnCompleteCheck(true, false);
-  fake_callback_.RunUntilCalled();
-  EXPECT_EQ(FakeCallback::RESULT_SUCCESS, fake_callback_.result_);
-  histogram_tester.ExpectUniqueSample("SafeBrowsing.WebSocketCheck.Skipped",
-                                      false, 1);
-}
-
-TEST_F(WebSocketSBHandshakeThrottleWithSafeBrowsingCheckTest,
-       MojoServiceNotThere) {
-  base::HistogramTester histogram_tester;
-  safe_browsing_receiver_.reset();
-  throttle_->ThrottleHandshake(
-      GURL(kTestUrl), blink::WebSecurityOrigin::CreateFromString(kTestUrl),
-      blink::WebSecurityOrigin(),
-      base::BindOnce(&FakeCallback::OnCompletion,
-                     base::Unretained(&fake_callback_)));
-  fake_callback_.RunUntilCalled();
-  EXPECT_EQ(FakeCallback::RESULT_SUCCESS, fake_callback_.result_);
-  histogram_tester.ExpectUniqueSample("SafeBrowsing.WebSocketCheck.Skipped",
-                                      false, 1);
-}
-
 }  // namespace
 
 }  // namespace safe_browsing
diff --git a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc
index 19e3f909..ba954b62 100644
--- a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc
+++ b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc
@@ -354,7 +354,7 @@
       unsafe_resource.is_delayed_warning = true;
       url_checker_delegate_
           ->StartObservingInteractionsForDelayedBlockingPageHelper(
-              unsafe_resource, /*is_main_frame=*/true);
+              unsafe_resource);
       state_ = STATE_DELAYED_BLOCKING_PAGE;
     }
     // Let the navigation continue in case of delayed warnings.
@@ -405,8 +405,7 @@
   state_ = STATE_DISPLAYING_BLOCKING_PAGE;
 
   url_checker_delegate_->StartDisplayingBlockingPageHelper(
-      resource, urls_[next_index_].method, headers_, /*is_main_frame=*/true,
-      has_user_gesture_);
+      resource, urls_[next_index_].method, headers_, has_user_gesture_);
 }
 
 void SafeBrowsingUrlCheckerImpl::CheckUrlImplAndMaybeDeleteSelf(
diff --git a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc
index 85dd54f..c185ba5 100644
--- a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc
+++ b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl_unittest.cc
@@ -187,14 +187,13 @@
 
   MOCK_METHOD1(MaybeDestroyNoStatePrefetchContents,
                void(base::OnceCallback<content::WebContents*()>));
-  MOCK_METHOD5(StartDisplayingBlockingPageHelper,
+  MOCK_METHOD4(StartDisplayingBlockingPageHelper,
                void(const security_interstitials::UnsafeResource&,
                     const std::string&,
                     const net::HttpRequestHeaders&,
-                    bool,
                     bool));
-  MOCK_METHOD2(StartObservingInteractionsForDelayedBlockingPageHelper,
-               void(const security_interstitials::UnsafeResource&, bool));
+  MOCK_METHOD1(StartObservingInteractionsForDelayedBlockingPageHelper,
+               void(const security_interstitials::UnsafeResource&));
   MOCK_METHOD5(ShouldSkipRequestCheck,
                bool(const GURL&,
                     int,
@@ -494,7 +493,7 @@
           /*has_post_commit_interstitial_skipped=*/false,
           SafeBrowsingUrlCheckerImpl::PerformedCheck::kHashDatabaseCheck));
   EXPECT_CALL(*url_checker_delegate_,
-              StartDisplayingBlockingPageHelper(_, _, _, _, _))
+              StartDisplayingBlockingPageHelper(_, _, _, _))
       .Times(0);
 
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
@@ -523,7 +522,7 @@
   EXPECT_CALL(callback, Run(_, _, _, _, _)).Times(0);
   EXPECT_CALL(*url_checker_delegate_,
               StartDisplayingBlockingPageHelper(
-                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _, _))
+                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _))
       .Times(1);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
   task_environment_.RunUntilIdle();
@@ -551,7 +550,7 @@
           /*has_post_commit_interstitial_skipped=*/false,
           SafeBrowsingUrlCheckerImpl::PerformedCheck::kHashDatabaseCheck));
   EXPECT_CALL(*url_checker_delegate_,
-              StartDisplayingBlockingPageHelper(_, _, _, _, _))
+              StartDisplayingBlockingPageHelper(_, _, _, _))
       .Times(0);
   safe_browsing_url_checker->CheckUrl(origin_url, "GET", origin_callback.Get());
 
@@ -592,7 +591,7 @@
   EXPECT_CALL(origin_callback, Run(_, _, _, _, _)).Times(0);
   // Not displayed yet, because the callback is not returned.
   EXPECT_CALL(*url_checker_delegate_,
-              StartDisplayingBlockingPageHelper(_, _, _, _, _))
+              StartDisplayingBlockingPageHelper(_, _, _, _))
       .Times(0);
   safe_browsing_url_checker->CheckUrl(origin_url, "GET", origin_callback.Get());
 
@@ -608,7 +607,7 @@
 
   // The blocking page should be displayed when the origin callback is returned.
   EXPECT_CALL(*url_checker_delegate_,
-              StartDisplayingBlockingPageHelper(_, _, _, _, _))
+              StartDisplayingBlockingPageHelper(_, _, _, _))
       .Times(1);
   database_manager_->RestartDelayedCallback(origin_url);
   task_environment_.RunUntilIdle();
@@ -640,7 +639,7 @@
   EXPECT_CALL(callback, Run(_, _, _, _, _)).Times(0);
   EXPECT_CALL(*url_checker_delegate_,
               StartDisplayingBlockingPageHelper(
-                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _, _))
+                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _))
       .Times(1);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
 
@@ -675,7 +674,7 @@
           /*has_post_commit_interstitial_skipped=*/false,
           SafeBrowsingUrlCheckerImpl::PerformedCheck::kUrlRealTimeCheck));
   EXPECT_CALL(*url_checker_delegate_,
-              StartDisplayingBlockingPageHelper(_, _, _, _, _))
+              StartDisplayingBlockingPageHelper(_, _, _, _))
       .Times(0);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
 
@@ -721,7 +720,7 @@
           /*has_post_commit_interstitial_skipped=*/false,
           SafeBrowsingUrlCheckerImpl::PerformedCheck::kUrlRealTimeCheck));
   EXPECT_CALL(*url_checker_delegate_,
-              StartDisplayingBlockingPageHelper(_, _, _, _, _))
+              StartDisplayingBlockingPageHelper(_, _, _, _))
       .Times(0);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
 
@@ -764,7 +763,7 @@
           /*has_post_commit_interstitial_skipped=*/false,
           SafeBrowsingUrlCheckerImpl::PerformedCheck::kUrlRealTimeCheck));
   EXPECT_CALL(*url_checker_delegate_,
-              StartDisplayingBlockingPageHelper(_, _, _, _, _))
+              StartDisplayingBlockingPageHelper(_, _, _, _))
       .Times(0);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
 
@@ -804,7 +803,7 @@
       callback;
   EXPECT_CALL(*url_checker_delegate_,
               StartDisplayingBlockingPageHelper(
-                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _, _))
+                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _))
       .Times(1);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
 
@@ -850,7 +849,7 @@
   // Suspicious site detection should happen for URL real time lookups.
   EXPECT_CALL(*url_checker_delegate_, NotifySuspiciousSiteDetected(_)).Times(1);
   EXPECT_CALL(*url_checker_delegate_,
-              StartDisplayingBlockingPageHelper(_, _, _, _, _))
+              StartDisplayingBlockingPageHelper(_, _, _, _))
       .Times(0);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
 
@@ -881,7 +880,7 @@
   EXPECT_CALL(
       *url_checker_delegate_,
       StartDisplayingBlockingPageHelper(
-          IsSameThreatSource(ThreatSource::URL_REAL_TIME_CHECK), _, _, _, _))
+          IsSameThreatSource(ThreatSource::URL_REAL_TIME_CHECK), _, _, _))
       .Times(1);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
 
@@ -919,7 +918,7 @@
   EXPECT_CALL(
       *url_checker_delegate_,
       StartDisplayingBlockingPageHelper(
-          IsSameThreatSource(ThreatSource::URL_REAL_TIME_CHECK), _, _, _, _))
+          IsSameThreatSource(ThreatSource::URL_REAL_TIME_CHECK), _, _, _))
       .Times(1);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
 
@@ -956,7 +955,7 @@
   EXPECT_CALL(
       *url_checker_delegate_,
       StartDisplayingBlockingPageHelper(
-          IsSameThreatSource(ThreatSource::URL_REAL_TIME_CHECK), _, _, _, _))
+          IsSameThreatSource(ThreatSource::URL_REAL_TIME_CHECK), _, _, _))
       .Times(1);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
 
@@ -995,7 +994,7 @@
           /*has_post_commit_interstitial_skipped=*/false,
           SafeBrowsingUrlCheckerImpl::PerformedCheck::kUrlRealTimeCheck));
   EXPECT_CALL(*url_checker_delegate_,
-              StartDisplayingBlockingPageHelper(_, _, _, _, _))
+              StartDisplayingBlockingPageHelper(_, _, _, _))
       .Times(0);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
 
@@ -1037,7 +1036,7 @@
           /*has_post_commit_interstitial_skipped=*/false,
           SafeBrowsingUrlCheckerImpl::PerformedCheck::kUrlRealTimeCheck));
   EXPECT_CALL(*url_checker_delegate_,
-              StartDisplayingBlockingPageHelper(_, _, _, _, _))
+              StartDisplayingBlockingPageHelper(_, _, _, _))
       .Times(0);
   safe_browsing_url_checker->CheckUrl(origin_url, "GET", origin_callback.Get());
 
@@ -1208,7 +1207,7 @@
       .Times(1);
   EXPECT_CALL(*url_checker_delegate_,
               StartDisplayingBlockingPageHelper(
-                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _, _))
+                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _))
       .Times(0);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
   task_environment_.RunUntilIdle();
@@ -1245,7 +1244,7 @@
       .Times(1);
   EXPECT_CALL(*url_checker_delegate_,
               StartDisplayingBlockingPageHelper(
-                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _, _))
+                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _))
       .Times(0);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
   task_environment_.RunUntilIdle();
@@ -1279,7 +1278,7 @@
   EXPECT_CALL(callback, Run(_, _, _, _, _)).Times(0);
   EXPECT_CALL(*url_checker_delegate_,
               StartDisplayingBlockingPageHelper(
-                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _, _))
+                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _))
       .Times(1);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
   task_environment_.RunUntilIdle();
@@ -1316,7 +1315,7 @@
   EXPECT_CALL(
       *url_checker_delegate_,
       StartDisplayingBlockingPageHelper(
-          IsSameThreatSource(ThreatSource::NATIVE_PVER5_REAL_TIME), _, _, _, _))
+          IsSameThreatSource(ThreatSource::NATIVE_PVER5_REAL_TIME), _, _, _))
       .Times(0);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
   task_environment_.RunUntilIdle();
@@ -1350,7 +1349,7 @@
   EXPECT_CALL(
       *url_checker_delegate_,
       StartDisplayingBlockingPageHelper(
-          IsSameThreatSource(ThreatSource::NATIVE_PVER5_REAL_TIME), _, _, _, _))
+          IsSameThreatSource(ThreatSource::NATIVE_PVER5_REAL_TIME), _, _, _))
       .Times(1);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
   task_environment_.RunUntilIdle();
@@ -1385,7 +1384,7 @@
   EXPECT_CALL(callback, Run(_, _, _, _, _)).Times(0);
   EXPECT_CALL(*url_checker_delegate_,
               StartDisplayingBlockingPageHelper(
-                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _, _))
+                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _))
       .Times(1);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
   task_environment_.RunUntilIdle();
@@ -1421,7 +1420,7 @@
   EXPECT_CALL(callback, Run(_, _, _, _, _)).Times(0);
   EXPECT_CALL(*url_checker_delegate_,
               StartDisplayingBlockingPageHelper(
-                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _, _))
+                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _))
       .Times(1);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
   task_environment_.RunUntilIdle();
@@ -1455,7 +1454,7 @@
   EXPECT_CALL(
       *url_checker_delegate_,
       StartDisplayingBlockingPageHelper(
-          IsSameThreatSource(ThreatSource::URL_REAL_TIME_CHECK), _, _, _, _))
+          IsSameThreatSource(ThreatSource::URL_REAL_TIME_CHECK), _, _, _))
       .Times(1);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
 
@@ -1486,7 +1485,7 @@
   EXPECT_CALL(callback, Run(_, _, _, _, _)).Times(0);
   EXPECT_CALL(*url_checker_delegate_,
               StartDisplayingBlockingPageHelper(
-                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _, _))
+                  IsSameThreatSource(ThreatSource::UNKNOWN), _, _, _))
       .Times(1);
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
 
@@ -1514,7 +1513,7 @@
                   /*has_post_commit_interstitial_skipped=*/false,
                   SafeBrowsingUrlCheckerImpl::PerformedCheck::kCheckSkipped));
   EXPECT_CALL(*url_checker_delegate_,
-              StartDisplayingBlockingPageHelper(_, _, _, _, _))
+              StartDisplayingBlockingPageHelper(_, _, _, _))
       .Times(0);
 
   safe_browsing_url_checker->CheckUrl(url, "GET", callback.Get());
diff --git a/components/safe_browsing/core/browser/url_checker_delegate.h b/components/safe_browsing/core/browser/url_checker_delegate.h
index b5e12dd..d542c55 100644
--- a/components/safe_browsing/core/browser/url_checker_delegate.h
+++ b/components/safe_browsing/core/browser/url_checker_delegate.h
@@ -49,14 +49,12 @@
       const security_interstitials::UnsafeResource& resource,
       const std::string& method,
       const net::HttpRequestHeaders& headers,
-      bool is_main_frame,
       bool has_user_gesture) = 0;
 
   // Starts observing user input events to display a SafeBrowsing interstitial
   // page when an event is received.
   virtual void StartObservingInteractionsForDelayedBlockingPageHelper(
-      const security_interstitials::UnsafeResource& resource,
-      bool is_main_frame) = 0;
+      const security_interstitials::UnsafeResource& resource) = 0;
 
   // An allowlisted URL is considered safe and therefore won't be checked with
   // the SafeBrowsing database.
diff --git a/components/safe_browsing/core/common/features.cc b/components/safe_browsing/core/common/features.cc
index 2aa7f2ca..ca55c114 100644
--- a/components/safe_browsing/core/common/features.cc
+++ b/components/safe_browsing/core/common/features.cc
@@ -288,10 +288,6 @@
              "SafeBrowsingRemoveCookiesInAuthRequests",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-BASE_FEATURE(kSafeBrowsingSkipSubresources2,
-             "SafeBrowsingSkipSubResources2",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
 BASE_FEATURE(kSafetyHubAbusiveNotificationRevocation,
              "SafetyHubAbusiveNotificationRevocation",
              base::FEATURE_DISABLED_BY_DEFAULT);
@@ -406,7 +402,6 @@
     {&kRealTimeUrlFilteringCustomMessage, true},
     {&kSafeBrowsingAsyncRealTimeCheck, true},
     {&kSafeBrowsingRemoveCookiesInAuthRequests, true},
-    {&kSafeBrowsingSkipSubresources2, true},
     {&kSafetyHubAbusiveNotificationRevocation, true},
     {&kSevenZipEvaluationEnabled, true},
     {&kSimplifiedUrlDisplay, true},
diff --git a/components/safe_browsing/core/common/features.h b/components/safe_browsing/core/common/features.h
index 026ef0e1..6c75a6c3 100644
--- a/components/safe_browsing/core/common/features.h
+++ b/components/safe_browsing/core/common/features.h
@@ -229,10 +229,6 @@
 // Controls whether cookies are removed when the access token is present.
 BASE_DECLARE_FEATURE(kSafeBrowsingRemoveCookiesInAuthRequests);
 
-// Controls whether to skip Safe Browsing checks for WebSockets and Web API
-// handshakes.
-BASE_DECLARE_FEATURE(kSafeBrowsingSkipSubresources2);
-
 // Automatically revoke abusive notifications in Safety Hub.
 BASE_DECLARE_FEATURE(kSafetyHubAbusiveNotificationRevocation);
 
diff --git a/components/strings/components_strings_am.xtb b/components/strings/components_strings_am.xtb
index b6dd1d8..7de8e6e 100644
--- a/components/strings/components_strings_am.xtb
+++ b/components/strings/components_strings_am.xtb
@@ -3062,6 +3062,7 @@
 <translation id="6915804003454593391">ተጠቃሚ፦</translation>
 <translation id="6916193791494646625">የማውረድ ምክንያት ያቅርቡ (አስፈላጊ)</translation>
 <translation id="6917795328362592458">አሁን የተጠቀሙበት የይለፍ ቃል በውሂብ ጥሰት ውስጥ ተገኝቷል። የእርስዎን መለያዎች ደህንነት ለመጠበቅ፣ የይለፍ ቃል አስተዳዳሪ የተቀመጡ የይለፍ ቃላትዎን እንዲፈትሹ ይመክራል።</translation>
+<translation id="6924013822850225188">በክፍያ ማጠናቀቂያ ላይ የካርድ ጥቅማጥቅሞችን ያዩ እንደሆነ ይምረጡ (የባንክ ደንቦች ተፈጻሚ ናቸው)</translation>
 <translation id="6925267999184670015">የሰሜን አሜሪካ B+</translation>
 <translation id="6926216138694948720">የሰውነት ሥነ ጥበብ</translation>
 <translation id="692638818576287323">የንግድ ተሽከርካሪዎች</translation>
@@ -3831,6 +3832,7 @@
 <translation id="830498451218851433">ግማሽ እጠፍ</translation>
 <translation id="8308653357438598313">የቀጥታ ስርጭት የቪድዮ ዥረት</translation>
 <translation id="8311895354659782580">የሪል ስቴት ዝርዝሮች</translation>
+<translation id="8312841338723044391">ቀጥታ ስርጭት</translation>
 <translation id="8316555157357957253">አሁን ጥቅም ላይ እየወለ ያለ</translation>
 <translation id="8319269383395457801">የመኖሪያ ሽያጮች</translation>
 <translation id="831997045666694187">ምሽት</translation>
diff --git a/components/strings/components_strings_bn.xtb b/components/strings/components_strings_bn.xtb
index 8ba032d..f4d67b6 100644
--- a/components/strings/components_strings_bn.xtb
+++ b/components/strings/components_strings_bn.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">ব্যবহারকারী:</translation>
 <translation id="6916193791494646625">ডাউনলোড করার কারণ লিখুন (খালি রাখা যাবে না)</translation>
 <translation id="6917795328362592458">আপনি এইমাত্র যে পাসওয়ার্ড ব্যবহার করলেন, সেটি হ্যাক হওয়া কোনও ডেটাবেসে পাওয়া গেছে। আপনার অ্যাকাউন্ট সুরক্ষিত করতে, Password Manager আপনার সেভ করা পাসওয়ার্ড চেক করার সাজেশন দিচ্ছে।</translation>
+<translation id="6924013822850225188">পৃষ্ঠা থেকে বেরিয়ে যাওয়ার সময় কার্ডের সুবিধাগুলি দেখতে চান কিনা তা বেছে নিন (ব্যাঙ্কের শর্তাবলী প্রয়োজ্য)</translation>
 <translation id="6925267999184670015">নর্থ আমেরিকান B+</translation>
 <translation id="6926216138694948720">বডি আর্ট</translation>
 <translation id="692638818576287323">ব্যবসায়িক গাড়ি</translation>
@@ -3832,6 +3833,7 @@
 <translation id="830498451218851433">অর্ধেক ফোল্ড করুন</translation>
 <translation id="8308653357438598313">লাইভ ভিডিও স্ট্রিমিং</translation>
 <translation id="8311895354659782580">রিয়েল এস্টেটের তালিকা</translation>
+<translation id="8312841338723044391">লাইভ</translation>
 <translation id="8316555157357957253">এখন ব্যবহার করা হচ্ছে</translation>
 <translation id="8319269383395457801">আবাসন বিক্রি</translation>
 <translation id="831997045666694187">সন্ধ্যা</translation>
diff --git a/components/strings/components_strings_bs.xtb b/components/strings/components_strings_bs.xtb
index 480fbbe..f72b441 100644
--- a/components/strings/components_strings_bs.xtb
+++ b/components/strings/components_strings_bs.xtb
@@ -508,6 +508,7 @@
 <translation id="192095259937375524">Dugme Dijeli ovu karticu, aktivirajte da dijelite ovu karticu dijeljenjem linka, kreiranjem QR koda, emitiranjem i drugo</translation>
 <translation id="1924727005275031552">Novo</translation>
 <translation id="1927439846988093361">Njega kose</translation>
+<translation id="1935353813610900265">Pošaljite povratne informacije za pretraživanje povijesti pomoću AI-ja</translation>
 <translation id="1935995810530254458">Ipak kopiraj</translation>
 <translation id="1939059826036755332">Automatska slika u slici</translation>
 <translation id="1939175642807587452">Može tražiti da šalje obavještenja</translation>
@@ -831,6 +832,7 @@
 <translation id="2526280916094749336">Možete koristiti sačuvane adrese na Googleovim proizvodima. Adresa će se sačuvati na Google računu <ph name="ACCOUNT" />.</translation>
 <translation id="2527451058878391043">Vaš CVC je na prednjoj strani kartice. To je četverocifreni kôd u gornjem desnom uglu iznad broja kartice.</translation>
 <translation id="2529899080962247600">Ovo polje ne smije sadržavati više od sljedećeg broja unosa: <ph name="MAX_ITEMS_LIMIT" />. Svi daljnji unosi će se zanemariti.</translation>
+<translation id="2530042584066815841">Zaključavanje i upotreba miša</translation>
 <translation id="2533649878691950253">Ovoj web lokaciji je blokiran pristup vašoj tačnoj lokaciji jer to obično ne dozvoljavate</translation>
 <translation id="253493526287553278">Pogledajte detalje o promotivnim kôdovima</translation>
 <translation id="2535585790302968248">Otvorite novu anonimnu karticu da privatno pregledate</translation>
@@ -856,6 +858,7 @@
 <translation id="255497580849974774">Neka uređaj ostane priključen na punjač tokom ažuriranja.</translation>
 <translation id="2556876185419854533">&amp;Poništi uređivanje</translation>
 <translation id="2559566667529177711">Višeslojno</translation>
+<translation id="2565789370591907825">Zaključavanje i upotreba tipkovnice</translation>
 <translation id="2570734079541893434">Upravljajte postavkama</translation>
 <translation id="2573170131138724450">Televizori</translation>
 <translation id="257674075312929031">Grupa</translation>
@@ -903,6 +906,7 @@
 <translation id="2687555958734450033">Najpogodniji format</translation>
 <translation id="2688186765492306706">500 x 760 mm</translation>
 <translation id="2688969097326701645">Da, nastavi</translation>
+<translation id="2690699652723742414">Posljednjih 30 dana</translation>
 <translation id="2691924980723297736">Sigurnosno upozorenje</translation>
 <translation id="2699273987028089219">Dostupan je podmeni; pritisnite <ph name="SHORTCUT" /> da odete u dodatne opcije.</translation>
 <translation id="2701514975700770343">Odštampana strana prema dolje</translation>
@@ -1032,6 +1036,7 @@
 <translation id="297173220375858963">Stolno izdavaštvo</translation>
 <translation id="2972581237482394796">&amp;Ponovi</translation>
 <translation id="2977665033722899841"><ph name="ROW_NAME" />, trenutno odabrano. <ph name="ROW_CONTENT" /></translation>
+<translation id="2977847223286097084">Zaključavanje i upotreba tipkovnice</translation>
 <translation id="2978824962390592855">Opera</translation>
 <translation id="2979424420072875974">Resursi za pisce</translation>
 <translation id="2980742331521553164">CVC kartice će se šifrirati i sačuvati na Google račun radi bržeg nastavka na plaćanje</translation>
@@ -1104,6 +1109,7 @@
 <translation id="31207688938192855"><ph name="BEGIN_LINK" />Pokušajte pokrenuti dijagnostiku povezivosti<ph name="END_LINK" />.</translation>
 <translation id="3120807611504813890">Koverta (lagana)</translation>
 <translation id="3121994479408824897">Idi na <ph name="DOMAIN" /></translation>
+<translation id="3122696783148405307">Prikaži rezultate iz posljednjih 30 dana</translation>
 <translation id="3126023634486644099">Naljepnice (trajne)</translation>
 <translation id="3133565499688974786"><ph name="SEARCH_ENGINE_NAME" /> je sada zadani pretraživač</translation>
 <translation id="3137283076021007034"><ph name="KEYWORD" /> – pretražite <ph name="KEYWORD_SHORT_NAME" /></translation>
@@ -1473,6 +1479,7 @@
 <translation id="3781428340399460090">Vatreno ružičasta</translation>
 <translation id="3783418713923659662">MasterCard</translation>
 <translation id="3784372983762739446">Bluetooth uređaji</translation>
+<translation id="378611282717571199">Najbolja podudaranja za upit "<ph name="SEARCH_QUERY" />"</translation>
 <translation id="3789155188480882154">Veličina 16</translation>
 <translation id="3789841737615482174">Instaliraj</translation>
 <translation id="3792100426446126328"><ph name="NAME" /> (<ph name="WIDTH" /> x <ph name="HEIGHT" /> in)</translation>
@@ -1493,6 +1500,7 @@
 <translation id="3815434930383843058">8 x 12 in</translation>
 <translation id="3816482573645936981">Vrijednost (zamijenjeno)</translation>
 <translation id="382115839591654906">CVC za karticu <ph name="CARD_NAME" /></translation>
+<translation id="3822492359574576064">zaključavanje i upotreba miša</translation>
 <translation id="3823019343150397277">IBAN</translation>
 <translation id="3823402221513322552">Vašim preglednikom upravlja domena <ph name="BROWSER_DOMAIN" />, a profilom domena <ph name="PROFILE_DOMAIN" /></translation>
 <translation id="382518646247711829">Ako koristite proksi server...</translation>
@@ -1817,6 +1825,7 @@
 <translation id="4438821706955556403">Uobičajena cijena</translation>
 <translation id="4441832193888514600">Zanemareno jer se pravilo može postaviti samo kao korisničko pravilo oblaka.</translation>
 <translation id="4445133368066241428">Popularne teme</translation>
+<translation id="4445964943162061557">Ovo je eksperimentalna značajka i neće uvijek biti bez pogrešaka.</translation>
 <translation id="4449116177348980384">Dugme Upravljaj postavkama web lokacije, aktivirajte da upravljate odobrenjima i podacima pohranjenim na web lokacijama u postavkama Chromea</translation>
 <translation id="4451135742916150903">Može tražiti da se poveže na HID uređaje</translation>
 <translation id="4451684391620232683">Tekst koji se prikazuje korisniku:</translation>
@@ -1895,6 +1904,7 @@
 <translation id="4631881646528206880">Registracija virtuelne kartice</translation>
 <translation id="4635278307999235413">Slanje podataka na administratorsku konzolu</translation>
 <translation id="4636930964841734540">Informacije</translation>
+<translation id="4640225694041297329">Prikaži rezultate iz posljednjih 7 dana</translation>
 <translation id="464342062220857295">Funkcije pretraživanja</translation>
 <translation id="4644670975240021822">Obrnuti redoslijed s odštampanom stranom prema dolje</translation>
 <translation id="4646534391647090355">Odvedi me tamo sada</translation>
@@ -1974,6 +1984,7 @@
 <translation id="4780366598804516005">Poštansko sanduče 1</translation>
 <translation id="4785376858512657294">Upravljajte Google računom</translation>
 <translation id="4785689107224900852">Prebaci na ovu karticu</translation>
+<translation id="4785998536350006000">Pretraživanje upita "<ph name="SEARCH_QUERY" />"</translation>
 <translation id="4786804728079074733">Odbojka</translation>
 <translation id="4787182171088676626">Koverta (tanka)</translation>
 <translation id="4789704664580239421">Obavještenja o padu cijene će se prikazivati na otvorenim karticama</translation>
@@ -2011,6 +2022,7 @@
 <translation id="4864801646102013152">Uređenje doma</translation>
 <translation id="4866506163384898554">Pritisnite |<ph name="ACCELERATOR1" />| + |<ph name="ACCELERATOR2" />| da prikažete kursor</translation>
 <translation id="4873616204573862158">Naočale</translation>
+<translation id="4873807733347502026">Zaključavanje i upotreba miša</translation>
 <translation id="4876188919622883022">Pojednostavljeni prikaz</translation>
 <translation id="4876305945144899064">Nema korisničkog imena</translation>
 <translation id="4876327226315760474">Ovo znači da bi funkcije web lokacije trebale funkcionirati prema očekivanjima, ali ćete možda imati manju zaštitu prilikom pregledanja.</translation>
@@ -2098,6 +2110,7 @@
 <translation id="5018802455907704660">16 x 20 in</translation>
 <translation id="5019198164206649151">Pohrana za sigurnosnu kopiju je u lošem stanju</translation>
 <translation id="5019293549442035120">Možete koristiti sačuvane adrese na Googleovim proizvodima. Adresa će se sačuvati na Google računu <ph name="USER_EMAIL" />.</translation>
+<translation id="5019952743397118625">Postavljeno je pravilo <ph name="EXTENSION_DEVELOPER_MODE_SETTINGS_POLICY_NAME" />. <ph name="DEVELOPER_TOOLS_AVAILABILITY_POLICY_NAME" /> neće upravljati dostupnošću načina rada razvojnog programera na stranici proširenja.</translation>
 <translation id="5021557570875267742">Pratite cijene uz Chrome</translation>
 <translation id="5023310440958281426">Provjerite pravila administratora</translation>
 <translation id="5030338702439866405">Izdavač:</translation>
@@ -2436,6 +2449,7 @@
 <translation id="5667827081946850877">Audio knjige</translation>
 <translation id="5675650730144413517">Ova stranica ne funkcionira</translation>
 <translation id="5675809467256309336">Plesna i elektronska muzika</translation>
+<translation id="5675959228867414813">Prikaži po datumu</translation>
 <translation id="5677928146339483299">Blokirano</translation>
 <translation id="5678007133659493065">Folija</translation>
 <translation id="5680642791693447368">Trileri, kriminalistički filmovi i misterije</translation>
@@ -2653,6 +2667,7 @@
 <translation id="6108702513636120202">Vaš pretraživač u Chromiumu</translation>
 <translation id="6108849843016142864">Gmizavci i vodozemci</translation>
 <translation id="610911394827799129">Google račun može imati druge oblike historije pregledanja na <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="611018310643025551">Vaša pretraživanja, najbolja podudaranja i sadržaj njihovih stranica šalju se Googleu i mogu ih vidjeti pregledavatelji radi poboljšanja te značajke.</translation>
 <translation id="6116338172782435947">Pogledajte tekst i slike kopirane u međumemoriju</translation>
 <translation id="6117833587752089929">Fotografija (saten)</translation>
 <translation id="6118782133429281336">Historija polazišta je prazna.</translation>
@@ -2909,6 +2924,7 @@
 <translation id="6587923378399804057">Link koji ste kopirali</translation>
 <translation id="6591833882275308647">Vašim uređajem <ph name="DEVICE_TYPE" /> se ne upravlja</translation>
 <translation id="6596325263575161958">Opcije za šifriranje</translation>
+<translation id="6596573334527383067">Prikažite rezultate od jučer</translation>
 <translation id="6597665340361269064">90 stepeni</translation>
 <translation id="6598976221101665070">Dramski filmovi</translation>
 <translation id="6599642189720630047">Praćeni proizvodi</translation>
@@ -3380,6 +3396,7 @@
 <translation id="7489392576326061356">Šamponi i regeneratori</translation>
 <translation id="7495528107193238112">Ovaj sadržaj je blokiran. Kontaktirajte vlasnika web lokacije da riješite problem.</translation>
 <translation id="749865518782565832">Vodoinstalacije</translation>
+<translation id="7500917112031739411">Prikaži po grupi</translation>
 <translation id="7501663406926337752">Vaša organizacija je prijavila web lokaciju koja slijedi</translation>
 <translation id="7507075214339298899">Koverta #9</translation>
 <translation id="7508255263130623398">Vraćeni ID uređaja pravila ne postoji ili ne odgovara trenutnom ID-u uređaja</translation>
@@ -3581,6 +3598,7 @@
 <translation id="7825558994363763489">Mikrovalne pećnice</translation>
 <translation id="782886543891417279">WiFi koji koristite (<ph name="WIFI_NAME" />) može zahtijevati da posjetite stranicu za prijavu.</translation>
 <translation id="7831993212387676366">Šta je lista za kupovinu?</translation>
+<translation id="7832078172950550575">Povijest pregledavanja možete pretraživati pomoću svakodnevnih izraza kao što su "pizza u blizini" ili "parkovi prikladni za obitelj u centru grada". Vaša pretraživanja, najbolja podudaranja i sadržaj njihovih stranica šalju se Googleu i mogu ih vidjeti pregledavatelji radi poboljšanja te značajke. <ph name="BEGIN_LINK" />Upravljajte postavkom pretraživanja povijesti<ph name="END_LINK" /></translation>
 <translation id="7840103971441592723">Snimanje ekrana nije pokrenuto</translation>
 <translation id="784137052867620416">Uvidi u kupovinu</translation>
 <translation id="784404208867107517">Historija prema grupama</translation>
@@ -3877,6 +3895,7 @@
 <translation id="8398335999901363925">Načini plaćanja koji su dostupni za popunjavanje dodirom su otvoreni u punoj visini.</translation>
 <translation id="8398446215576328011">Poništi primijenjena pravila</translation>
 <translation id="8398790343843005537">Pronađite svoj telefon</translation>
+<translation id="8399276468426899527">zaključavanje i upotreba tipkovnice</translation>
 <translation id="8400929824946688748">Poslovi i obrazovanje</translation>
 <translation id="8403506619177967839">Fan fikcija</translation>
 <translation id="8405579342203358118">Upravljajte time koje informacije sinhronizirate u postavkama Chromea</translation>
@@ -4218,6 +4237,7 @@
 <translation id="9089260154716455634">Pravilo za period van radnog vremena:</translation>
 <translation id="9090218457905363312">Reggae i karipska muzika</translation>
 <translation id="9090243919347147717">Prilozi</translation>
+<translation id="9090548458280093580">Pretražujte svoju povijesti pomoću AI-ja</translation>
 <translation id="9090993752571911635">Pružaoci internetskih usluga (ISP-ovi)</translation>
 <translation id="9093723786115107672">Odjeća za spavanje</translation>
 <translation id="9094544726794842788">Oznaka "Ne sviđa mi se" otvara obrazac za slanje detaljnih povratnih informacija o tome zašto vam se ovi rezultati ne sviđaju</translation>
diff --git a/components/strings/components_strings_cy.xtb b/components/strings/components_strings_cy.xtb
index 0e989cb..f21f1a99 100644
--- a/components/strings/components_strings_cy.xtb
+++ b/components/strings/components_strings_cy.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">Defnyddiwr:</translation>
 <translation id="6916193791494646625">Rhowch reswm dros lawrlwytho (gofynnol)</translation>
 <translation id="6917795328362592458">Canfuwyd y cyfrinair rydych newydd ei ddefnyddio mewn achos o dor data. Er mwyn diogelu'ch cyfrifon, mae'r Rheolwr Cyfrineiriau yn argymell gwirio'ch cyfrineiriau sydd wedi'u cadw.</translation>
+<translation id="6924013822850225188">Dewiswch a ydych yn gweld buddion eich cerdyn wrth dalu (mae telerau banc yn berthnasol)</translation>
 <translation id="6925267999184670015">B+ Gogledd America</translation>
 <translation id="6926216138694948720">Celf Corff</translation>
 <translation id="692638818576287323">Cerbydau Masnachol</translation>
@@ -3832,6 +3833,7 @@
 <translation id="830498451218851433">Hanner Plyg</translation>
 <translation id="8308653357438598313">Ffrydio Fideo Byw</translation>
 <translation id="8311895354659782580">Rhestrau Eiddo Tirol</translation>
+<translation id="8312841338723044391">YN FYW</translation>
 <translation id="8316555157357957253">Defnyddio nawr</translation>
 <translation id="8319269383395457801">Gwerthiannau Preswyl</translation>
 <translation id="831997045666694187">Nos</translation>
diff --git a/components/strings/components_strings_da.xtb b/components/strings/components_strings_da.xtb
index a8765b3..9ab871e9 100644
--- a/components/strings/components_strings_da.xtb
+++ b/components/strings/components_strings_da.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">Bruger:</translation>
 <translation id="6916193791494646625">Angiv årsag til download (påkrævet)</translation>
 <translation id="6917795328362592458">Den adgangskode, du lige har brugt, er blevet lækket i forbindelse med et brud på datasikkerheden. For at beskytte dine konti anbefaler Adgangs­kode­admin­istrator, at du tjekker dine gemte adgangskoder.</translation>
+<translation id="6924013822850225188">Vælg, om du vil se dine kortfordele ved betalingen (bankvilkår er gældende)</translation>
 <translation id="6925267999184670015">Nordamerika B+</translation>
 <translation id="6926216138694948720">Kropskunst</translation>
 <translation id="692638818576287323">Erhvervskøretøjer</translation>
@@ -3832,6 +3833,7 @@
 <translation id="830498451218851433">Fals halvt</translation>
 <translation id="8308653357438598313">Live videostreaming</translation>
 <translation id="8311895354659782580">Ejendomshandel</translation>
+<translation id="8312841338723044391">LIVE</translation>
 <translation id="8316555157357957253">Bruges nu</translation>
 <translation id="8319269383395457801">Salg af ejendom</translation>
 <translation id="831997045666694187">Aften</translation>
diff --git a/components/strings/components_strings_en-GB.xtb b/components/strings/components_strings_en-GB.xtb
index 3cd10023..9fcc520 100644
--- a/components/strings/components_strings_en-GB.xtb
+++ b/components/strings/components_strings_en-GB.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">User:</translation>
 <translation id="6916193791494646625">Provide reason for downloading (required)</translation>
 <translation id="6917795328362592458">The password that you just used was found in a data breach. To secure your accounts, Password Manager recommends checking your saved passwords.</translation>
+<translation id="6924013822850225188">Choose whether you see your card benefits at checkout (bank terms apply)</translation>
 <translation id="6925267999184670015">North American B+</translation>
 <translation id="6926216138694948720">Body art</translation>
 <translation id="692638818576287323">Commercial Vehicles</translation>
@@ -3681,7 +3682,7 @@
 <translation id="8037117624646282037">Who has used the device recently</translation>
 <translation id="8037357227543935929">Ask (default)</translation>
 <translation id="803771048473350947">File</translation>
-<translation id="8041089156583427627">Send Feedback</translation>
+<translation id="8041089156583427627">Send feedback</translation>
 <translation id="8041940743680923270">Use global default (Ask)</translation>
 <translation id="8043255123207491407">See seller's terms and conditions</translation>
 <translation id="8046360364391076336">Industrial Materials and Equipment</translation>
@@ -3832,6 +3833,7 @@
 <translation id="830498451218851433">Fold half</translation>
 <translation id="8308653357438598313">Live Video Streaming</translation>
 <translation id="8311895354659782580">Real Property Listings</translation>
+<translation id="8312841338723044391">LIVE</translation>
 <translation id="8316555157357957253">Using now</translation>
 <translation id="8319269383395457801">Residential Sales</translation>
 <translation id="831997045666694187">Evening</translation>
diff --git a/components/strings/components_strings_es.xtb b/components/strings/components_strings_es.xtb
index 19dcf494..ba14f81f 100644
--- a/components/strings/components_strings_es.xtb
+++ b/components/strings/components_strings_es.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">Usuario:</translation>
 <translation id="6916193791494646625">Indica el motivo de la descarga (obligatorio)</translation>
 <translation id="6917795328362592458">La contraseña que acabas de usar se ha encontrado en una brecha de seguridad de datos. Para proteger tus cuentas, el gestor de contraseñas te recomienda que compruebes las contraseñas que tengas guardadas.</translation>
+<translation id="6924013822850225188">Elige si quieres ver las ventajas de tu tarjeta al tramitar una compra (se aplican los términos del banco)</translation>
 <translation id="6925267999184670015">B+ norteamericano</translation>
 <translation id="6926216138694948720">Arte corporal</translation>
 <translation id="692638818576287323">Vehículos comerciales</translation>
@@ -3832,6 +3833,7 @@
 <translation id="830498451218851433">Plegado al medio</translation>
 <translation id="8308653357438598313">Emisión de vídeo en directo</translation>
 <translation id="8311895354659782580">Anuncios inmobiliarios</translation>
+<translation id="8312841338723044391">EN DIRECTO</translation>
 <translation id="8316555157357957253">Se está usando ahora</translation>
 <translation id="8319269383395457801">Ventas de viviendas</translation>
 <translation id="831997045666694187">Tarde</translation>
diff --git a/components/strings/components_strings_eu.xtb b/components/strings/components_strings_eu.xtb
index fcd831f..d6ab8b9 100644
--- a/components/strings/components_strings_eu.xtb
+++ b/components/strings/components_strings_eu.xtb
@@ -3058,6 +3058,7 @@
 <translation id="6915804003454593391">Erabiltzailea:</translation>
 <translation id="6916193791494646625">Deskargatzeko arrazoia (beharrezkoa)</translation>
 <translation id="6917795328362592458">Erabili berri duzun pasahitza datuen isilpekotasunaren urratze batean aurkitu da. Kontuak babesteko, Pasahitz-kudeatzailea aplikazioak gordeta dauzkazun pasahitzak seguruak direla egiaztatzea gomendatzen du.</translation>
+<translation id="6924013822850225188">Aukeratu ordainketa-prozesuan txartelaren abantailak ikusi nahi dituzun (bankuaren baldintzak aplikatzen dira)</translation>
 <translation id="6925267999184670015">B+ iparramerikarra</translation>
 <translation id="6926216138694948720">Gorputz-artea</translation>
 <translation id="692638818576287323">Merkataritza-ibilgailuak</translation>
@@ -3827,6 +3828,7 @@
 <translation id="830498451218851433">Erdibitzeko tolestura</translation>
 <translation id="8308653357438598313">Zuzeneko bideo-igorpenak</translation>
 <translation id="8311895354659782580">Higiezinen eskaintzak</translation>
+<translation id="8312841338723044391">ZUZENEAN</translation>
 <translation id="8316555157357957253">Orain erabiltzen</translation>
 <translation id="8319269383395457801">Bizitegien salmentak</translation>
 <translation id="831997045666694187">Arratsaldea</translation>
diff --git a/components/strings/components_strings_fa.xtb b/components/strings/components_strings_fa.xtb
index 5250e54..1b03dc5 100644
--- a/components/strings/components_strings_fa.xtb
+++ b/components/strings/components_strings_fa.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">کاربر:</translation>
 <translation id="6916193791494646625">دلیلی برای بارگیری ارائه دهید (الزامی)</translation>
 <translation id="6917795328362592458">گذرواژه‌ای که اکنون استفاده کردید در سرقت اطلاعات شبکه پیدا شده است. برای حفظ امنیت حساب‌هایتان، «مدیر گذرواژه» توصیه می‌کند گذرواژه‌های ذخیره‌شده‌تان را بررسی کنید.</translation>
+<translation id="6924013822850225188">انتخاب می‌کنید مزایای کارت هنگام تصفیه‌حساب به شما نمایش داده شود یا نه (شرایط بانک اعمال می‌شود)</translation>
 <translation id="6925267999184670015">‏B+‎ آمریکای شمالی</translation>
 <translation id="6926216138694948720">هنر بدن</translation>
 <translation id="692638818576287323">خودروهای تجاری</translation>
@@ -3832,6 +3833,7 @@
 <translation id="830498451218851433">تاخوردگی از وسط</translation>
 <translation id="8308653357438598313">جاری‌سازی ویدیویی زنده</translation>
 <translation id="8311895354659782580">فهرست مستغلات</translation>
+<translation id="8312841338723044391">زنده</translation>
 <translation id="8316555157357957253">هم‌اکنون درحال استفاده است</translation>
 <translation id="8319269383395457801">فروش مسکونی</translation>
 <translation id="831997045666694187">شب</translation>
diff --git a/components/strings/components_strings_fil.xtb b/components/strings/components_strings_fil.xtb
index 17364fbd..0d5ce4a 100644
--- a/components/strings/components_strings_fil.xtb
+++ b/components/strings/components_strings_fil.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">User:</translation>
 <translation id="6916193791494646625">Magbigay ng dahilan para sa pag-download (nire-require)</translation>
 <translation id="6917795328362592458">Nakita sa isang data breach ang password na kakagamit mo lang. Para ma-secure ang iyong mga account, inirerekomenda ng Password Manager na tingnan mo ang iyong mga naka-save na password.</translation>
+<translation id="6924013822850225188">Piliin kung makikita mo ang mga benepisyo ng iyong card sa pag-checkout (nalalapat ang mga tuntunin ng bangko)</translation>
 <translation id="6925267999184670015">North American B+</translation>
 <translation id="6926216138694948720">Body Art</translation>
 <translation id="692638818576287323">Mga Sasakyang Pang-negosyo</translation>
@@ -3832,6 +3833,7 @@
 <translation id="830498451218851433">Fold half</translation>
 <translation id="8308653357438598313">Live na Video Stream</translation>
 <translation id="8311895354659782580">Mga Listing ng Real Estate</translation>
+<translation id="8312841338723044391">LIVE</translation>
 <translation id="8316555157357957253">Ginagamit ngayon</translation>
 <translation id="8319269383395457801">Mga Pagbebenta ng Tirahan</translation>
 <translation id="831997045666694187">Gabi</translation>
diff --git a/components/strings/components_strings_fr-CA.xtb b/components/strings/components_strings_fr-CA.xtb
index 2bea5a5..b1cc45d 100644
--- a/components/strings/components_strings_fr-CA.xtb
+++ b/components/strings/components_strings_fr-CA.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">Utilisateur :</translation>
 <translation id="6916193791494646625">Fournir la raison du téléchargement (obligatoire)</translation>
 <translation id="6917795328362592458">Le mot de passe que vous venez d'utiliser a été trouvé dans un cas de violation de données. Pour sécuriser vos comptes, le Gestionnaire de mots de passe vous recommande de vérifier vos mots de passe enregistrés.</translation>
+<translation id="6924013822850225188">Choisissez si vous voyez les avantages de votre carte lors du paiement (des conditions bancaires s'appliquent)</translation>
 <translation id="6925267999184670015">Amérique du Nord B+</translation>
 <translation id="6926216138694948720">Art corporel</translation>
 <translation id="692638818576287323">Véhicules commerciaux</translation>
@@ -3832,6 +3833,7 @@
 <translation id="830498451218851433">Plier en deux</translation>
 <translation id="8308653357438598313">Diffusion en direct de vidéos</translation>
 <translation id="8311895354659782580">Annonces immobilières</translation>
+<translation id="8312841338723044391">EN DIRECT</translation>
 <translation id="8316555157357957253">Utiliser maintenant</translation>
 <translation id="8319269383395457801">Ventes résidentielles</translation>
 <translation id="831997045666694187">Soirée</translation>
diff --git a/components/strings/components_strings_hi.xtb b/components/strings/components_strings_hi.xtb
index 7df5fbe..fce9766 100644
--- a/components/strings/components_strings_hi.xtb
+++ b/components/strings/components_strings_hi.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">उपयोगकर्ता:</translation>
 <translation id="6916193791494646625">डाउनलोड करने की वजह बताएं (ज़रूरी है)</translation>
 <translation id="6917795328362592458">आपने अभी जो पासवर्ड इस्तेमाल किया है वह डेटा के गलत इस्तेमाल की वजह से लीक हो चुका है. Google के पासवर्ड मैनेजर का सुझाव है कि आप सेव किए गए पासवर्ड की जांच करें. इस तरह, आपके खाते सुरक्षित रहेंगे.</translation>
+<translation id="6924013822850225188">चुनें कि चेकआउट करते समय आपको कार्ड के फ़ायदे दिखे या नहीं (बैंक की शर्तें लागू)</translation>
 <translation id="6925267999184670015">नॉर्थ अमेरिकन B+</translation>
 <translation id="6926216138694948720">बॉडी आर्ट</translation>
 <translation id="692638818576287323">व्यावसायिक वाहन</translation>
@@ -3832,6 +3833,7 @@
 <translation id="830498451218851433">फ़ोल्ड हाल्फ़</translation>
 <translation id="8308653357438598313">लाइव वीडियो स्ट्रीमिंग</translation>
 <translation id="8311895354659782580">रीयल एस्टेट की सूची</translation>
+<translation id="8312841338723044391">लाइव</translation>
 <translation id="8316555157357957253">अभी इस सुविधा का इस्तेमाल किया जा रहा है</translation>
 <translation id="8319269383395457801">रेज़िडेंशियल सेल</translation>
 <translation id="831997045666694187">शाम</translation>
diff --git a/components/strings/components_strings_hr.xtb b/components/strings/components_strings_hr.xtb
index 6a52f39..aab63798 100644
--- a/components/strings/components_strings_hr.xtb
+++ b/components/strings/components_strings_hr.xtb
@@ -508,6 +508,7 @@
 <translation id="192095259937375524">Gumb Dijeli ovu karticu, aktivirajte ga da biste podijelili ovu karticu dijeljenjem veze, izradom QR koda, emitiranjem i na druge načine</translation>
 <translation id="1924727005275031552">Novo</translation>
 <translation id="1927439846988093361">Njega kose</translation>
+<translation id="1935353813610900265">Pošaljite povratne informacije za pretraživanje povijesti pomoću AI-ja</translation>
 <translation id="1935995810530254458">Ipak kopiraj</translation>
 <translation id="1939059826036755332">Automatska slika u slici</translation>
 <translation id="1939175642807587452">Može tražiti dopuštenje za slanje obavijesti</translation>
@@ -831,6 +832,7 @@
 <translation id="2526280916094749336">Spremljene adrese možete upotrijebiti na Googleovim proizvodima. Ta će se adresa spremiti na vaš Google račun, <ph name="ACCOUNT" />.</translation>
 <translation id="2527451058878391043">CVC možete pronaći na prednjoj strani kartice. To je četveroznamenkasti kôd u gornjem desnom kutu iznad broja kartice.</translation>
 <translation id="2529899080962247600">Broj unosa u ovom polju ne smije biti veći od <ph name="MAX_ITEMS_LIMIT" />. Svi će se daljnji unosi zanemariti.</translation>
+<translation id="2530042584066815841">Zaključavanje i upotreba miša</translation>
 <translation id="2533649878691950253">Web-lokaciji je blokiran pristup vašoj točnoj lokaciji jer to obično ne dopuštate</translation>
 <translation id="253493526287553278">Pogledajte pojedinosti o promotivnom kodu</translation>
 <translation id="2535585790302968248">Otvorite novu anonimnu karticu da biste pregledavali privatno</translation>
@@ -856,6 +858,7 @@
 <translation id="255497580849974774">Neka uređaj ostane povezan s punjačem tijekom ažuriranja.</translation>
 <translation id="2556876185419854533">&amp;Poništi uređivanje</translation>
 <translation id="2559566667529177711">Višeslojno</translation>
+<translation id="2565789370591907825">Zaključavanje i upotreba tipkovnice</translation>
 <translation id="2570734079541893434">Upravljajte postavkama</translation>
 <translation id="2573170131138724450">Televizori</translation>
 <translation id="257674075312929031">Grupa</translation>
@@ -903,6 +906,7 @@
 <translation id="2687555958734450033">Najbolja veličina</translation>
 <translation id="2688186765492306706">500 x 760 mm</translation>
 <translation id="2688969097326701645">Da, nastavi</translation>
+<translation id="2690699652723742414">Posljednjih 30 dana</translation>
 <translation id="2691924980723297736">Sigurnosno upozorenje</translation>
 <translation id="2699273987028089219">Dostupan je podizbornik, koristite <ph name="SHORTCUT" /> za navigaciju do dodatnih opcija.</translation>
 <translation id="2701514975700770343">Prema dolje</translation>
@@ -1032,6 +1036,7 @@
 <translation id="297173220375858963">Stolno izdavaštvo</translation>
 <translation id="2972581237482394796">&amp;Vrati poništeno</translation>
 <translation id="2977665033722899841"><ph name="ROW_NAME" />, trenutačno odabrano. <ph name="ROW_CONTENT" /></translation>
+<translation id="2977847223286097084">Zaključavanje i upotreba tipkovnice</translation>
 <translation id="2978824962390592855">Opera</translation>
 <translation id="2979424420072875974">Resursi za pisce</translation>
 <translation id="2980742331521553164">CVC te kartice šifrirat će se i spremiti na vaš Google račun radi brže naplate</translation>
@@ -1104,6 +1109,7 @@
 <translation id="31207688938192855"><ph name="BEGIN_LINK" />Pokušajte pokrenuti Dijagnostiku povezivosti<ph name="END_LINK" />.</translation>
 <translation id="3120807611504813890">Omotnica (lagana)</translation>
 <translation id="3121994479408824897">Otvorite <ph name="DOMAIN" /></translation>
+<translation id="3122696783148405307">Prikaži rezultate iz posljednjih 30 dana</translation>
 <translation id="3126023634486644099">Naljepnice (trajno)</translation>
 <translation id="3133565499688974786"><ph name="SEARCH_ENGINE_NAME" /> je sada vaša zadana tražilica</translation>
 <translation id="3137283076021007034"><ph name="KEYWORD" /> – pretražite <ph name="KEYWORD_SHORT_NAME" /></translation>
@@ -1472,6 +1478,7 @@
 <translation id="3781428340399460090">Jarko ružičasta</translation>
 <translation id="3783418713923659662">Mastercard</translation>
 <translation id="3784372983762739446">Bluetooth uređaji</translation>
+<translation id="378611282717571199">Najbolja podudaranja za upit "<ph name="SEARCH_QUERY" />"</translation>
 <translation id="3789155188480882154">Veličina 16</translation>
 <translation id="3789841737615482174">Instaliraj</translation>
 <translation id="3792100426446126328"><ph name="NAME" /> (<ph name="WIDTH" /> x <ph name="HEIGHT" /> in)</translation>
@@ -1492,6 +1499,7 @@
 <translation id="3815434930383843058">8 x 12 in</translation>
 <translation id="3816482573645936981">Vrijednost (naslijeđena)</translation>
 <translation id="382115839591654906">CVC za karticu <ph name="CARD_NAME" /></translation>
+<translation id="3822492359574576064">zaključavanje i upotreba miša</translation>
 <translation id="3823019343150397277">IBAN</translation>
 <translation id="3823402221513322552">Vašim preglednikom upravlja <ph name="BROWSER_DOMAIN" />, a vašim profilom upravlja <ph name="PROFILE_DOMAIN" /></translation>
 <translation id="382518646247711829">Ako upotrebljavate proxy poslužitelj...</translation>
@@ -1816,6 +1824,7 @@
 <translation id="4438821706955556403">Uobičajena cijena</translation>
 <translation id="4441832193888514600">Zanemareno jer se pravilo može postaviti samo kao korisničko pravilo oblaka.</translation>
 <translation id="4445133368066241428">Popularne teme</translation>
+<translation id="4445964943162061557">Ovo je eksperimentalna značajka i neće uvijek biti bez pogrešaka.</translation>
 <translation id="4449116177348980384">Gumb Upravljaj postavkama web-lokacija, aktivirajte ga za upravljanje dopuštenjima i podacima pohranjenim na web-lokacijama u postavkama Chromea</translation>
 <translation id="4451135742916150903">Može tražiti dopuštenje za povezivanje s HID uređajima</translation>
 <translation id="4451684391620232683">Tekst koji se prikazuje korisniku:</translation>
@@ -1894,6 +1903,7 @@
 <translation id="4631881646528206880">Registracija za virtualnu karticu</translation>
 <translation id="4635278307999235413">Slanje podataka na administratorsku konzolu</translation>
 <translation id="4636930964841734540">Informacije</translation>
+<translation id="4640225694041297329">Prikaži rezultate iz posljednjih 7 dana</translation>
 <translation id="464342062220857295">Značajke pretraživanja</translation>
 <translation id="4644670975240021822">Suprotnim redoslijedom prema dolje</translation>
 <translation id="4646534391647090355">Otvori odmah</translation>
@@ -1973,6 +1983,7 @@
 <translation id="4780366598804516005">Izlazni spremnik s odjeljcima 1</translation>
 <translation id="4785376858512657294">Upravljajte Google računom</translation>
 <translation id="4785689107224900852">Prijeđite na ovu karticu</translation>
+<translation id="4785998536350006000">Pretraživanje upita "<ph name="SEARCH_QUERY" />"</translation>
 <translation id="4786804728079074733">Odbojka</translation>
 <translation id="4787182171088676626">Omotnica (tanko)</translation>
 <translation id="4789704664580239421">Upozorenja o sniženju cijena prikazat će se na otvorenim karticama</translation>
@@ -2010,6 +2021,7 @@
 <translation id="4864801646102013152">Uređenje doma</translation>
 <translation id="4866506163384898554">Pritisnite |<ph name="ACCELERATOR1" />| + |<ph name="ACCELERATOR2" />| da bi se prikazao pokazivač</translation>
 <translation id="4873616204573862158">Naočale</translation>
+<translation id="4873807733347502026">Zaključavanje i upotreba miša</translation>
 <translation id="4876188919622883022">Pojednostavljeni prikaz</translation>
 <translation id="4876305945144899064">Nema korisničkog imena</translation>
 <translation id="4876327226315760474">To znači da značajke web-lokacije trebaju funkcionirati prema očekivanjima, no možda ćete imati manje zaštite pregledavanja.</translation>
@@ -2097,6 +2109,7 @@
 <translation id="5018802455907704660">16 x 20 in</translation>
 <translation id="5019198164206649151">Sigurnosno pohranjivanje u neispravnom je stanju</translation>
 <translation id="5019293549442035120">Spremljene adrese možete koristiti na Googleovim proizvodima. Ta će se adresa spremiti na vaš Google račun, <ph name="USER_EMAIL" />.</translation>
+<translation id="5019952743397118625">Postavljeno je pravilo <ph name="EXTENSION_DEVELOPER_MODE_SETTINGS_POLICY_NAME" />. <ph name="DEVELOPER_TOOLS_AVAILABILITY_POLICY_NAME" /> neće upravljati dostupnošću načina rada razvojnog programera na stranici proširenja.</translation>
 <translation id="5021557570875267742">Praćenje cijena pomoću Chromea</translation>
 <translation id="5023310440958281426">Provjerite pravila svojeg administratora</translation>
 <translation id="5030338702439866405">Izdaje</translation>
@@ -2435,6 +2448,7 @@
 <translation id="5667827081946850877">Audioknjige</translation>
 <translation id="5675650730144413517">Stranica ne funkcionira</translation>
 <translation id="5675809467256309336">Dance i elektronička glazba</translation>
+<translation id="5675959228867414813">Prikaži po datumu</translation>
 <translation id="5677928146339483299">Blokirano</translation>
 <translation id="5678007133659493065">Folija</translation>
 <translation id="5680642791693447368">Trileri, kriminalistički filmovi i filmovi o misterijima</translation>
@@ -2652,6 +2666,7 @@
 <translation id="6108702513636120202">Vaša tražilica u Chromiumu</translation>
 <translation id="6108849843016142864">Gmazovi i vodozemci</translation>
 <translation id="610911394827799129">Na vašem Google računu možda postoje drugi oblici povijesti pregledavanja na stranici <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation>
+<translation id="611018310643025551">Vaša pretraživanja, najbolja podudaranja i sadržaj njihovih stranica šalju se Googleu i mogu ih vidjeti pregledavatelji radi poboljšanja te značajke.</translation>
 <translation id="6116338172782435947">vidjeti tekst i slike koje kopirate u međuspremnik</translation>
 <translation id="6117833587752089929">Fotografija (saten)</translation>
 <translation id="6118782133429281336">Popis izvora je prazan.</translation>
@@ -2908,6 +2923,7 @@
 <translation id="6587923378399804057">Veza koju ste kopirali</translation>
 <translation id="6591833882275308647">Uređaj <ph name="DEVICE_TYPE" /> nije upravljani uređaj</translation>
 <translation id="6596325263575161958">Opcije šifriranja</translation>
+<translation id="6596573334527383067">Prikažite rezultate od jučer</translation>
 <translation id="6597665340361269064">90 stupnjeva</translation>
 <translation id="6598976221101665070">Drame</translation>
 <translation id="6599642189720630047">Praćeni proizvodi</translation>
@@ -3379,6 +3395,7 @@
 <translation id="7489392576326061356">Šamponi i regeneratori</translation>
 <translation id="7495528107193238112">Ovaj je sadržaj blokiran. Obratite se vlasniku web-lokacije da biste riješili problem.</translation>
 <translation id="749865518782565832">Vodoinstalaterske usluge</translation>
+<translation id="7500917112031739411">Prikaži po grupi</translation>
 <translation id="7501663406926337752">Vaša organizacija označila je web-lokaciju koja slijedi</translation>
 <translation id="7507075214339298899">Omotnica br. 9</translation>
 <translation id="7508255263130623398">Vraćeni ID uređaja pravila prazan je ili ne odgovara trenutačnom ID-u uređaja</translation>
@@ -3580,6 +3597,7 @@
 <translation id="7825558994363763489">Mikrovalne pećnice</translation>
 <translation id="782886543891417279">Za Wi-Fi koji upotrebljavate (<ph name="WIFI_NAME" />) možda ćete morati posjetiti stranicu za prijavu.</translation>
 <translation id="7831993212387676366">Što je popis za kupnju?</translation>
+<translation id="7832078172950550575">Povijest pregledavanja možete pretraživati pomoću svakodnevnih izraza kao što su "pizza u blizini" ili "parkovi prikladni za obitelj u centru grada". Vaša pretraživanja, najbolja podudaranja i sadržaj njihovih stranica šalju se Googleu i mogu ih vidjeti pregledavatelji radi poboljšanja te značajke. <ph name="BEGIN_LINK" />Upravljajte postavkom pretraživanja povijesti<ph name="END_LINK" /></translation>
 <translation id="7840103971441592723">Snimanje zaslona je počelo</translation>
 <translation id="784137052867620416">Uvidi za Shopping</translation>
 <translation id="784404208867107517">Grupirana povijest</translation>
@@ -3876,6 +3894,7 @@
 <translation id="8398335999901363925">Načini plaćanja dostupni za unos dodirom otvoreni su preko cijelog zaslona.</translation>
 <translation id="8398446215576328011">Vrati primijenjena pravila</translation>
 <translation id="8398790343843005537">Pronađite svoj telefon</translation>
+<translation id="8399276468426899527">zaključavanje i upotreba tipkovnice</translation>
 <translation id="8400929824946688748">Poslovi i obrazovanje</translation>
 <translation id="8403506619177967839">"Fanfic" književnost</translation>
 <translation id="8405579342203358118">U postavkama Chromea možete upravljati time koji će se podaci sinkronizirati</translation>
@@ -4218,6 +4237,7 @@
 <translation id="9089260154716455634">Pravilo za prekid rada:</translation>
 <translation id="9090218457905363312">Reggae i karipska glazba</translation>
 <translation id="9090243919347147717">Privici</translation>
+<translation id="9090548458280093580">Pretražujte svoju povijesti pomoću AI-ja</translation>
 <translation id="9090993752571911635">Davatelji internetskih usluga (ISP-ovi)</translation>
 <translation id="9093723786115107672">Odjeća za spavanje</translation>
 <translation id="9094544726794842788">Palac dolje otvara obrazac za slanje detaljnih povratnih informacija o tome zašto vam se ti rezultati ne sviđaju</translation>
diff --git a/components/strings/components_strings_hy.xtb b/components/strings/components_strings_hy.xtb
index 711b004..b3e3dd6f 100644
--- a/components/strings/components_strings_hy.xtb
+++ b/components/strings/components_strings_hy.xtb
@@ -4294,6 +4294,7 @@
 <translation id="920643408853370361">Ճանապարհորդական ապահովագրություն</translation>
 <translation id="9207861905230894330">Չհաջողվեց ավելացնել հոդվածը:</translation>
 <translation id="9210825002219699214">Օդային ճանապարհորդություն</translation>
+<translation id="9211461151375991073">Մուտքագրեք @ նշանը՝ <ph name="FEATURED_SEARCH_LIST" /> կայքերում որոնելու համար</translation>
 <translation id="9213433120051936369">Անհատականացրեք արտաքին տեսքը</translation>
 <translation id="9215416866750762878">Ծրագրերից մեկը Chrome-ին թույլ չի տալիս անվտանգ միանալ այս կայքին</translation>
 <translation id="92178312226016010">Դուք հետագծում եք այս ապրանքը։</translation>
diff --git a/components/strings/components_strings_id.xtb b/components/strings/components_strings_id.xtb
index 2ff7f849..f1b215eb 100644
--- a/components/strings/components_strings_id.xtb
+++ b/components/strings/components_strings_id.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">Pengguna:</translation>
 <translation id="6916193791494646625">Berikan alasan mendownload (wajib)</translation>
 <translation id="6917795328362592458">Sandi yang baru saja Anda gunakan terekspos dalam pelanggaran data. Untuk mengamankan akun Anda, Pengelola Sandi merekomendasikan untuk memeriksa sandi tersimpan Anda.</translation>
+<translation id="6924013822850225188">Pilih apakah Anda akan melihat manfaat kartu saat checkout (persyaratan bank berlaku)</translation>
 <translation id="6925267999184670015">Amerika Utara B+</translation>
 <translation id="6926216138694948720">Seni Rajah dan Tindik</translation>
 <translation id="692638818576287323">Kendaraan Niaga</translation>
@@ -3830,6 +3831,7 @@
 <translation id="830498451218851433">Lipatan setengah</translation>
 <translation id="8308653357438598313">Streaming Video Live</translation>
 <translation id="8311895354659782580">Listingan Real Estat</translation>
+<translation id="8312841338723044391">LIVE</translation>
 <translation id="8316555157357957253">Sedang digunakan sekarang</translation>
 <translation id="8319269383395457801">Penjualan Rumah</translation>
 <translation id="831997045666694187">Sore</translation>
diff --git a/components/strings/components_strings_is.xtb b/components/strings/components_strings_is.xtb
index 56bf7da..b39ac64 100644
--- a/components/strings/components_strings_is.xtb
+++ b/components/strings/components_strings_is.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">Notandi:</translation>
 <translation id="6916193791494646625">Gefðu upp ástæðu niðurhals (áskilið)</translation>
 <translation id="6917795328362592458">Aðgangsorðið sem þú varst að nota fannst í öryggisbroti. Aðgangsorðastjórnun mælir með að þú athugir vistuð aðgangsorð til að tryggja öryggi reikninganna þinna.</translation>
+<translation id="6924013822850225188">Veldu hvort þú sérð fríðindi kortsins þíns við greiðslu (skilmálar banka gilda)</translation>
 <translation id="6925267999184670015">B+ fyrir Norður Ameríku</translation>
 <translation id="6926216138694948720">Líkamsskreyting</translation>
 <translation id="692638818576287323">Flutningabifreiðir</translation>
@@ -3832,6 +3833,7 @@
 <translation id="830498451218851433">Brotið í miðju</translation>
 <translation id="8308653357438598313">Myndstraumur í beinni</translation>
 <translation id="8311895354659782580">Fasteignaauglýsingar</translation>
+<translation id="8312841338723044391">Í BEINNI</translation>
 <translation id="8316555157357957253">Í notkun núna</translation>
 <translation id="8319269383395457801">Sala íbúðarhúsnæðis</translation>
 <translation id="831997045666694187">Kvöld</translation>
diff --git a/components/strings/components_strings_iw.xtb b/components/strings/components_strings_iw.xtb
index b8593aa..dfad14c3 100644
--- a/components/strings/components_strings_iw.xtb
+++ b/components/strings/components_strings_iw.xtb
@@ -566,6 +566,7 @@
 <translation id="2036983605131262583">גליל חלופי</translation>
 <translation id="2040463897538655645">אחסון נשלף</translation>
 <translation id="2040894699575719559">המיקום נחסם</translation>
+<translation id="2041788246978549610">שימוש במיקרופונים הזמינים (<ph name="MICS_COUNT" />)</translation>
 <translation id="2042213636306070719">מגש 7</translation>
 <translation id="204357726431741734">‏כדי להשתמש בסיסמאות השמורות בחשבון Google, עליך להיכנס שוב לחשבון</translation>
 <translation id="2045871135676061132">מעטפה אישית</translation>
@@ -885,6 +886,7 @@
 <translation id="2655752832536625875">חדר אמבטיה</translation>
 <translation id="2657637947725373811">{0,plural, =1{להעביר את הקובץ הסודי?}one{להעביר את הקבצים הסודיים?}two{להעביר את הקבצים הסודיים?}other{להעביר את הקבצים הסודיים?}}</translation>
 <translation id="2658843814961855121">דיני עבודה והעסקה</translation>
+<translation id="2658944305627908367">לא יתבצע עיבוד לעסקאות שחורגות מהיתרה שלך</translation>
 <translation id="2660779039299703961">אירוע</translation>
 <translation id="2664887757054927933">{COUNT,plural, =0{אין}=1{סיסמה אחת (עבור <ph name="DOMAIN_LIST" />)}=2{שתי סיסמאות (עבור <ph name="DOMAIN_LIST" />)}one{סיסמה אחת (עבור <ph name="DOMAIN_LIST" />)}other{# סיסמאות (עבור <ph name="DOMAIN_LIST" />)}}</translation>
 <translation id="2666092431469916601">למעלה</translation>
@@ -1081,6 +1083,7 @@
 <translation id="3090667236485488075">Glass</translation>
 <translation id="3095940652251934233">Statement</translation>
 <translation id="3098513225387949945">המערכת התעלמה מהמדיניות כי רשימת ההשבתה מכילה תבנית ששווה ל-'*', שזהה להשבתת המדיניות.</translation>
+<translation id="3099619114405539473">שימוש במצלמות הזמינות (<ph name="CAMERAS_COUNT" />)</translation>
 <translation id="3102312643185441063">חיסכון</translation>
 <translation id="3103188521861412364">מניות ואג"ח</translation>
 <translation id="3105172416063519923">מזהה נכס:</translation>
@@ -1357,6 +1360,7 @@
 <translation id="3583757800736429874">&amp;ביצוע מחדש של העברה</translation>
 <translation id="3584299510153766161">שני ניקובים בחלק התחתון</translation>
 <translation id="3584755835709800788">סרטי מדע בדיוני ופנטזיה</translation>
+<translation id="3585455899094692781">שימוש במצלמות הזמינות והזזה שלהן (<ph name="CAMERAS_COUNT" />)</translation>
 <translation id="3586833803451155175">Wet Film</translation>
 <translation id="3586931643579894722">הסתרת הפרטים</translation>
 <translation id="3587738293690942763">אמצעי</translation>
diff --git a/components/strings/components_strings_ja.xtb b/components/strings/components_strings_ja.xtb
index f9a9436..e6aebd8 100644
--- a/components/strings/components_strings_ja.xtb
+++ b/components/strings/components_strings_ja.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">ユーザー:</translation>
 <translation id="6916193791494646625">ダウンロードする理由をお知らせください(必須)</translation>
 <translation id="6917795328362592458">たった今使用したパスワードがデータ侵害で検出されました。パスワード マネージャーでは、アカウントを保護するために保存したパスワードを確認することをおすすめします。</translation>
+<translation id="6924013822850225188">購入手続き時にカードの特典を表示するかどうかを選択します(カード発行会社の利用規約が適用されます)</translation>
 <translation id="6925267999184670015">北米 B+</translation>
 <translation id="6926216138694948720">ボディアート</translation>
 <translation id="692638818576287323">商用自動車</translation>
@@ -3833,6 +3834,7 @@
 <translation id="830498451218851433">2 つ折り</translation>
 <translation id="8308653357438598313">ライブ動画ストリーミング</translation>
 <translation id="8311895354659782580">不動産情報</translation>
+<translation id="8312841338723044391">ライブ</translation>
 <translation id="8316555157357957253">現在使用中</translation>
 <translation id="8319269383395457801">住宅販売</translation>
 <translation id="831997045666694187">夕方</translation>
diff --git a/components/strings/components_strings_ko.xtb b/components/strings/components_strings_ko.xtb
index 9fc9b443..f5e2d20 100644
--- a/components/strings/components_strings_ko.xtb
+++ b/components/strings/components_strings_ko.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">사용자:</translation>
 <translation id="6916193791494646625">다운로드 사유 입력(필수)</translation>
 <translation id="6917795328362592458">방금 사용한 비밀번호가 정보 유출로 인해 노출된 것으로 확인됩니다. 계정 보호를 위해 비밀번호 관리자에서 저장된 비밀번호를 확인하시기 바랍니다.</translation>
+<translation id="6924013822850225188">결제 시 카드 혜택을 표시할지 선택합니다(은행 약관 적용).</translation>
 <translation id="6925267999184670015">북미 B+</translation>
 <translation id="6926216138694948720">바디아트</translation>
 <translation id="692638818576287323">상업용 차량</translation>
@@ -3831,6 +3832,7 @@
 <translation id="830498451218851433">폴드 하프</translation>
 <translation id="8308653357438598313">라이브 동영상 스트리밍</translation>
 <translation id="8311895354659782580">부동산 매물</translation>
+<translation id="8312841338723044391">라이브</translation>
 <translation id="8316555157357957253">지금 사용 중</translation>
 <translation id="8319269383395457801">주택 판매</translation>
 <translation id="831997045666694187">저녁</translation>
diff --git a/components/strings/components_strings_lo.xtb b/components/strings/components_strings_lo.xtb
index 9a6df8c..803d7dd 100644
--- a/components/strings/components_strings_lo.xtb
+++ b/components/strings/components_strings_lo.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">ຜູ້​ໃຊ້​:</translation>
 <translation id="6916193791494646625">ໃຫ້ເຫດຜົນສໍາລັບການດາວໂຫຼດ (ຈຳເປັນ)</translation>
 <translation id="6917795328362592458">ພົບລະຫັດຜ່ານທີ່ທ່ານຫາກໍໃຊ້ນັ້ນໃນການຮົ່ວໄຫຼຂໍ້ມູນ. ເພື່ອຮັກສາຄວາມປອດໄພໃຫ້ບັນຊີຂອງທ່ານ, ຕົວຈັດການລະຫັດຜ່ານແນະນຳໃຫ້ກວດສອບລະຫັດຜ່ານທີ່ບັນທຶກໄວ້ຂອງທ່ານ.</translation>
+<translation id="6924013822850225188">ເລືອກວ່າທ່ານຈະເບິ່ງສິດທິປະໂຫຍດບັດຂອງທ່ານຢູ່ຈຸດຈ່າຍເງິນຫຼືບໍ່ (ໂດຍເປັນໄປຕາມຂໍ້ກຳນົດຂອງທະນາຄານ)</translation>
 <translation id="6925267999184670015">North American B+</translation>
 <translation id="6926216138694948720">ສິນລະປະເທິງຮ່າງກາຍ</translation>
 <translation id="692638818576287323">ການຂັບລົດທາງການຄ້າ</translation>
@@ -3832,6 +3833,7 @@
 <translation id="830498451218851433">ພັບເຄິ່ງ</translation>
 <translation id="8308653357438598313">ການສະຕຣີມວິດີໂອສົດ</translation>
 <translation id="8311895354659782580">ລາຍຊື່ອະສັງຫາລິມະຊັບ</translation>
+<translation id="8312841338723044391">ສົດ</translation>
 <translation id="8316555157357957253">ກຳລັງໃຊ້ຕອນນີ້</translation>
 <translation id="8319269383395457801">ການຂາຍທີ່ຢູ່ອາໄສ</translation>
 <translation id="831997045666694187">ຕອນແລງ</translation>
diff --git a/components/strings/components_strings_mn.xtb b/components/strings/components_strings_mn.xtb
index 47bd189..d48e7cc 100644
--- a/components/strings/components_strings_mn.xtb
+++ b/components/strings/components_strings_mn.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">Хэрэглэгч:</translation>
 <translation id="6916193791494646625">Татаж буй шалтгааныг өгнө үү (шаардлагатай)</translation>
 <translation id="6917795328362592458">Таны дөнгөж сая ашигласан нууц үгийг өгөгдлийн зөрчлөөс оллоо. Таны бүртгэлүүдийг хамгаалахын тулд Нууц үгний менежер хадгалсан нууц үгнүүдээ шалгахыг зөвлөж байна.</translation>
+<translation id="6924013822850225188">Та тооцоо хийх үедээ картынхаа үр өгөөжийг харах эсэхийг сонгоно уу (банкны нөхцөл хэрэгжинэ)</translation>
 <translation id="6925267999184670015">Хойд Америкийн B+</translation>
 <translation id="6926216138694948720">Боди арт</translation>
 <translation id="692638818576287323">Худалдааны тээврийн хэрэгслүүд</translation>
@@ -3832,6 +3833,7 @@
 <translation id="830498451218851433">Хагас нугалаа</translation>
 <translation id="8308653357438598313">Шууд видео дамжуулалт</translation>
 <translation id="8311895354659782580">Үл хөдлөх хөрөнгийн жагсаалтууд</translation>
+<translation id="8312841338723044391">ШУУД</translation>
 <translation id="8316555157357957253">Одоо ашиглаж байна</translation>
 <translation id="8319269383395457801">Орон сууцны борлуулалтууд</translation>
 <translation id="831997045666694187">Үдэш</translation>
diff --git a/components/strings/components_strings_mr.xtb b/components/strings/components_strings_mr.xtb
index 9223275..d50e911dc 100644
--- a/components/strings/components_strings_mr.xtb
+++ b/components/strings/components_strings_mr.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">वापरकर्ता:</translation>
 <translation id="6916193791494646625">डाउनलोड करण्याचे कारण द्या (आवश्यक)</translation>
 <translation id="6917795328362592458">तुम्ही नुकताच वापरलेला पासवर्ड डेटा भंगामध्ये आढळला होता. तुमची खाती सुरक्षित करण्यासाठी, पासवर्ड व्यवस्थापक तुमचे सेव्ह केलेले पासवर्ड तपासण्याची शिफारस करतो.</translation>
+<translation id="6924013822850225188">चेकआउट करताना तुम्हाला कार्डचे फायदे दिसणार की नाही हे निवडा (बँकच्या अटी लागू)</translation>
 <translation id="6925267999184670015">North American B+</translation>
 <translation id="6926216138694948720">बॉडी आर्ट</translation>
 <translation id="692638818576287323">व्यावसायिक वाहने</translation>
@@ -3832,6 +3833,7 @@
 <translation id="830498451218851433">फोल्ड हाफ</translation>
 <translation id="8308653357438598313">लाइव्ह व्हिडिओ स्ट्रीम करणे</translation>
 <translation id="8311895354659782580">रीअल इस्टेट सूची</translation>
+<translation id="8312841338723044391">लाइव्ह</translation>
 <translation id="8316555157357957253">आता वापरत आहे</translation>
 <translation id="8319269383395457801">निवासी विक्री</translation>
 <translation id="831997045666694187">संध्याकाळी</translation>
@@ -4284,6 +4286,7 @@
 <translation id="920643408853370361">प्रवास विमा</translation>
 <translation id="9207861905230894330">लेख जोडण्यात अयशस्वी.</translation>
 <translation id="9210825002219699214">विमान प्रवास</translation>
+<translation id="9211461151375991073"><ph name="FEATURED_SEARCH_LIST" /> शोधण्यासाठी @ टाइप करा</translation>
 <translation id="9213433120051936369">स्वरूप कस्टमाइझ करा</translation>
 <translation id="9215416866750762878">एक ॲप्लिकेशन Chrome ला या साइटशी सुरक्षितपणे कनेक्ट करण्यापासून थांबवत आहे</translation>
 <translation id="92178312226016010">तुम्ही हे उत्पादन ट्रॅक करत आहात.</translation>
diff --git a/components/strings/components_strings_ms.xtb b/components/strings/components_strings_ms.xtb
index ef39543..b1dc547 100644
--- a/components/strings/components_strings_ms.xtb
+++ b/components/strings/components_strings_ms.xtb
@@ -4288,6 +4288,7 @@
 <translation id="920643408853370361">Insurans Perjalanan</translation>
 <translation id="9207861905230894330">Gagal menambahkan artikel.</translation>
 <translation id="9210825002219699214">Perjalanan Udara</translation>
+<translation id="9211461151375991073">Taip @ untuk membuat carian <ph name="FEATURED_SEARCH_LIST" /></translation>
 <translation id="9213433120051936369">Sesuaikan rupa</translation>
 <translation id="9215416866750762878">Satu aplikasi menghalang Chrome daripada menyambung ke tapak ini dengan selamat</translation>
 <translation id="92178312226016010">Anda menjejaki produk ini.</translation>
diff --git a/components/strings/components_strings_my.xtb b/components/strings/components_strings_my.xtb
index 76f8bc9..7dee0df 100644
--- a/components/strings/components_strings_my.xtb
+++ b/components/strings/components_strings_my.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">အသုံးပြုသူ:</translation>
 <translation id="6916193791494646625">ဒေါင်းလုဒ်လုပ်ခြင်းအတွက် အကြောင်းရင်းပေးရန် (လိုအပ်သည်)</translation>
 <translation id="6917795328362592458">သင်သုံးလိုက်သောစကားဝှက်ကို ဒေတာကျိုးပေါက်မှုတွင် တွေ့ရှိထားသည်။ သင့်အကောင့်များကို လုံခြုံစေရန် ‘စကားဝှက်မန်နေဂျာ’ က သင်သိမ်းထားသော စကားဝှက်များကို စစ်ဆေးရန် အကြံပြုပါသည်။</translation>
+<translation id="6924013822850225188">ငွေရှင်းသည့်အခါ သင့်ကတ်အကျိုးခံစားခွင့်များကို မြင်ရခြင်း ရှိ၊ မရှိ ရွေးနိုင်သည် (ဘဏ်စည်းမျဉ်းများ ရှိသည်)</translation>
 <translation id="6925267999184670015">မြောက်အမေရိကန် B+</translation>
 <translation id="6926216138694948720">ကိုယ်ပေါ်အလှဆင်ခြင်း အနုပညာ</translation>
 <translation id="692638818576287323">လုပ်ငန်းသုံးယာဉ်</translation>
@@ -3834,6 +3835,7 @@
 <translation id="830498451218851433">တစ်ဝက် ခေါက်ရန်</translation>
 <translation id="8308653357438598313">ဗီဒီယိုတိုက်ရိုက်လွှင့်ခြင်း</translation>
 <translation id="8311895354659782580">အိမ်ခြံမြေစာရင်း</translation>
+<translation id="8312841338723044391">တိုက်ရိုက်ထုတ်လွှင့်မှု</translation>
 <translation id="8316555157357957253">ယခု သုံးနေသည်</translation>
 <translation id="8319269383395457801">လူနေရပ်ကွက်တွင်းအိမ် အရောင်း</translation>
 <translation id="831997045666694187">ညနေ</translation>
diff --git a/components/strings/components_strings_ne.xtb b/components/strings/components_strings_ne.xtb
index c5d5031..d43b50c 100644
--- a/components/strings/components_strings_ne.xtb
+++ b/components/strings/components_strings_ne.xtb
@@ -3061,6 +3061,7 @@
 <translation id="6915804003454593391">प्रयोगकर्ता:</translation>
 <translation id="6916193791494646625">डाउनलोड गर्नुको कारण उल्लेख गर्नुहोस् (अनिवार्य)</translation>
 <translation id="6917795328362592458">तपाईंले भर्खरै प्रयोग गर्नुभएको पासवर्ड चोरी भएको डेटाको सङ्ग्रहमा भेटिएको छ। तपाईंका खाताको सुरक्षार्थ पासवर्ड म्यानेजर तपाईंले सेभ गरेका पासवर्डहरू सुरक्षित छन् कि छैनन् जाँच्न सिफारिस गर्छ।</translation>
+<translation id="6924013822850225188">चेकआउट गर्ने बेलामा तपाईंलाई तपाईंका कार्डका लाभहरू देखाउने कि नदेखाउने भन्ने कुरा छनौट गर्नुहोस् (बैंकका सर्तहरू लागू हुन्छन्)</translation>
 <translation id="6925267999184670015">North American B+</translation>
 <translation id="6926216138694948720">शरीरमा बनाइने कला</translation>
 <translation id="692638818576287323">व्यावसायिक प्रयोजनका लागि प्रयोग हुने सवारी साधन</translation>
@@ -3830,6 +3831,7 @@
 <translation id="830498451218851433">आधा फोल्ड</translation>
 <translation id="8308653357438598313">लाइभ भिडियो स्ट्रिमिङ</translation>
 <translation id="8311895354659782580">घरजग्गाको सूची</translation>
+<translation id="8312841338723044391">लाइभ</translation>
 <translation id="8316555157357957253">अहिले प्रयोग गरिँदै छ</translation>
 <translation id="8319269383395457801">रेसिडेन्सियल सेल</translation>
 <translation id="831997045666694187">साँझ</translation>
diff --git a/components/strings/components_strings_nl.xtb b/components/strings/components_strings_nl.xtb
index fd1784d..f06dc24 100644
--- a/components/strings/components_strings_nl.xtb
+++ b/components/strings/components_strings_nl.xtb
@@ -4279,6 +4279,7 @@
 <translation id="920643408853370361">Reisverzekeringen</translation>
 <translation id="9207861905230894330">Kan artikel niet toevoegen.</translation>
 <translation id="9210825002219699214">Vliegreizen</translation>
+<translation id="9211461151375991073">Typ @ om te zoeken op <ph name="FEATURED_SEARCH_LIST" /></translation>
 <translation id="9213433120051936369">Weergave aanpassen</translation>
 <translation id="9215416866750762878">Een app voorkomt dat Chrome veilig verbinding kan maken met deze site</translation>
 <translation id="92178312226016010">Je volgt dit product.</translation>
diff --git a/components/strings/components_strings_ro.xtb b/components/strings/components_strings_ro.xtb
index 5ad1202..bc59a89 100644
--- a/components/strings/components_strings_ro.xtb
+++ b/components/strings/components_strings_ro.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">Utilizator:</translation>
 <translation id="6916193791494646625">Indică motivul descărcării (obligatoriu)</translation>
 <translation id="6917795328362592458">Parola pe care tocmai ai folosit-o a fost găsită într-o încălcare a securității datelor. Pentru a-ți proteja conturile, Managerul de parole îți recomandă să verifici parolele salvate.</translation>
+<translation id="6924013822850225188">Alege dacă vezi beneficiile cardului la finalizarea achiziției (se aplică condițiile bancare)</translation>
 <translation id="6925267999184670015">North American B+</translation>
 <translation id="6926216138694948720">Artă corporală</translation>
 <translation id="692638818576287323">Vehicule comerciale</translation>
@@ -3832,6 +3833,7 @@
 <translation id="830498451218851433">Îndoire la jumătate</translation>
 <translation id="8308653357438598313">Streaming video live</translation>
 <translation id="8311895354659782580">Liste de imobiliare</translation>
+<translation id="8312841338723044391">LIVE</translation>
 <translation id="8316555157357957253">Se folosește acum</translation>
 <translation id="8319269383395457801">Vânzări de imobile rezidențiale</translation>
 <translation id="831997045666694187">Seara</translation>
diff --git a/components/strings/components_strings_ru.xtb b/components/strings/components_strings_ru.xtb
index 825a9715..5b6d960 100644
--- a/components/strings/components_strings_ru.xtb
+++ b/components/strings/components_strings_ru.xtb
@@ -3062,6 +3062,7 @@
 <translation id="6915804003454593391">Пользователь:</translation>
 <translation id="6916193791494646625">Укажите, зачем вы хотите скачать файл (обязательно)</translation>
 <translation id="6917795328362592458">Пароль, который вы только что использовали, был раскрыт в результате утечки данных. Чтобы защитить свои аккаунты, проверьте сохраненные пароли в Менеджере паролей.</translation>
+<translation id="6924013822850225188">Выберите, показывать ли преимущества карты при оформлении покупки (действуют условия банка)</translation>
 <translation id="6925267999184670015">North American B+</translation>
 <translation id="6926216138694948720">Боди-арт</translation>
 <translation id="692638818576287323">Коммерческий транспорт</translation>
@@ -3831,6 +3832,7 @@
 <translation id="830498451218851433">Фальцовка книжкой</translation>
 <translation id="8308653357438598313">Онлайн-видеотрансляции</translation>
 <translation id="8311895354659782580">Недвижимость и земельные участки</translation>
+<translation id="8312841338723044391">ПРЯМОЙ ЭФИР</translation>
 <translation id="8316555157357957253">Разрешение используется сейчас</translation>
 <translation id="8319269383395457801">Продажа жилья</translation>
 <translation id="831997045666694187">До вечера</translation>
diff --git a/components/strings/components_strings_si.xtb b/components/strings/components_strings_si.xtb
index 93bcf3c..80dfcf3 100644
--- a/components/strings/components_strings_si.xtb
+++ b/components/strings/components_strings_si.xtb
@@ -508,6 +508,7 @@
 <translation id="192095259937375524">මෙම පටිත්ත බෙදා ගන්න බොත්තම, සබැඳිය බෙදා ගැනීමෙන්, QR කේතයක් තැනීමෙන්, විකාශය කිරීමෙන්, සහ තවත් දේ මගින් මෙම පටිත්ත බෙදා ගැනීමට සක්‍රිය කරන්න</translation>
 <translation id="1924727005275031552">නව</translation>
 <translation id="1927439846988093361">හිසකෙස් රැකවරණය</translation>
+<translation id="1935353813610900265">AI බලගන්වන ඉතිහාස සෙවීම සඳහා ප්‍රතිපෝෂණය යවන්න</translation>
 <translation id="1935995810530254458">කෙසේ වෙතත් පිටපත් කරන්න</translation>
 <translation id="1939059826036755332">ස්වයංක්‍රීය පින්තූරය තුළ පින්තූරය</translation>
 <translation id="1939175642807587452">දැනුම්දීම් යැවීමට ඉල්ලිය හැකිය</translation>
@@ -831,6 +832,7 @@
 <translation id="2526280916094749336">ඔබට Google නිෂ්පාදන හරහා සුරැකි ලිපින භාවිත කළ හැක. මෙම ලිපිනය ඔබේ Google ගිණුමේ, <ph name="ACCOUNT" /> සුරකිනු ලැබේ.</translation>
 <translation id="2527451058878391043">ඔබේ CVC ඔබේ කාඩ්පතෙහි ඉදිරිපස ඇත. එය ඔබේ කාඩ්පත් අංකයට ඉහළින් ඉහළ දකුණේ ඇති සංඛ්‍යා 4 කේතයයි.</translation>
 <translation id="2529899080962247600">මෙම ක්ෂේත්‍රයට <ph name="MAX_ITEMS_LIMIT" />කට වඩා වැඩි ඇතුළත් කිරීම් තිබිය යුතුය. සියලු වැඩිදුර ඇතුළත් කිරීම් නොසලකා හරිනු ඇත.</translation>
+<translation id="2530042584066815841">මූසික අගුල සහ භාවිතය</translation>
 <translation id="2533649878691950253">ඔබ සාමාන්‍යයෙන් මෙයට ඉඩ නොදෙන නිසා ඔබගේ ඉතා නිවැරදි ස්ථානය දැන ගැනීමෙන් මෙම අඩවිය අවහිර කර ඇත</translation>
 <translation id="253493526287553278">ප්‍රවර්ධන කේත විස්තර බලන්න</translation>
 <translation id="2535585790302968248">පුද්ගලිකව බ්‍රවුස් කිරීමට නව අප්‍රකට ටැබයක් විවෘත කරන්න</translation>
@@ -856,6 +858,7 @@
 <translation id="255497580849974774">යාවත්කාලීන කිරීමේ දී ඔබේ උපාංගය චාලකයකට සම්බන්ධ කර තබා ගන්න.</translation>
 <translation id="2556876185419854533">සංස්කරණය &amp;පසුගමනය කරන්න</translation>
 <translation id="2559566667529177711">බහු ස්ථර</translation>
+<translation id="2565789370591907825">යතුරු පුවරු අගුල සහ භාවිතය</translation>
 <translation id="2570734079541893434">සැකසීම් කළමනාකරණය කරන්න</translation>
 <translation id="2573170131138724450">රුපවාහිනී</translation>
 <translation id="257674075312929031">සමූහය</translation>
@@ -903,6 +906,7 @@
 <translation id="2687555958734450033">හොඳින්ම ගැළපේ</translation>
 <translation id="2688186765492306706">මිමි 500 x 760</translation>
 <translation id="2688969097326701645">ඔව්, දිගටම කරගෙන යන්න</translation>
+<translation id="2690699652723742414">පසුගිය දින 30</translation>
 <translation id="2691924980723297736">ආරක්‍ෂක අවවාදය</translation>
 <translation id="2699273987028089219">උප මෙනුව තිබේ, අතිරේක විකල්ප වෙත සංචාලනය කිරීමට <ph name="SHORTCUT" /> භාවිතා කරන්න.</translation>
 <translation id="2701514975700770343">මුහුණ පහළට</translation>
@@ -1032,6 +1036,7 @@
 <translation id="297173220375858963">ඩෙස්ක්ටොප් ප්‍රකාශනය</translation>
 <translation id="2972581237482394796">&amp;නැවත කරන්න</translation>
 <translation id="2977665033722899841"><ph name="ROW_NAME" />, දැනට තෝරා ඇත. <ph name="ROW_CONTENT" /></translation>
+<translation id="2977847223286097084">ඔබේ යතුරු පුවරුව අගුලු දමා භාවිත කරන්න</translation>
 <translation id="2978824962390592855">ඔපෙරා</translation>
 <translation id="2979424420072875974">ලියන්නන්ගේ සම්පත්</translation>
 <translation id="2980742331521553164">මෙම කාඩ්පතේ CVC සංකේතනය කර වේගවත් පිටවීම සඳහා ඔබේ Google ගිණුමේ සුරකිනු ඇත</translation>
@@ -1104,6 +1109,7 @@
 <translation id="31207688938192855"><ph name="BEGIN_LINK" />සම්බන්ධතා දෝෂහරණ ධාවනය කිරීමට උත්සාහ කරන්න<ph name="END_LINK" />.</translation>
 <translation id="3120807611504813890">ලියුම් කවරය (සැහැල්ලු)</translation>
 <translation id="3121994479408824897"><ph name="DOMAIN" /> වෙත යන්න</translation>
+<translation id="3122696783148405307">පසුගිය දින 30 න් ප්‍රතිඵල පෙන්වන්න</translation>
 <translation id="3126023634486644099">ලේබල් (ස්ථිර)</translation>
 <translation id="3133565499688974786"><ph name="SEARCH_ENGINE_NAME" /> දැන් ඔබේ පෙරනිමි සෙවීම් යන්ත්‍රය වේ</translation>
 <translation id="3137283076021007034"><ph name="KEYWORD" /> - <ph name="KEYWORD_SHORT_NAME" /> සෙවීම</translation>
@@ -1473,6 +1479,7 @@
 <translation id="3781428340399460090">උණුසුම් රෝස</translation>
 <translation id="3783418713923659662">මාස්ටර්කාඩ්</translation>
 <translation id="3784372983762739446">බ්ලූටූත් උපාංග</translation>
+<translation id="378611282717571199">"<ph name="SEARCH_QUERY" />" සඳහා හොඳම ගැළපීම්</translation>
 <translation id="3789155188480882154">ප්‍රමාණය 16</translation>
 <translation id="3789841737615482174">ස්ථාපනය</translation>
 <translation id="3792100426446126328"><ph name="NAME" /> (අඟ <ph name="WIDTH" /> x <ph name="HEIGHT" />)</translation>
@@ -1493,6 +1500,7 @@
 <translation id="3815434930383843058">අඟ 8 x 12</translation>
 <translation id="3816482573645936981">අගය (ඉක්මවා ඇත)</translation>
 <translation id="382115839591654906"><ph name="CARD_NAME" /> සඳහා CVC</translation>
+<translation id="3822492359574576064">මූසික අගුල සහ භාවිතය</translation>
 <translation id="3823019343150397277">IBAN</translation>
 <translation id="3823402221513322552">ඔබේ බ්‍රව්සරය කළමනාකරණය කරන්නේ <ph name="BROWSER_DOMAIN" /> සහ ඔබේ පැතිකඩ කළමනාකරණය කරන්නේ <ph name="PROFILE_DOMAIN" /> විසිනි</translation>
 <translation id="382518646247711829">ඔබ ප්‍රොක්සි සර්වරය භාවිතා කළහොත්...</translation>
@@ -1817,6 +1825,7 @@
 <translation id="4438821706955556403">නියමානුකූල මිල</translation>
 <translation id="4441832193888514600">ප්‍රතිපත්තිය ක්ලවුඩ් පරිශීලක ප්‍රතිපත්තියක් ලෙස පමණක් සැකසිය හැකි බැවින් නොසලකා හරින ලදී.</translation>
 <translation id="4445133368066241428">ජනප්‍රිය මාතෘකා</translation>
+<translation id="4445964943162061557">මෙය පරීක්‍ෂණාත්මක විශේෂාංගයක් වන අතර සැම විටම නිවැරදි විය නොහැක.</translation>
 <translation id="4449116177348980384">අඩවි සැකසීම් කළමනාකරණය කරන්න බොත්තම, Chrome සැකසීම් තුළ අඩවි හරහා ගබඩා කර ඇති අවසර සහ දත්ත කළමනාකරණය කිරීමට සක්‍රිය කරන්න</translation>
 <translation id="4451135742916150903">HID උපාංග වෙත සම්බන්ධ වීමට ඉල්ලිය හැකිය</translation>
 <translation id="4451684391620232683">පරිශීලක වෙත ඉදිරිපත් කරන ලද පෙළ:</translation>
@@ -1895,6 +1904,7 @@
 <translation id="4631881646528206880">අතථ්‍ය කාඩ්පත ලියාපදිංචි කිරීම</translation>
 <translation id="4635278307999235413">පරිපාලක කොන්සෝලය වෙත දත්ත යැවීම</translation>
 <translation id="4636930964841734540">තතු</translation>
+<translation id="4640225694041297329">පසුගිය දින 7 න් ප්‍රතිඵල පෙන්වන්න</translation>
 <translation id="464342062220857295">විශේෂාංග සොයන්න</translation>
 <translation id="4644670975240021822">ප්‍රතිවර්තන පිළිවෙළ මුහුණු පහළට</translation>
 <translation id="4646534391647090355">දැන් මාව එතැනට ගෙන යන්න</translation>
@@ -1974,6 +1984,7 @@
 <translation id="4780366598804516005">තැපැල් පෙට්ටිය 1</translation>
 <translation id="4785376858512657294">Google ගිණුම කළමනාකරණය කරන්න</translation>
 <translation id="4785689107224900852">මෙම පටිත්තට මාරු වන්න</translation>
+<translation id="4785998536350006000">"<ph name="SEARCH_QUERY" />" සෙවීම</translation>
 <translation id="4786804728079074733">වොලිබෝල්</translation>
 <translation id="4787182171088676626">ලියුම් කවරය (සිනිඳු)</translation>
 <translation id="4789704664580239421">මිල පහත වැටීමේ ඇඟවීම් ඔබේ විවෘත පටිති මත පෙන්වයි</translation>
@@ -2011,6 +2022,7 @@
 <translation id="4864801646102013152">නිවාස වැඩි දියුණු කිරීම</translation>
 <translation id="4866506163384898554">ඔබගේ කර්සරය පෙන්වීමට |<ph name="ACCELERATOR1" />| + |<ph name="ACCELERATOR2" />| ඔබන්න</translation>
 <translation id="4873616204573862158">ඇස් පැළඳුම්</translation>
+<translation id="4873807733347502026">ඔබේ මූසිකය අගුලු දමා භාවිත කරන්න</translation>
 <translation id="4876188919622883022">සරල දසුන</translation>
 <translation id="4876305945144899064">පරිශීලක නමක් නැත</translation>
 <translation id="4876327226315760474">මෙයින් අදහස් කරන්නේ අඩවි විශේෂාංග බලාපොරොත්තු වූ පරිදි ක්‍රියා කළ යුතු නමුත් ඔබට අඩු බ්‍රවුස් කිරීමේ ආරක්ෂාවක් තිබිය හැකි බවයි.</translation>
@@ -2098,6 +2110,7 @@
 <translation id="5018802455907704660">අඟ 16 x 20</translation>
 <translation id="5019198164206649151">උපස්ථ ගබඩාව දුර්වල තත්වයක</translation>
 <translation id="5019293549442035120">ඔබට Google නිෂ්පාදන හරහා සුරැකි ලිපින භාවිතා කළ හැක. මෙම ලිපිනය ඔබේ Google ගිණුමේ, <ph name="USER_EMAIL" /> සුරකිනු ඇත.</translation>
+<translation id="5019952743397118625"><ph name="EXTENSION_DEVELOPER_MODE_SETTINGS_POLICY_NAME" /> ප්‍රතිපත්තිය සකසා ඇත. <ph name="DEVELOPER_TOOLS_AVAILABILITY_POLICY_NAME" /> දිගු පිටුව මත සංවර්ධක ප්‍රකාරය ලැබීම පාලන නොකරයි.</translation>
 <translation id="5021557570875267742">Chrome සමග මිල ගණන් නිරීක්ෂණය කරන්න</translation>
 <translation id="5023310440958281426">ඔබේ පරිපාලකගේ ප්‍රතිපත්ති විමසන්න</translation>
 <translation id="5030338702439866405">නිකුත් කළේ</translation>
@@ -2436,6 +2449,7 @@
 <translation id="5667827081946850877">ශ්‍රව්‍යපොත්</translation>
 <translation id="5675650730144413517">මෙම පිටුව ක්‍රියා නොකරයි</translation>
 <translation id="5675809467256309336">නැටුම් සහ ඉලෙක්ට්‍රොනික සංගීතය</translation>
+<translation id="5675959228867414813">දිනය අනුව පෙන්වන්න</translation>
 <translation id="5677928146339483299">බාධාකළ</translation>
 <translation id="5678007133659493065">ලෝපත</translation>
 <translation id="5680642791693447368">ත්‍රාසජනක, අපරාධ සහ අභිරහස් චිත්‍රපට</translation>
@@ -2653,6 +2667,7 @@
 <translation id="6108702513636120202">Chromium හි ඔබේ සෙවීම් යන්ත්‍රය</translation>
 <translation id="6108849843016142864">උරගයින් සහ උභයජීවීන්</translation>
 <translation id="610911394827799129">ඔබේ Google ගිණුමට <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> හිදී බ්‍රවුස් කිරීමේ ඉතිහාසයේ වෙනත් ආකාරයන් තිබිය හැක</translation>
+<translation id="611018310643025551">ඔබේ සෙවීම්, හොඳම ගැළපීම්, සහ ඒවායේ පිටු අන්තර්ගත Google වෙත යවනු ලබන අතර මෙම විශේෂාංගය දියුණු කිරීමට මානව සමාලෝචකයින් විසින් දකිනු ලැබේවි.</translation>
 <translation id="6116338172782435947">පසුරු පුවරුවට පිටපත් කළ පෙළ සහ රූප බලන්න</translation>
 <translation id="6117833587752089929">ඡායාරූපය (සැටින්)</translation>
 <translation id="6118782133429281336">මූලාරම්භ ලැයිස්තුව හිස් වේ.</translation>
@@ -2909,6 +2924,7 @@
 <translation id="6587923378399804057">ඔබ පිටපත් කළ සබැඳිය</translation>
 <translation id="6591833882275308647">ඔබේ <ph name="DEVICE_TYPE" /> කළමනා නොකෙරේ</translation>
 <translation id="6596325263575161958">සංකේතනය කිරීමේ විකල්ප</translation>
+<translation id="6596573334527383067">ඊයේ සිට ප්‍රතිඵල පෙන්වන්න</translation>
 <translation id="6597665340361269064">අංශක 90</translation>
 <translation id="6598976221101665070">නාට්‍ය චිත්‍රපට</translation>
 <translation id="6599642189720630047">හඹා ගිය නිෂ්පාදන</translation>
@@ -3379,6 +3395,7 @@
 <translation id="7489392576326061356">ෂැම්පු සහ කන්ඩිෂනර්</translation>
 <translation id="7495528107193238112">මෙම අන්තර්ගතය අවහිර කර ඇත. ගැටලුව නිවැරදි කිරීමට අඩවි හිමිකරු අමතන්න</translation>
 <translation id="749865518782565832">ජලනල ශිල්පය</translation>
+<translation id="7500917112031739411">සමූහය අනුව පෙන්වන්න</translation>
 <translation id="7501663406926337752">ඉදිරි අඩවිය ඔබේ සංවිධානය විසින් සලකුණු කර ඇත</translation>
 <translation id="7507075214339298899">ලියුම් කවරය #9</translation>
 <translation id="7508255263130623398">ආපසු ලබා දුන් ප්‍රතිපත්ති උපාංග id හිස් හෝ වත්මන් උපාංග id හා නොගැළපෙයි</translation>
@@ -3580,6 +3597,7 @@
 <translation id="7825558994363763489">මයික්‍රෝවේව් උඳුන්</translation>
 <translation id="782886543891417279">ඔබ භාවිතා කරන Wi-Fi (<ph name="WIFI_NAME" />) මගින් ඔබ එහි පුරනය වීමේ පිටුවට පිවිසීමට අවශ්‍ය විය හැක.</translation>
 <translation id="7831993212387676366">සාප්පු ලැයිස්තුව යනු කුමක් ද?</translation>
+<translation id="7832078172950550575">එදිනෙදා භාෂාව භාවිත කර, ඔබට "මා අවට පීසා තැන්" හෝ “නගරයේ පවුල් හිතකාමී උඩඟු" වැනි වැකිකඩ භාවිත කර ඔබේ බ්‍රවුස් කිරීමේ ඉතිහාසය සෙවිය හැක. ඔබේ සෙවීම්, හොඳම ගැළපීම්, සහ ඒවායේ පිටු අන්තර්ගත Google වෙත යවනු ලබන අතර මෙම විශේෂාංගය දියුණු කිරීමට මානව සමාලෝචකයින් විසින් දකිනු ලැබේවි. <ph name="BEGIN_LINK" />ඔබේ ඉතිහාස සෙවුම් සැකසීම කළමනා කරන්න<ph name="END_LINK" /></translation>
 <translation id="7840103971441592723">තිර ග්‍රහණය ආරම්භ කර ඇත</translation>
 <translation id="784137052867620416">සාප්පු සවාරි ඇතුළාන්ත</translation>
 <translation id="784404208867107517">සමූහගත ඉතිහාසය</translation>
@@ -3875,6 +3893,7 @@
 <translation id="8398335999901363925">සම්පූර්ණ උසින් විවෘත කරන ලද ස්පර්ශයෙහි පිරවිය හැකි ගෙවීම් ක්‍රම තිබේ.</translation>
 <translation id="8398446215576328011">යෙදූ ප්‍රතිපත්ති ප්‍රතිවර්තනය කරන්න</translation>
 <translation id="8398790343843005537">ඔබගේ දුරකථනය සොයන්න</translation>
+<translation id="8399276468426899527">යතුරු පුවරු අගුල සහ භාවිතය</translation>
 <translation id="8400929824946688748">රැකියා සහ අධ්‍යාපනය</translation>
 <translation id="8403506619177967839">දිරිමත් කරන්නන්ගේ පරිකල්පන</translation>
 <translation id="8405579342203358118">Chrome සැකසීම් තුළ ඔබ සමමුමුහුර්ත කරන්නේ කුමන තොරතුරුද යන්න කළමනාකරණය කරන්න</translation>
@@ -4216,6 +4235,7 @@
 <translation id="9089260154716455634">අක්‍රිය වේලා ප්‍රතිපත්තිය:</translation>
 <translation id="9090218457905363312">රෙගේ සහ කැරිබියන් සංගීතය</translation>
 <translation id="9090243919347147717">ඇමුණුම්</translation>
+<translation id="9090548458280093580">ඔබේ ඉතිහාසයෙන් සොයන්න, AI බලගන්වයි</translation>
 <translation id="9090993752571911635">අන්තර්ජාල සේවා සපයන්නන් (ISPs)</translation>
 <translation id="9093723786115107672">නිදන ඇඳුම්</translation>
 <translation id="9094544726794842788">ඔබ මෙම ප්‍රතිඵල වලට අකමැති හේතුව පිළිබඳව සවිස්තරාත්මක ප්‍රතිපෝෂණ ඉදිරිපත් කිරීම සඳහා මාපටැඟිල්ලක් පහළට පෝරමයක් විවෘත කරයි</translation>
diff --git a/components/strings/components_strings_sk.xtb b/components/strings/components_strings_sk.xtb
index 48d5598..52fdbc5 100644
--- a/components/strings/components_strings_sk.xtb
+++ b/components/strings/components_strings_sk.xtb
@@ -3058,6 +3058,7 @@
 <translation id="6915804003454593391">Používateľ:</translation>
 <translation id="6916193791494646625">Poskytnite dôvod stiahnutia (povinné)</translation>
 <translation id="6917795328362592458">Heslo, ktoré ste práve použili, bolo nájdené v zozname hesiel odhalených pri porušení ochrany údajov. Ak chcete svoje účty zabezpečiť, Správca hesiel odporúča uložené heslá skontrolovať.</translation>
+<translation id="6924013822850225188">Vyberte, či sa majú zobrazovať výhody karty pri platbe (platia zmluvné podmienky banky)</translation>
 <translation id="6925267999184670015">Severoamerický formát B+</translation>
 <translation id="6926216138694948720">Kreslenie na telo</translation>
 <translation id="692638818576287323">Komerčné vozidlá</translation>
@@ -3827,6 +3828,7 @@
 <translation id="830498451218851433">Zahnúť v polovici</translation>
 <translation id="8308653357438598313">Priame prenosy</translation>
 <translation id="8311895354659782580">Realitné kancelárie</translation>
+<translation id="8312841338723044391">NAŽIVO</translation>
 <translation id="8316555157357957253">Používa sa teraz</translation>
 <translation id="8319269383395457801">Predaj nehnuteľností</translation>
 <translation id="831997045666694187">Večer</translation>
diff --git a/components/strings/components_strings_sr-Latn.xtb b/components/strings/components_strings_sr-Latn.xtb
index bfa8fad..4fac62f 100644
--- a/components/strings/components_strings_sr-Latn.xtb
+++ b/components/strings/components_strings_sr-Latn.xtb
@@ -508,6 +508,7 @@
 <translation id="192095259937375524">Dugme Deli ovu karticu, aktivirajte ga da biste delili ovu karticu deljenjem linka, pravljenjem QR koda, prebacivanjem i na druge načine</translation>
 <translation id="1924727005275031552">Novo</translation>
 <translation id="1927439846988093361">Nega kose</translation>
+<translation id="1935353813610900265">Pošaljite povratne informacije za pretragu istorije koju omogućava AI</translation>
 <translation id="1935995810530254458">Ipak kopiraj</translation>
 <translation id="1939059826036755332">Automatska slika u slici</translation>
 <translation id="1939175642807587452">Može da traži da šalje obaveštenja</translation>
@@ -831,6 +832,7 @@
 <translation id="2526280916094749336">Možete da koristite sačuvane adrese u svim Google proizvodima. Ova adresa će biti sačuvana na Google nalogu <ph name="ACCOUNT" />.</translation>
 <translation id="2527451058878391043">CVC je na prednjoj strani kartice. To je 4-cifreni kôd u gornjem desnom uglu iznad broja kartice.</translation>
 <translation id="2529899080962247600">Ovo polje ne sme da ima više od <ph name="MAX_ITEMS_LIMIT" /> unosa. Svi budući unosi će se zanemariti.</translation>
+<translation id="2530042584066815841">Zaključavanje i korišćenje miša</translation>
 <translation id="2533649878691950253">Ovom sajtu je zabranjen pristup vašoj preciznoj lokaciji jer obično to ne dozvoljavate</translation>
 <translation id="253493526287553278">Prikaži detalje o promotivnom kodu</translation>
 <translation id="2535585790302968248">Otvorite novu karticu bez arhiviranja da biste pregledali privatno</translation>
@@ -856,6 +858,7 @@
 <translation id="255497580849974774">Neka uređaj bude povezan sa punjačem tokom ažuriranja.</translation>
 <translation id="2556876185419854533">&amp;Opozovi izmenu</translation>
 <translation id="2559566667529177711">Više slojeva</translation>
+<translation id="2565789370591907825">Zaključavanje i korišćenje tastature</translation>
 <translation id="2570734079541893434">Upravljajte podešavanjima</translation>
 <translation id="2573170131138724450">Televizori</translation>
 <translation id="257674075312929031">Grupa</translation>
@@ -903,6 +906,7 @@
 <translation id="2687555958734450033">Najbolja veličina</translation>
 <translation id="2688186765492306706">500×760 mm</translation>
 <translation id="2688969097326701645">Da, nastavi</translation>
+<translation id="2690699652723742414">Poslednjih 30 dana</translation>
 <translation id="2691924980723297736">Bezbednosno upozorenje</translation>
 <translation id="2699273987028089219">Podmeni je dostupan. Koristite <ph name="SHORTCUT" /> da biste došli do dodatnih opcija.</translation>
 <translation id="2701514975700770343">Sa odštampanom stranom nadole</translation>
@@ -1032,6 +1036,7 @@
 <translation id="297173220375858963">Stono izdavaštvo</translation>
 <translation id="2972581237482394796">&amp;Ponovi radnju</translation>
 <translation id="2977665033722899841"><ph name="ROW_NAME" />, trenutno izabrano. <ph name="ROW_CONTENT" /></translation>
+<translation id="2977847223286097084">zaključa i koristi tastaturu</translation>
 <translation id="2978824962390592855">Opera</translation>
 <translation id="2979424420072875974">Resursi za pisce</translation>
 <translation id="2980742331521553164">CVC ove kartice će biti šifrovan i sačuvan na Google nalogu radi bržeg plaćanja</translation>
@@ -1104,6 +1109,7 @@
 <translation id="31207688938192855"><ph name="BEGIN_LINK" />Pokušajte da pokrenete dijagnostiku veze<ph name="END_LINK" />.</translation>
 <translation id="3120807611504813890">Koverta (lagana)</translation>
 <translation id="3121994479408824897">Idi na <ph name="DOMAIN" /></translation>
+<translation id="3122696783148405307">Prikažite rezultate iz poslednjih 30 dana</translation>
 <translation id="3126023634486644099">Nalepnice (trajne)</translation>
 <translation id="3133565499688974786"><ph name="SEARCH_ENGINE_NAME" /> je sada vaš podrazumevani pretraživač</translation>
 <translation id="3137283076021007034"><ph name="KEYWORD" /> – Pretražite stavku <ph name="KEYWORD_SHORT_NAME" /></translation>
@@ -1473,6 +1479,7 @@
 <translation id="3781428340399460090">Jarkoroze</translation>
 <translation id="3783418713923659662">Mastercard</translation>
 <translation id="3784372983762739446">Bluetooth uređaji</translation>
+<translation id="378611282717571199">Najbolja podudaranja za „<ph name="SEARCH_QUERY" />“</translation>
 <translation id="3789155188480882154">Veličina 16</translation>
 <translation id="3789841737615482174">Instaliraj</translation>
 <translation id="3792100426446126328"><ph name="NAME" /> (<ph name="WIDTH" />x<ph name="HEIGHT" /> in)</translation>
@@ -1493,6 +1500,7 @@
 <translation id="3815434930383843058">8×12 in</translation>
 <translation id="3816482573645936981">Vrednost (zamenjena)</translation>
 <translation id="382115839591654906">CVC za: <ph name="CARD_NAME" /></translation>
+<translation id="3822492359574576064">zaključavanje i korišćenje miša</translation>
 <translation id="3823019343150397277">IBAN</translation>
 <translation id="3823402221513322552">Pregledačem upravlja <ph name="BROWSER_DOMAIN" />, a profilom upravlja <ph name="PROFILE_DOMAIN" /></translation>
 <translation id="382518646247711829">Ako koristite proksi server...</translation>
@@ -1817,6 +1825,7 @@
 <translation id="4438821706955556403">Uobičajena cena</translation>
 <translation id="4441832193888514600">Ignoriše se jer smernice mogu da se podese samo kao smernice za korisnika u klaudu.</translation>
 <translation id="4445133368066241428">Popularne teme</translation>
+<translation id="4445964943162061557">Ovo je eksperimentalna funkcija i neće uvek raditi kako treba.</translation>
 <translation id="4449116177348980384">Dugme Upravljaj podešavanjima sajta, aktivirajte ga da biste upravljali dozvolama i podacima sačuvanim na različitim sajtovima u podešavanjima Chrome-a</translation>
 <translation id="4451135742916150903">Može da traži da se povezuje sa HID uređajima</translation>
 <translation id="4451684391620232683">Tekst predstavljen korisniku:</translation>
@@ -1895,6 +1904,7 @@
 <translation id="4631881646528206880">Registracija za virtuelnu karticu</translation>
 <translation id="4635278307999235413">Podaci se šalju u administratorsku konzolu</translation>
 <translation id="4636930964841734540">Informacije</translation>
+<translation id="4640225694041297329">Prikažite rezultate iz poslednjih 7 dana</translation>
 <translation id="464342062220857295">Funkcije pretrage</translation>
 <translation id="4644670975240021822">Obrnutim redosledom sa odštampanom stranom nadole</translation>
 <translation id="4646534391647090355">Odvedi me tamo</translation>
@@ -1974,6 +1984,7 @@
 <translation id="4780366598804516005">1. poštansko sanduče</translation>
 <translation id="4785376858512657294">Upravljajte Google nalogom</translation>
 <translation id="4785689107224900852">Pređite na ovu karticu</translation>
+<translation id="4785998536350006000">Pretražuje se „<ph name="SEARCH_QUERY" />“</translation>
 <translation id="4786804728079074733">Odbojka</translation>
 <translation id="4787182171088676626">Koverta (tanka)</translation>
 <translation id="4789704664580239421">Obaveštenja o sniženjima će se prikazivati na otvorenim karticama</translation>
@@ -2011,6 +2022,7 @@
 <translation id="4864801646102013152">Uređenje doma</translation>
 <translation id="4866506163384898554">Pritisnite |<ph name="ACCELERATOR1" />| + |<ph name="ACCELERATOR2" />| da bi se pokazivač prikazao</translation>
 <translation id="4873616204573862158">Naočare</translation>
+<translation id="4873807733347502026">zaključa i koristi miš</translation>
 <translation id="4876188919622883022">Pojednostavljeni prikaz</translation>
 <translation id="4876305945144899064">Nema korisničkog imena</translation>
 <translation id="4876327226315760474">To znači da bi funkcije sajta trebalo da rade na očekivani način, ali možda ćete imati manje zaštite pri pregledanju.</translation>
@@ -2098,6 +2110,7 @@
 <translation id="5018802455907704660">16×20 in</translation>
 <translation id="5019198164206649151">Skladište toka podataka je u lošem stanju</translation>
 <translation id="5019293549442035120">Možete da koristite sačuvane adrese u svim Google proizvodima. Ova adresa će biti sačuvana na Google nalogu <ph name="USER_EMAIL" />.</translation>
+<translation id="5019952743397118625">Smernice <ph name="EXTENSION_DEVELOPER_MODE_SETTINGS_POLICY_NAME" /> su podešene. <ph name="DEVELOPER_TOOLS_AVAILABILITY_POLICY_NAME" /> neće kontrolisati dostupnost režima programera na stranici sa dodacima.</translation>
 <translation id="5021557570875267742">Pratite cene pomoću Chrome-a</translation>
 <translation id="5023310440958281426">Proverite smernice administratora</translation>
 <translation id="5030338702439866405">Izdao/la</translation>
@@ -2436,6 +2449,7 @@
 <translation id="5667827081946850877">Audio-knjige</translation>
 <translation id="5675650730144413517">Ova stranica ne funkcioniše</translation>
 <translation id="5675809467256309336">Dens i elektronska muzika</translation>
+<translation id="5675959228867414813">Prikaži prema datumu</translation>
 <translation id="5677928146339483299">Blokirano</translation>
 <translation id="5678007133659493065">Folija</translation>
 <translation id="5680642791693447368">Trileri, kriminalistički filmovi i filmovi misterije</translation>
@@ -2653,6 +2667,7 @@
 <translation id="6108702513636120202">Vaš pretraživač u Chromium-u</translation>
 <translation id="6108849843016142864">Gmizavci i vodozemci</translation>
 <translation id="610911394827799129">Google nalog može da ima druge oblike istorije pregledanja na <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation>
+<translation id="611018310643025551">Pretrage, najbolja podudaranja i sadržaj stranica šalju se Google-u i osobe koje pregledaju mogu da ih vide radi poboljšanja ove funkcije.</translation>
 <translation id="6116338172782435947">da vidi tekst i slike koji su kopirani u privremenu memoriju</translation>
 <translation id="6117833587752089929">Slika (saten)</translation>
 <translation id="6118782133429281336">Lista porekla je prazna.</translation>
@@ -2908,6 +2923,7 @@
 <translation id="6587923378399804057">Link koji ste kopirali</translation>
 <translation id="6591833882275308647"><ph name="DEVICE_TYPE" />-om se ne upravlja</translation>
 <translation id="6596325263575161958">Opcije šifrovanja</translation>
+<translation id="6596573334527383067">Prikažite rezultate od juče</translation>
 <translation id="6597665340361269064">90 stepeni</translation>
 <translation id="6598976221101665070">Drame</translation>
 <translation id="6599642189720630047">Proizvodi koje pratite</translation>
@@ -3379,6 +3395,7 @@
 <translation id="7489392576326061356">Šamponi i regeneratori</translation>
 <translation id="7495528107193238112">Ovaj sadržaj je blokiran. Obratite se vlasniku sajta da biste rešili problem.</translation>
 <translation id="749865518782565832">Vodoinstalaterske usluge</translation>
+<translation id="7500917112031739411">Prikaži prema grupi</translation>
 <translation id="7501663406926337752">Organizacija je obeležila sajt u nastavku</translation>
 <translation id="7507075214339298899">Koverta br. 9</translation>
 <translation id="7508255263130623398">Vraćeni ID uređaja za smernice je prazan ili se ne podudara sa aktuelnim ID-om uređaja</translation>
@@ -3580,6 +3597,7 @@
 <translation id="7825558994363763489">Mikrotalasne pećnice</translation>
 <translation id="782886543891417279">WiFi mreža koju koristite (<ph name="WIFI_NAME" />) će možda zahtevati da posetite stranicu za prijavljivanje.</translation>
 <translation id="7831993212387676366">Šta je to lista za kupovinu?</translation>
+<translation id="7832078172950550575">Pomoću svakodnevnog jezika možete da pretražujete istoriju pregledanja koristeći fraze kao što su „picerije u blizini“ ili „parkovi u centru grada pogodni za porodicu“. Pretrage, najbolja podudaranja i sadržaj stranica šalju se Google-u i osobe koje pregledaju mogu da ih vide radi poboljšanja ove funkcije. <ph name="BEGIN_LINK" />Upravljajte podešavanjem pretrage istorije<ph name="END_LINK" /></translation>
 <translation id="7840103971441592723">Snimanje ekrana je počelo</translation>
 <translation id="784137052867620416">Uvid u kupovinu</translation>
 <translation id="784404208867107517">Grupisana istorija</translation>
@@ -3876,6 +3894,7 @@
 <translation id="8398335999901363925">Načini plaćanja dostupni za unos dodirom otvoreni su u punoj visini.</translation>
 <translation id="8398446215576328011">Vrati primenjive smernice</translation>
 <translation id="8398790343843005537">Pronađi telefon</translation>
+<translation id="8399276468426899527">zaključavanje i korišćenje tastature</translation>
 <translation id="8400929824946688748">Poslovi i obrazovanje</translation>
 <translation id="8403506619177967839">Dela poklonika čuvenih likova</translation>
 <translation id="8405579342203358118">Upravljajte time koje informacije sinhronizujete u podešavanjima Chrome-a</translation>
@@ -4218,6 +4237,7 @@
 <translation id="9089260154716455634">Smernice sa vremenskim rasporedom:</translation>
 <translation id="9090218457905363312">Rege i karipska muzika</translation>
 <translation id="9090243919347147717">Prilozi</translation>
+<translation id="9090548458280093580">Pretražite istoriju, koju omogućava AI</translation>
 <translation id="9090993752571911635">Internet provajderi</translation>
 <translation id="9093723786115107672">Odeća za spavanje</translation>
 <translation id="9094544726794842788">Opcija Ne sviđa mi se otvara obrazac za slanje detaljnih povratnih informacija o tome zašto vam se ne sviđaju ovi rezultati</translation>
diff --git a/components/strings/components_strings_sr.xtb b/components/strings/components_strings_sr.xtb
index e2cad94a..0d2fc1a7 100644
--- a/components/strings/components_strings_sr.xtb
+++ b/components/strings/components_strings_sr.xtb
@@ -508,6 +508,7 @@
 <translation id="192095259937375524">Дугме Дели ову картицу, активирајте га да бисте делили ову картицу дељењем линка, прављењем QR кода, пребацивањем и на друге начине</translation>
 <translation id="1924727005275031552">Ново</translation>
 <translation id="1927439846988093361">Нега косе</translation>
+<translation id="1935353813610900265">Пошаљите повратне информације за претрагу историје коју омогућава AI</translation>
 <translation id="1935995810530254458">Ипак копирај</translation>
 <translation id="1939059826036755332">Аутоматска слика у слици</translation>
 <translation id="1939175642807587452">Може да тражи да шаље обавештења</translation>
@@ -831,6 +832,7 @@
 <translation id="2526280916094749336">Можете да користите сачуване адресе у свим Google производима. Ова адреса ће бити сачувана на Google налогу <ph name="ACCOUNT" />.</translation>
 <translation id="2527451058878391043">CVC је на предњој страни картице. То је 4-цифрени кôд у горњем десном углу изнад броја картице.</translation>
 <translation id="2529899080962247600">Ово поље не сме да има више од <ph name="MAX_ITEMS_LIMIT" /> уноса. Сви будући уноси ће се занемарити.</translation>
+<translation id="2530042584066815841">Закључавање и коришћење миша</translation>
 <translation id="2533649878691950253">Овом сајту је забрањен приступ вашој прецизној локацији јер обично то не дозвољавате</translation>
 <translation id="253493526287553278">Прикажи детаље о промотивном коду</translation>
 <translation id="2535585790302968248">Отворите нову картицу без архивирања да бисте прегледали приватно</translation>
@@ -856,6 +858,7 @@
 <translation id="255497580849974774">Нека уређај буде повезан са пуњачем током ажурирања.</translation>
 <translation id="2556876185419854533">&amp;Опозови измену</translation>
 <translation id="2559566667529177711">Више слојева</translation>
+<translation id="2565789370591907825">Закључавање и коришћење тастатуре</translation>
 <translation id="2570734079541893434">Управљајте подешавањима</translation>
 <translation id="2573170131138724450">Телевизори</translation>
 <translation id="257674075312929031">Група</translation>
@@ -903,6 +906,7 @@
 <translation id="2687555958734450033">Најбоља величина</translation>
 <translation id="2688186765492306706">500×760 mm</translation>
 <translation id="2688969097326701645">Да, настави</translation>
+<translation id="2690699652723742414">Последњих 30 дана</translation>
 <translation id="2691924980723297736">Безбедносно упозорење</translation>
 <translation id="2699273987028089219">Подмени је доступан. Користите <ph name="SHORTCUT" /> да бисте дошли до додатних опција.</translation>
 <translation id="2701514975700770343">Са одштампаном страном надоле</translation>
@@ -1032,6 +1036,7 @@
 <translation id="297173220375858963">Стоно издаваштво</translation>
 <translation id="2972581237482394796">&amp;Понови радњу</translation>
 <translation id="2977665033722899841"><ph name="ROW_NAME" />, тренутно изабрано. <ph name="ROW_CONTENT" /></translation>
+<translation id="2977847223286097084">закључа и користи тастатуру</translation>
 <translation id="2978824962390592855">Опера</translation>
 <translation id="2979424420072875974">Ресурси за писце</translation>
 <translation id="2980742331521553164">CVC ове картице ће бити шифрован и сачуван на Google налогу ради бржег плаћања</translation>
@@ -1104,6 +1109,7 @@
 <translation id="31207688938192855"><ph name="BEGIN_LINK" />Покушајте да покренете дијагностику везе<ph name="END_LINK" />.</translation>
 <translation id="3120807611504813890">Коверта (лагана)</translation>
 <translation id="3121994479408824897">Иди на <ph name="DOMAIN" /></translation>
+<translation id="3122696783148405307">Прикажите резултате из последњих 30 дана</translation>
 <translation id="3126023634486644099">Налепнице (трајне)</translation>
 <translation id="3133565499688974786"><ph name="SEARCH_ENGINE_NAME" /> је сада ваш подразумевани претраживач</translation>
 <translation id="3137283076021007034"><ph name="KEYWORD" /> – Претражите ставку <ph name="KEYWORD_SHORT_NAME" /></translation>
@@ -1473,6 +1479,7 @@
 <translation id="3781428340399460090">Јаркорозе</translation>
 <translation id="3783418713923659662">Mastercard</translation>
 <translation id="3784372983762739446">Bluetooth уређаји</translation>
+<translation id="378611282717571199">Најбоља подударања за „<ph name="SEARCH_QUERY" />“</translation>
 <translation id="3789155188480882154">Величина 16</translation>
 <translation id="3789841737615482174">Инсталирај</translation>
 <translation id="3792100426446126328"><ph name="NAME" /> (<ph name="WIDTH" />x<ph name="HEIGHT" /> in)</translation>
@@ -1493,6 +1500,7 @@
 <translation id="3815434930383843058">8×12 in</translation>
 <translation id="3816482573645936981">Вредност (замењена)</translation>
 <translation id="382115839591654906">CVC за: <ph name="CARD_NAME" /></translation>
+<translation id="3822492359574576064">закључавање и коришћење миша</translation>
 <translation id="3823019343150397277">IBAN</translation>
 <translation id="3823402221513322552">Прегледачем управља <ph name="BROWSER_DOMAIN" />, а профилом управља <ph name="PROFILE_DOMAIN" /></translation>
 <translation id="382518646247711829">Ако користите прокси сервер...</translation>
@@ -1817,6 +1825,7 @@
 <translation id="4438821706955556403">Уобичајена цена</translation>
 <translation id="4441832193888514600">Игнорише се јер смернице могу да се подесе само као смернице за корисника у клауду.</translation>
 <translation id="4445133368066241428">Популарне теме</translation>
+<translation id="4445964943162061557">Ово је експериментална функција и неће увек радити како треба.</translation>
 <translation id="4449116177348980384">Дугме Управљај подешавањима сајта, активирајте га да бисте управљали дозволама и подацима сачуваним на различитим сајтовима у подешавањима Chrome-а</translation>
 <translation id="4451135742916150903">Може да тражи да се повезује са HID уређајима</translation>
 <translation id="4451684391620232683">Текст представљен кориснику:</translation>
@@ -1895,6 +1904,7 @@
 <translation id="4631881646528206880">Регистрација за виртуелну картицу</translation>
 <translation id="4635278307999235413">Подаци се шаљу у администраторску конзолу</translation>
 <translation id="4636930964841734540">Информације</translation>
+<translation id="4640225694041297329">Прикажите резултате из последњих 7 дана</translation>
 <translation id="464342062220857295">Функције претраге</translation>
 <translation id="4644670975240021822">Обрнутим редоследом са одштампаном страном надоле</translation>
 <translation id="4646534391647090355">Одведи ме тамо</translation>
@@ -1974,6 +1984,7 @@
 <translation id="4780366598804516005">1. поштанско сандуче</translation>
 <translation id="4785376858512657294">Управљајте Google налогом</translation>
 <translation id="4785689107224900852">Пређите на ову картицу</translation>
+<translation id="4785998536350006000">Претражује се „<ph name="SEARCH_QUERY" />“</translation>
 <translation id="4786804728079074733">Одбојка</translation>
 <translation id="4787182171088676626">Коверта (танка)</translation>
 <translation id="4789704664580239421">Обавештења о снижењима ће се приказивати на отвореним картицама</translation>
@@ -2011,6 +2022,7 @@
 <translation id="4864801646102013152">Уређење дома</translation>
 <translation id="4866506163384898554">Притисните |<ph name="ACCELERATOR1" />| + |<ph name="ACCELERATOR2" />| да би се показивач приказао</translation>
 <translation id="4873616204573862158">Наочаре</translation>
+<translation id="4873807733347502026">закључа и користи миш</translation>
 <translation id="4876188919622883022">Поједностављени приказ</translation>
 <translation id="4876305945144899064">Нема корисничког имена</translation>
 <translation id="4876327226315760474">То значи да би функције сајта требало да раде на очекивани начин, али можда ћете имати мање заштите при прегледању.</translation>
@@ -2098,6 +2110,7 @@
 <translation id="5018802455907704660">16×20 in</translation>
 <translation id="5019198164206649151">Складиште тока података је у лошем стању</translation>
 <translation id="5019293549442035120">Можете да користите сачуване адресе у свим Google производима. Ова адреса ће бити сачувана на Google налогу <ph name="USER_EMAIL" />.</translation>
+<translation id="5019952743397118625">Смернице <ph name="EXTENSION_DEVELOPER_MODE_SETTINGS_POLICY_NAME" /> су подешене. <ph name="DEVELOPER_TOOLS_AVAILABILITY_POLICY_NAME" /> неће контролисати доступност режима програмера на страници са додацима.</translation>
 <translation id="5021557570875267742">Пратите цене помоћу Chrome-а</translation>
 <translation id="5023310440958281426">Проверите смернице администратора</translation>
 <translation id="5030338702439866405">Издао/ла</translation>
@@ -2436,6 +2449,7 @@
 <translation id="5667827081946850877">Аудио-књиге</translation>
 <translation id="5675650730144413517">Ова страница не функционише</translation>
 <translation id="5675809467256309336">Денс и електронска музика</translation>
+<translation id="5675959228867414813">Прикажи према датуму</translation>
 <translation id="5677928146339483299">Блокирано</translation>
 <translation id="5678007133659493065">Фолија</translation>
 <translation id="5680642791693447368">Трилери, криминалистички филмови и филмови мистерије</translation>
@@ -2653,6 +2667,7 @@
 <translation id="6108702513636120202">Ваш претраживач у Chromium-у</translation>
 <translation id="6108849843016142864">Гмизавци и водоземци</translation>
 <translation id="610911394827799129">Google налог може да има друге облике историје прегледања на <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation>
+<translation id="611018310643025551">Претраге, најбоља подударања и садржај страница шаљу се Google-у и особе које прегледају могу да их виде ради побољшања ове функције.</translation>
 <translation id="6116338172782435947">да види текст и слике који су копирани у привремену меморију</translation>
 <translation id="6117833587752089929">Слика (сатен)</translation>
 <translation id="6118782133429281336">Листа порекла је празна.</translation>
@@ -2908,6 +2923,7 @@
 <translation id="6587923378399804057">Линк који сте копирали</translation>
 <translation id="6591833882275308647"><ph name="DEVICE_TYPE" />-ом се не управља</translation>
 <translation id="6596325263575161958">Опције шифровања</translation>
+<translation id="6596573334527383067">Прикажите резултате од јуче</translation>
 <translation id="6597665340361269064">90 степени</translation>
 <translation id="6598976221101665070">Драме</translation>
 <translation id="6599642189720630047">Производи које пратите</translation>
@@ -3379,6 +3395,7 @@
 <translation id="7489392576326061356">Шампони и регенератори</translation>
 <translation id="7495528107193238112">Овај садржај је блокиран. Обратите се власнику сајта да бисте решили проблем.</translation>
 <translation id="749865518782565832">Водоинсталатерске услуге</translation>
+<translation id="7500917112031739411">Прикажи према групи</translation>
 <translation id="7501663406926337752">Организација је обележила сајт у наставку</translation>
 <translation id="7507075214339298899">Коверта бр. 9</translation>
 <translation id="7508255263130623398">Враћени ИД уређаја за смернице је празан или се не подудара са актуелним ИД-ом уређаја</translation>
@@ -3580,6 +3597,7 @@
 <translation id="7825558994363763489">Микроталасне пећнице</translation>
 <translation id="782886543891417279">WiFi мрежа коју користите (<ph name="WIFI_NAME" />) ће можда захтевати да посетите страницу за пријављивање.</translation>
 <translation id="7831993212387676366">Шта је то листа за куповину?</translation>
+<translation id="7832078172950550575">Помоћу свакодневног језика можете да претражујете историју прегледања користећи фразе као што су „пицерије у близини“ или „паркови у центру града погодни за породицу“. Претраге, најбоља подударања и садржај страница шаљу се Google-у и особе које прегледају могу да их виде ради побољшања ове функције. <ph name="BEGIN_LINK" />Управљајте подешавањем претраге историје<ph name="END_LINK" /></translation>
 <translation id="7840103971441592723">Снимање екрана је почело</translation>
 <translation id="784137052867620416">Увид у куповину</translation>
 <translation id="784404208867107517">Груписана историја</translation>
@@ -3876,6 +3894,7 @@
 <translation id="8398335999901363925">Начини плаћања доступни за унос додиром отворени су у пуној висини.</translation>
 <translation id="8398446215576328011">Врати примењиве смернице</translation>
 <translation id="8398790343843005537">Пронађи телефон</translation>
+<translation id="8399276468426899527">закључавање и коришћење тастатуре</translation>
 <translation id="8400929824946688748">Послови и образовање</translation>
 <translation id="8403506619177967839">Дела поклоника чувених ликова</translation>
 <translation id="8405579342203358118">Управљајте тиме које информације синхронизујете у подешавањима Chrome-а</translation>
@@ -4218,6 +4237,7 @@
 <translation id="9089260154716455634">Смернице са временским распоредом:</translation>
 <translation id="9090218457905363312">Реге и карипска музика</translation>
 <translation id="9090243919347147717">Прилози</translation>
+<translation id="9090548458280093580">Претражите историју, коју омогућава AI</translation>
 <translation id="9090993752571911635">Интернет провајдери</translation>
 <translation id="9093723786115107672">Одећа за спавање</translation>
 <translation id="9094544726794842788">Опција Не свиђа ми се отвара образац за слање детаљних повратних информација о томе зашто вам се не свиђају ови резултати</translation>
diff --git a/components/strings/components_strings_sw.xtb b/components/strings/components_strings_sw.xtb
index ea5078d..8154017 100644
--- a/components/strings/components_strings_sw.xtb
+++ b/components/strings/components_strings_sw.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">Mtumiaji:</translation>
 <translation id="6916193791494646625">Toa sababu ya kupakua (ni lazima)</translation>
 <translation id="6917795328362592458">Nenosiri ulilotumia hivi punde limepatikana kwenye ufichuzi haramu wa data. Ili uimarishe usalama wa akaunti zako, Kidhibiti cha Manenosiri kinapendekeza ukague manenosiri yako yaliyohifadhiwa.</translation>
+<translation id="6924013822850225188">Chagua ikiwa ungependa kuangalia manufaa ya kadi yako unapolipa (sheria na masharti ya benki yanatumika)</translation>
 <translation id="6925267999184670015">Ukubwa wa North American B+</translation>
 <translation id="6926216138694948720">Sanaa ya Mwili</translation>
 <translation id="692638818576287323">Magari ya Biashara</translation>
@@ -3830,6 +3831,7 @@
 <translation id="830498451218851433">Kunja nusu</translation>
 <translation id="8308653357438598313">Utiririshaji wa Video wa Moja kwa Moja</translation>
 <translation id="8311895354659782580">Matangazo ya Mali Zisizohamishika</translation>
+<translation id="8312841338723044391">MUBASHARA</translation>
 <translation id="8316555157357957253">Inatumika sasa</translation>
 <translation id="8319269383395457801">Mauzo ya Nyumba za Makazi</translation>
 <translation id="831997045666694187">Jioni</translation>
diff --git a/components/strings/components_strings_ta.xtb b/components/strings/components_strings_ta.xtb
index 6bac00c2..325cefa 100644
--- a/components/strings/components_strings_ta.xtb
+++ b/components/strings/components_strings_ta.xtb
@@ -872,7 +872,7 @@
 <translation id="2612993535136743634">உங்கள் சாதனத்திலும் Google கணக்கிலும் சேமிக்கப்பட்டுள்ள பாதுகாப்புக் குறியீடுகள் அனைத்தும் நீக்கப்படும்</translation>
 <translation id="2616412942031748191">தேடலில் மேம்படுத்துதல் &amp; மார்க்கெட்டிங்</translation>
 <translation id="2618206371527040026">கல்வி மாநாடுகள் மற்றும் வெளியீடுகள்</translation>
-<translation id="2619052155095999743">செருகு</translation>
+<translation id="2619052155095999743">சேர்</translation>
 <translation id="2625385379895617796">உங்கள் கடிகாரம் மிகவும் முன்னோக்கி இருக்கிறது</translation>
 <translation id="262745152991669301">USB சாதனங்களுடன் இணைய முயலும்போது அனுமதி கேட்க வேண்டும்</translation>
 <translation id="2634124572758952069"><ph name="HOST_NAME" /> இன் சேவையக IP முகவரியைக் கண்டறிய முடியவில்லை.</translation>
diff --git a/components/strings/components_strings_uz.xtb b/components/strings/components_strings_uz.xtb
index 7a6ef6e..9e9aa91 100644
--- a/components/strings/components_strings_uz.xtb
+++ b/components/strings/components_strings_uz.xtb
@@ -4280,6 +4280,7 @@
 <translation id="920643408853370361">Sayohat sugʻurtasi</translation>
 <translation id="9207861905230894330">Maqolani qo‘shib bo‘lmadi.</translation>
 <translation id="9210825002219699214">Avia sayohatlar</translation>
+<translation id="9211461151375991073"><ph name="FEATURED_SEARCH_LIST" /> qidirish uchun @ deb yozing</translation>
 <translation id="9213433120051936369">Dizaynini moslash</translation>
 <translation id="9215416866750762878">Ilova Chromening bu saytga xavfsiz ulanishiga xalaqit qilmoqda</translation>
 <translation id="92178312226016010">Siz bu mahsulotni kuzatyapsiz.</translation>
diff --git a/components/strings/components_strings_vi.xtb b/components/strings/components_strings_vi.xtb
index f819405..91d8d59e 100644
--- a/components/strings/components_strings_vi.xtb
+++ b/components/strings/components_strings_vi.xtb
@@ -3063,6 +3063,7 @@
 <translation id="6915804003454593391">Người dùng:</translation>
 <translation id="6916193791494646625">Cung cấp lý do tải tệp xuống (bắt buộc)</translation>
 <translation id="6917795328362592458">Mật khẩu bạn vừa sử dụng đã bị lộ trong một sự cố rò rỉ dữ liệu. Để bảo mật tài khoản của bạn, Trình quản lý mật khẩu khuyên bạn nên kiểm tra các mật khẩu đã lưu.</translation>
+<translation id="6924013822850225188">Chọn xem bạn có muốn thấy các lợi ích của thẻ khi thanh toán hay không (áp dụng điều khoản của ngân hàng)</translation>
 <translation id="6925267999184670015">B+ Bắc Mỹ</translation>
 <translation id="6926216138694948720">Nghệ thuật vẽ trên cơ thể</translation>
 <translation id="692638818576287323">Xe thương mại</translation>
@@ -3832,6 +3833,7 @@
 <translation id="830498451218851433">Gấp đôi</translation>
 <translation id="8308653357438598313">Truyền video trực tiếp</translation>
 <translation id="8311895354659782580">Danh bạ bất động sản</translation>
+<translation id="8312841338723044391">TRỰC TIẾP</translation>
 <translation id="8316555157357957253">Đang sử dụng</translation>
 <translation id="8319269383395457801">Bán nhà ở</translation>
 <translation id="831997045666694187">Buổi tối</translation>
diff --git a/components/strings/components_strings_zh-HK.xtb b/components/strings/components_strings_zh-HK.xtb
index 44dc6cd..b6e5895 100644
--- a/components/strings/components_strings_zh-HK.xtb
+++ b/components/strings/components_strings_zh-HK.xtb
@@ -3062,6 +3062,7 @@
 <translation id="6915804003454593391">使用者:</translation>
 <translation id="6916193791494646625">請提供下載的原因 (必填)</translation>
 <translation id="6917795328362592458">系統發現您剛才使用的密碼因資料外洩而被洩露。為確保帳戶安全,「密碼管理工具」建議您檢查已儲存的密碼。</translation>
+<translation id="6924013822850225188">選擇是否在結帳時查看付款卡禮遇 (根據銀行條款規定)</translation>
 <translation id="6925267999184670015">North American B+</translation>
 <translation id="6926216138694948720">人體藝術</translation>
 <translation id="692638818576287323">商用汽車</translation>
@@ -3831,6 +3832,7 @@
 <translation id="830498451218851433">對摺</translation>
 <translation id="8308653357438598313">直播影片串流</translation>
 <translation id="8311895354659782580">房地產出售</translation>
+<translation id="8312841338723044391">直播</translation>
 <translation id="8316555157357957253">使用中</translation>
 <translation id="8319269383395457801">住宅出售</translation>
 <translation id="831997045666694187">傍晚</translation>
diff --git a/components/strings/components_strings_zu.xtb b/components/strings/components_strings_zu.xtb
index 32954a4..c53ca5e3 100644
--- a/components/strings/components_strings_zu.xtb
+++ b/components/strings/components_strings_zu.xtb
@@ -3060,6 +3060,7 @@
 <translation id="6915804003454593391">Umsebenzisi:</translation>
 <translation id="6916193791494646625">Nikeza isizathu sokudawuniloda (kuyadingeka)</translation>
 <translation id="6917795328362592458">Iphasiwedi osanda kuyisebenzisa itholakele ekwephuleni isivumelwano sedatha. Ukuze ivikele ama-akhawunti akho, Isiphathi Sephasiwedi sincoma ukuhlola amaphasiwedi akho alondoloziwe.</translation>
+<translation id="6924013822850225188">Khetha uma ngabe ubona izinzuzo zekhadi lakho ekuphumeni (kusebenza imigomo yasebhange)</translation>
 <translation id="6925267999184670015">North American B+</translation>
 <translation id="6926216138694948720">Ubuciko bomzimba</translation>
 <translation id="692638818576287323">Izimoto Zezokuthengisa</translation>
@@ -3829,6 +3830,7 @@
 <translation id="830498451218851433">Goqa ngohafu</translation>
 <translation id="8308653357438598313">Ukusakaza Ividiyo Bukhoma</translation>
 <translation id="8311895354659782580">Uhlu Lwezindlu Ezithengiwayo</translation>
+<translation id="8312841338723044391">BUKHOMA</translation>
 <translation id="8316555157357957253">Iyasebenzisa manje</translation>
 <translation id="8319269383395457801">Ukuthengiswa Kwezindawo Zokuhlala</translation>
 <translation id="831997045666694187">Kusihlwa</translation>
diff --git a/components/supervised_user/core/browser/proto_fetcher.cc b/components/supervised_user/core/browser/proto_fetcher.cc
index 7532585..7f11385 100644
--- a/components/supervised_user/core/browser/proto_fetcher.cc
+++ b/components/supervised_user/core/browser/proto_fetcher.cc
@@ -271,11 +271,9 @@
                           stopwatch_.Elapsed());
 }
 
-void Metrics::RecordAuthError(const ProtoFetcherStatus& status) const {
-  CHECK_EQ(status.state(),
-           ProtoFetcherStatus::State::GOOGLE_SERVICE_AUTH_ERROR);
+void Metrics::RecordAuthError(const GoogleServiceAuthError& auth_error) const {
   base::UmaHistogramEnumeration(GetFullHistogramName(MetricType::kAuthError),
-                                status.google_service_auth_error().state(),
+                                auth_error.state(),
                                 GoogleServiceAuthError::NUM_STATES);
 }
 
@@ -422,21 +420,12 @@
   metrics_->RecordLatency();
   metrics_->RecordStatusLatency(status);
 
-  // Record additional status-specific metrics.
-  switch (status.state()) {
-    case ProtoFetcherStatus::State::GOOGLE_SERVICE_AUTH_ERROR:
-      metrics_->RecordAuthError(status);
-      break;
+  if (access_token_auth_error_) {
+    metrics_->RecordAuthError(access_token_auth_error_.value());
+  }
 
-    case ProtoFetcherStatus::State::HTTP_STATUS_OR_NET_ERROR:
-      metrics_->RecordHttpStatusOrNetError(status);
-      break;
-
-    case ProtoFetcherStatus::State::OK:
-    case ProtoFetcherStatus::State::INVALID_RESPONSE:
-    case ProtoFetcherStatus::State::DATA_ERROR:
-      // No additional metrics to record.
-      break;
+  if (status.state() == ProtoFetcherStatus::State::HTTP_STATUS_OR_NET_ERROR) {
+    metrics_->RecordHttpStatusOrNetError(status);
   }
 }
 
@@ -444,11 +433,13 @@
     scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
     base::expected<signin::AccessTokenInfo, GoogleServiceAuthError>
         access_token) {
-  if (!access_token.has_value() &&
-      config_.access_token_config.credentials_requirement ==
-          AccessTokenConfig::CredentialsRequirement::kStrict) {
-    OnError(ProtoFetcherStatus::GoogleServiceAuthError(access_token.error()));
-    return;
+  if (!access_token.has_value()) {
+    access_token_auth_error_ = access_token.error();
+    if (config_.access_token_config.credentials_requirement ==
+        AccessTokenConfig::CredentialsRequirement::kStrict) {
+      OnError(ProtoFetcherStatus::GoogleServiceAuthError(access_token.error()));
+      return;
+    }
   }
 
   if (IsMetricsRecordingEnabled()) {
diff --git a/components/supervised_user/core/browser/proto_fetcher.h b/components/supervised_user/core/browser/proto_fetcher.h
index 51810d4..8c560bc3 100644
--- a/components/supervised_user/core/browser/proto_fetcher.h
+++ b/components/supervised_user/core/browser/proto_fetcher.h
@@ -178,7 +178,7 @@
   void RecordApiLatency(
       ProtoFetcherStatus::HttpStatusOrNetErrorType http_status_or_net_error);
   virtual void RecordStatusLatency(const ProtoFetcherStatus& status) const;
-  void RecordAuthError(const ProtoFetcherStatus& status) const;
+  void RecordAuthError(const GoogleServiceAuthError& auth_error) const;
   void RecordHttpStatusOrNetError(const ProtoFetcherStatus& status) const;
 
  protected:
@@ -293,6 +293,10 @@
   // followed by a request made with SimpleURLLoader. Purposely made last field
   // should it depend on other members of this class.
   ApiAccessTokenFetcher fetcher_;
+
+  // If an auth error was encountered when fetching the access token, it is
+  // stored here (whether or not it was fatal).
+  std::optional<GoogleServiceAuthError> access_token_auth_error_;
 };
 
 // Overlay over ProtoFetcher that interprets successful responses as given
diff --git a/components/supervised_user/core/browser/proto_fetcher_unittest.cc b/components/supervised_user/core/browser/proto_fetcher_unittest.cc
index 8d82ace..7ecdfdd 100644
--- a/components/supervised_user/core/browser/proto_fetcher_unittest.cc
+++ b/components/supervised_user/core/browser/proto_fetcher_unittest.cc
@@ -904,6 +904,15 @@
   SimulateDefaultResponseForPendingRequest(0);
 
   EXPECT_TRUE(receiver->GetResult().has_value());
+
+  // Check that both the overall Status, and the detailed AuthError metrics
+  // are recorded.
+  histogram_tester.ExpectUniqueSample(
+      base::StrCat({*GetConfig().histogram_basename, ".Status"}),
+      ProtoFetcherStatus::State::OK, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StrCat({*GetConfig().histogram_basename, ".AuthError"}),
+      GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS, 1);
 }
 
 class FetchManagerTest : public testing::Test {
diff --git a/components/supervised_user/core/common/features.cc b/components/supervised_user/core/common/features.cc
index edb9dbf..12fd26e 100644
--- a/components/supervised_user/core/common/features.cc
+++ b/components/supervised_user/core/common/features.cc
@@ -131,6 +131,9 @@
 BASE_FEATURE(kReplaceSupervisionPrefsWithAccountCapabilitiesOnIOS,
              "ReplaceSupervisionPrefsWithAccountCapabilitiesOnIOS",
              base::FEATURE_ENABLED_BY_DEFAULT);
+BASE_FEATURE(kReplaceSupervisionSystemCapabilitiesWithAccountCapabilitiesOnIOS,
+             "ReplaceSupervisionSystemCapabilitiesWithAccountCapabilitiesOnIOS",
+             base::FEATURE_ENABLED_BY_DEFAULT);
 #endif
 
 bool IsKidFriendlyContentFeedAvailable() {
diff --git a/components/supervised_user/core/common/features.h b/components/supervised_user/core/common/features.h
index e6b796d..2a76230 100644
--- a/components/supervised_user/core/common/features.h
+++ b/components/supervised_user/core/common/features.h
@@ -79,6 +79,9 @@
 // Replaces usages of prefs::kSupervisedUserID with AccountInfo capabilities on
 // iOS.
 BASE_DECLARE_FEATURE(kReplaceSupervisionPrefsWithAccountCapabilitiesOnIOS);
+// Replaces usages of system capabilities with AccountInfo capabilities on iOS.
+BASE_DECLARE_FEATURE(
+    kReplaceSupervisionSystemCapabilitiesWithAccountCapabilitiesOnIOS);
 #endif
 
 // Returns whether local parent approvals on Family Link user's device are
diff --git a/components/sync/base/model_type.h b/components/sync/base/model_type.h
index ae558f8..f1e9be7 100644
--- a/components/sync/base/model_type.h
+++ b/components/sync/base/model_type.h
@@ -403,8 +403,8 @@
 // unsynced data. The warning offers the user to either save the data locally or
 // abort sign-out, depending on the platform.
 constexpr ModelTypeSet TypesRequiringUnsyncedDataCheckOnSignout() {
-  return {syncer::BOOKMARKS, syncer::READING_LIST, syncer::PASSWORDS,
-          syncer::CONTACT_INFO};
+  return {syncer::BOOKMARKS, syncer::CONTACT_INFO, syncer::PASSWORDS,
+          syncer::READING_LIST, syncer::SAVED_TAB_GROUP};
 }
 
 // User types that can be encrypted, which is a subset of UserTypes() and a
diff --git a/components/sync/service/passphrase_type_metrics_provider.cc b/components/sync/service/passphrase_type_metrics_provider.cc
index ecfbda39..5cf8f36 100644
--- a/components/sync/service/passphrase_type_metrics_provider.cc
+++ b/components/sync/service/passphrase_type_metrics_provider.cc
@@ -76,8 +76,8 @@
 PassphraseTypeMetricsProvider::~PassphraseTypeMetricsProvider() = default;
 
 bool PassphraseTypeMetricsProvider::ProvideHistograms() {
-  // TODO(crbug.com/338027160): Remove Sync.PassphraseType2 once
-  // Sync.PassphraseType3 reaches the stable channel.
+  // TODO(crbug.com/347711860): Remove Sync.PassphraseType2 on 06/2025 once
+  // Sync.PassphraseType3 has been available for a year.
   base::UmaHistogramEnumeration(
       "Sync.PassphraseType2",
       GetPassphraseTypeForAllProfiles(get_all_sync_services_callback_.Run(),
diff --git a/components/test/data/autofill/heuristics-json/internal b/components/test/data/autofill/heuristics-json/internal
index 8fd2aef9..1a305f4 160000
--- a/components/test/data/autofill/heuristics-json/internal
+++ b/components/test/data/autofill/heuristics-json/internal
@@ -1 +1 @@
-Subproject commit 8fd2aef905fe4040b989aa45b40c545d0926b590
+Subproject commit 1a305f4778c0bde5f4b02e987a41e5df51217f82
diff --git a/components/variations/field_trial_config/field_trial_util_unittest.cc b/components/variations/field_trial_config/field_trial_util_unittest.cc
index 87e1e6b6..8b64759 100644
--- a/components/variations/field_trial_config/field_trial_util_unittest.cc
+++ b/components/variations/field_trial_config/field_trial_util_unittest.cc
@@ -11,6 +11,7 @@
 
 #include "base/command_line.h"
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/strings/utf_string_conversions.h"
@@ -57,17 +58,17 @@
   }
 
   const char* name = nullptr;
-  base::span<const Study::Platform> platforms = {};
-  base::span<const Study::FormFactor> form_factors = {};
+  base::raw_span<const Study::Platform> platforms = {};
+  base::raw_span<const Study::FormFactor> form_factors = {};
   std::optional<bool> is_low_end_device = std::nullopt;
   const char* min_os_version = nullptr;
-  base::span<const FieldTrialTestingExperimentParams> params = {};
-  base::span<const char*> enable_features = {};
-  base::span<const char*> disable_features = {};
+  base::raw_span<const FieldTrialTestingExperimentParams> params = {};
+  base::raw_span<const char*> enable_features = {};
+  base::raw_span<const char*> disable_features = {};
   const char* forcing_flag = nullptr;
-  base::span<const OverrideUIString> override_ui_string = {};
-  base::span<const char*> hardware_classes = {};
-  base::span<const char*> exclude_hardware_classes = {};
+  base::raw_span<const OverrideUIString> override_ui_string = {};
+  base::raw_span<const char*> hardware_classes = {};
+  base::raw_span<const char*> exclude_hardware_classes = {};
 };
 
 class TestOverrideStringCallback {
diff --git a/components/variations/service/ui_string_overrider.cc b/components/variations/service/ui_string_overrider.cc
index 78791448..3b1c4bfc 100644
--- a/components/variations/service/ui_string_overrider.cc
+++ b/components/variations/service/ui_string_overrider.cc
@@ -20,6 +20,8 @@
   CHECK_EQ(resource_hashes_.size(), resource_indices_.size());
 }
 
+UIStringOverrider::UIStringOverrider(const UIStringOverrider&) = default;
+
 UIStringOverrider::~UIStringOverrider() = default;
 
 int UIStringOverrider::GetResourceIndex(uint32_t hash) {
diff --git a/components/variations/service/ui_string_overrider.h b/components/variations/service/ui_string_overrider.h
index 671cc13d..9af9eae1 100644
--- a/components/variations/service/ui_string_overrider.h
+++ b/components/variations/service/ui_string_overrider.h
@@ -9,6 +9,7 @@
 #include <stdint.h>
 
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 
 namespace variations {
 
@@ -35,6 +36,8 @@
   UIStringOverrider(base::span<const uint32_t> resource_hashes,
                     base::span<const int> resource_indices);
 
+  UIStringOverrider(const UIStringOverrider&);
+
   UIStringOverrider& operator=(const UIStringOverrider&) = delete;
 
   ~UIStringOverrider();
@@ -44,8 +47,8 @@
   int GetResourceIndex(uint32_t hash);
 
  private:
-  const base::span<const uint32_t> resource_hashes_;
-  const base::span<const int> resource_indices_;
+  const base::raw_span<const uint32_t> resource_hashes_;
+  const base::raw_span<const int> resource_indices_;
 };
 
 }  // namespace variations
diff --git a/components/vector_icons/BUILD.gn b/components/vector_icons/BUILD.gn
index 657874a..c1c0912 100644
--- a/components/vector_icons/BUILD.gn
+++ b/components/vector_icons/BUILD.gn
@@ -285,8 +285,6 @@
       "google_chrome/page_insights.icon",
       "google_chrome/page_insights_color.icon",
       "google_chrome/pen_spark.icon",
-      "google_chrome/plus_address_logo_large.icon",
-      "google_chrome/plus_address_logo_small.icon",
     ]
   }
 }
diff --git a/components/viz/service/display/overlay_processor_ozone.cc b/components/viz/service/display/overlay_processor_ozone.cc
index aeee010ea..1884bdb6 100644
--- a/components/viz/service/display/overlay_processor_ozone.cc
+++ b/components/viz/service/display/overlay_processor_ozone.cc
@@ -416,10 +416,6 @@
         std::min(max_overlays_supported, max_overlays_config_);
     has_independent_cursor_plane_ =
         hardware_capabilities.has_independent_cursor_plane;
-
-    UMA_HISTOGRAM_COUNTS_100(
-        "Compositing.Display.OverlayProcessorOzone.MaxPlanesSupported",
-        hardware_capabilities.num_overlay_capable_planes);
   } else {
     // Default to attempting 1 overlay if we get an invalid response.
     max_overlays_considered_ = 1;
diff --git a/components/viz/service/display/overlay_processor_using_strategy.cc b/components/viz/service/display/overlay_processor_using_strategy.cc
index 113b565..6addfcf 100644
--- a/components/viz/service/display/overlay_processor_using_strategy.cc
+++ b/components/viz/service/display/overlay_processor_using_strategy.cc
@@ -408,7 +408,6 @@
         resource_provider, render_passes, &surface_damage_rect_list,
         output_surface_plane, candidates, content_bounds, damage_rect);
   }
-  LogCheckOverlaySupportMetrics();
 
   DCHECK(candidates->empty() || success);
   UMA_HISTOGRAM_COUNTS_100(kNumOverlaysPromotedHistogramName,
@@ -439,18 +438,7 @@
     primary_plane_color_space_ = primary_plane->color_space;
 #endif
 
-  base::ElapsedTimer timer;
   CheckOverlaySupportImpl(primary_plane, candidate_list);
-  check_overlay_support_call_count_++;
-
-  base::TimeDelta time = timer.Elapsed();
-
-  static constexpr base::TimeDelta kMinTime = base::Microseconds(1);
-  static constexpr base::TimeDelta kMaxTime = base::Milliseconds(10);
-  static constexpr int kTimeBuckets = 50;
-  UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
-      "Compositing.Display.OverlayProcessorUsingStrategy.CheckOverlaySupportUs",
-      time, kMinTime, kMaxTime, kTimeBuckets);
 }
 
 void OverlayProcessorUsingStrategy::ClearOverlayCombinationCache() {
@@ -1196,12 +1184,4 @@
   max_failed_scale_ = std::min(max_failed_scale_, kMaxFailedScaleMin);
 }
 
-void OverlayProcessorUsingStrategy::LogCheckOverlaySupportMetrics() {
-  UMA_HISTOGRAM_COUNTS_100(
-      "Compositing.Display.OverlayProcessorUsingStrategy."
-      "CheckOverlaySupportCallCount",
-      check_overlay_support_call_count_);
-  check_overlay_support_call_count_ = 0;
-}
-
 }  // namespace viz
diff --git a/components/viz/service/display/overlay_processor_using_strategy.h b/components/viz/service/display/overlay_processor_using_strategy.h
index 6e0e0701..53ce20a 100644
--- a/components/viz/service/display/overlay_processor_using_strategy.h
+++ b/components/viz/service/display/overlay_processor_using_strategy.h
@@ -252,10 +252,6 @@
   // be whether that scaling worked or not.
   void UpdateDownscalingCapabilities(float scale_factor, bool success);
 
-  // Logs the number of times CheckOverlaySupport was called this frame, and
-  // resets the counter to 0.
-  void LogCheckOverlaySupportMetrics();
-
   // Moves `curr_overlays` into `prev_overlays`, and updates `curr_overlays` to
   // reflect the overlays that will be promoted this frame in `candidates`.
   void UpdateOverlayStatusMap(const OverlayCandidateList& candidates);
@@ -270,7 +266,6 @@
   base::TimeTicks last_time_interval_switch_overlay_tick_;
   ProposedCandidateKey prev_overlay_tracking_id_;
   uint64_t frame_sequence_number_ = 0;
-  int check_overlay_support_call_count_ = 0;
 
   // These values are used for tracking how much we can downscale with overlays
   // and is used for when we require an overlay so we can determine how much we
diff --git a/components/viz/service/display_embedder/skia_output_device_dawn.cc b/components/viz/service/display_embedder/skia_output_device_dawn.cc
index 946b6a2..37c9909 100644
--- a/components/viz/service/display_embedder/skia_output_device_dawn.cc
+++ b/components/viz/service/display_embedder/skia_output_device_dawn.cc
@@ -112,17 +112,24 @@
   surface_desc.nextInChain = &android_native_window_desc;
 #endif
 
-  CHECK(context_state_->dawn_context_provider() &&
-        context_state_->dawn_context_provider()->GetDevice());
+  auto* context_provider = context_state_->dawn_context_provider();
+  CHECK(context_provider && context_provider->GetDevice());
 
-  surface_ =
-      context_state_->dawn_context_provider()->GetInstance().CreateSurface(
-          &surface_desc);
-  CHECK(surface_);
-  wgpu::TextureUsage supported_usage = context_state_->dawn_context_provider()
-                                           ->GetDevice()
-                                           .GetSupportedSurfaceUsage(surface_);
-  CHECK_EQ(~supported_usage & kUsage, 0);
+  surface_ = context_provider->GetInstance().CreateSurface(&surface_desc);
+
+  // With Dawn/Vulkan the Vulkan surface is created lazily when needed, like
+  // here for GetCapabilities(), and not when `surface_` is created. This may
+  // fail.
+  wgpu::SurfaceCapabilities caps;
+  wgpu::Status result =
+      surface_.GetCapabilities(context_provider->GetAdapter(), &caps);
+  // TOOD(crbug.com/347047834): This is where vkCreateAndroidSurfaceKHR()
+  // failures first show up. Have SkiaOutputDeviceDawn creation fail instead of
+  // crashing the GPU process.
+  CHECK_EQ(result, wgpu::Status::Success);
+
+  // Verify `surface_` supports all the required usage for the swap chain.
+  CHECK_EQ(~caps.usages & kUsage, 0);
 }
 
 SkiaOutputDeviceDawn::~SkiaOutputDeviceDawn() = default;
diff --git a/components/viz/service/display_embedder/skia_output_device_gl.cc b/components/viz/service/display_embedder/skia_output_device_gl.cc
index c6a03b5..b6dca7a8 100644
--- a/components/viz/service/display_embedder/skia_output_device_gl.cc
+++ b/components/viz/service/display_embedder/skia_output_device_gl.cc
@@ -30,7 +30,6 @@
 #include "ui/gl/gl_features.h"
 #include "ui/gl/gl_implementation.h"
 #include "ui/gl/gl_surface.h"
-#include "ui/gl/gl_version_info.h"
 
 namespace viz {
 
@@ -137,20 +136,12 @@
   DCHECK(context_state_->context());
 
   GrDirectContext* gr_context = context_state_->gr_context();
-  gl::CurrentGL* current_gl = context_state_->context()->GetCurrentGL();
 
   // Get alpha bits from the default frame buffer.
   int alpha_bits = 0;
   glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
   gr_context->resetContext(kRenderTarget_GrGLBackendState);
-  const auto* version = current_gl->Version.get();
-  if (version->is_desktop_core_profile) {
-    glGetFramebufferAttachmentParameterivEXT(
-        GL_FRAMEBUFFER, GL_BACK_LEFT, GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
-        &alpha_bits);
-  } else {
-    glGetIntegerv(GL_ALPHA_BITS, &alpha_bits);
-  }
+  glGetIntegerv(GL_ALPHA_BITS, &alpha_bits);
   CHECK_GL_ERROR();
 
   auto color_type = kRGBA_8888_SkColorType;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
index ad0f4e7..05630fb1 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -406,8 +406,7 @@
 
 #if BUILDFLAG(ENABLE_VULKAN)
     // No frame will come for us, make sure that all the cleanup is done.
-    if (base::FeatureList::IsEnabled(features::kGpuCleanupInBackground) &&
-        context_state_->GrContextIsVulkan()) {
+    if (context_state_->GrContextIsVulkan()) {
       DCHECK(context_state_->vk_context_provider());
       auto* fence_helper = context_state_->vk_context_provider()
                                ->GetDeviceQueue()
diff --git a/components/web_package/input_reader.cc b/components/web_package/input_reader.cc
index 256779d..94e0dbd 100644
--- a/components/web_package/input_reader.cc
+++ b/components/web_package/input_reader.cc
@@ -4,10 +4,53 @@
 
 #include "components/web_package/input_reader.h"
 
+#include "base/containers/contains.h"
+#include "base/functional/overloaded.h"
+#include "base/numerics/checked_math.h"
 #include "base/strings/string_util.h"
+#include "base/types/cxx23_to_underlying.h"
+#include "components/cbor/constants.h"
+#include "components/cbor/values.h"
 
 namespace web_package {
 
+namespace {
+
+// This array must be kept in sync with the `CBORType` enum.
+constexpr std::array kAcceptedCBORTypes = {
+    // clang-format off
+    CBORType::kUnsignedInt,
+    CBORType::kNegativeInt,
+    CBORType::kByteString,
+    CBORType::kTextString,
+    CBORType::kArray,
+    CBORType::kMap,
+    CBORType::kSimpleValue,
+    // clang-format on
+};
+
+std::optional<int64_t> DecodeValueToNegative(uint64_t value) {
+  auto negative_value = -base::CheckedNumeric<int64_t>(value) - 1;
+  if (!negative_value.IsValid()) {
+    return std::nullopt;
+  }
+  return static_cast<int64_t>(negative_value.ValueOrDie());
+}
+
+std::optional<int64_t> DecodeValueToUnsigned(uint64_t value) {
+  auto unsigned_value = base::CheckedNumeric<int64_t>(value);
+  if (!unsigned_value.IsValid()) {
+    return std::nullopt;
+  }
+  return static_cast<int64_t>(unsigned_value.ValueOrDie());
+}
+
+}  // namespace
+
+InputReader::InputReader(base::span<const uint8_t> buf) : buf_(buf) {}
+
+InputReader::~InputReader() = default;
+
 std::optional<uint8_t> InputReader::ReadByte() {
   uint8_t b;
   if (!buf_.ReadU8BigEndian(b)) {
@@ -39,6 +82,59 @@
   return pair->second;
 }
 
+std::optional<CBORHeader> InputReader::ReadCBORHeader() {
+  auto pair = ReadTypeAndArgument();
+  if (!pair) {
+    return std::nullopt;
+  }
+
+  const auto& [type, additional_info] = *pair;
+  switch (type) {
+    case CBORType::kSimpleValue: {
+      using SimpleValue = cbor::Value::SimpleValue;
+      if (additional_info == base::to_underlying(SimpleValue::TRUE_VALUE)) {
+        return {{true}};
+      } else if (additional_info ==
+                 base::to_underlying(SimpleValue::FALSE_VALUE)) {
+        return {{false}};
+      } else {
+        return std::nullopt;
+      }
+    }
+    case CBORType::kUnsignedInt:
+    case CBORType::kNegativeInt: {
+      std::optional<int64_t> value =
+          type == CBORType::kUnsignedInt
+              ? DecodeValueToUnsigned(additional_info)
+              : DecodeValueToNegative(additional_info);
+      if (!value) {
+        return std::nullopt;
+      }
+      return {{*value}};
+    }
+    case CBORType::kByteString:
+    case CBORType::kTextString: {
+      using StringInfo = CBORHeader::StringInfo;
+      using StringType = CBORHeader::StringInfo::StringType;
+
+      return {{StringInfo{.type = type == CBORType::kByteString
+                                      ? StringType::kByteString
+                                      : StringType::kTextString,
+                          .byte_length = additional_info}}};
+    }
+    case CBORType::kArray:
+    case CBORType::kMap: {
+      using ContainerInfo = CBORHeader::ContainerInfo;
+      using ContainerType = CBORHeader::ContainerInfo::ContainerType;
+
+      return {{ContainerInfo{.type = type == CBORType::kArray
+                                         ? ContainerType::kArray
+                                         : ContainerType::kMap,
+                             .size = additional_info}}};
+    }
+  }
+}
+
 // https://datatracker.ietf.org/doc/html/rfc8949.html#section-3
 std::optional<std::pair<CBORType, uint64_t>>
 InputReader::ReadTypeAndArgument() {
@@ -47,8 +143,17 @@
     return std::nullopt;
   }
 
-  CBORType type = static_cast<CBORType>((*first_byte & 0xE0) / 0x20);
-  uint8_t b = *first_byte & 0x1F;
+  // There are more CBOR types in the standard than we accept. To avoid mishits
+  // during `static_cast<CBORType>`, it's safer to validate the type beforehand.
+  uint8_t type_byte = (*first_byte & cbor::constants::kMajorTypeMask) >>
+                      cbor::constants::kMajorTypeBitShift;
+  if (!base::Contains(kAcceptedCBORTypes, type_byte,
+                      &base::to_underlying<CBORType>)) {
+    return std::nullopt;
+  }
+
+  CBORType type = static_cast<CBORType>(type_byte);
+  uint8_t b = *first_byte & cbor::constants::kAdditionalInformationMask;
 
   if (b <= 23) {
     return std::make_pair(type, b);
diff --git a/components/web_package/input_reader.h b/components/web_package/input_reader.h
index 34dfb927..f1ac295b 100644
--- a/components/web_package/input_reader.h
+++ b/components/web_package/input_reader.h
@@ -10,17 +10,42 @@
 
 #include "base/containers/span.h"
 #include "base/containers/span_reader.h"
+#include "base/memory/stack_allocated.h"
+#include "base/types/id_type.h"
+#include "third_party/abseil-cpp/absl/types/variant.h"
 
 namespace web_package {
 
 // https://datatracker.ietf.org/doc/html/rfc8949.html#section-3.1
 enum class CBORType {
-  // kUnsignedInt = 0,
-  // kNegativeInt = 1,
+  kUnsignedInt = 0,
+  kNegativeInt = 1,
   kByteString = 2,
   kTextString = 3,
   kArray = 4,
   kMap = 5,
+  // kTag = 6,
+  kSimpleValue = 7,
+  // kFloatValue = 7,
+};
+
+struct CBORHeader {
+  struct StringInfo {
+    enum class StringType {
+      kByteString,
+      kTextString,
+    } type;
+    uint64_t byte_length;
+  };
+  struct ContainerInfo {
+    enum class ContainerType {
+      kArray,
+      kMap,
+    } type;
+    uint64_t size;
+  };
+
+  const absl::variant<bool, int64_t, StringInfo, ContainerInfo> data;
 };
 
 // The maximum length of the CBOR item header (type and argument).
@@ -31,12 +56,16 @@
 
 // A utility class for reading various values from input buffer.
 class InputReader {
+  STACK_ALLOCATED();
+
  public:
-  explicit InputReader(base::span<const uint8_t> buf) : buf_(buf) {}
+  explicit InputReader(base::span<const uint8_t> buf);
 
   InputReader(const InputReader&) = delete;
   InputReader& operator=(const InputReader&) = delete;
 
+  ~InputReader();
+
   size_t CurrentOffset() const { return buf_.num_read(); }
   size_t Size() const { return buf_.remaining(); }
 
@@ -62,10 +91,17 @@
   std::optional<std::string_view> ReadString(size_t n);
 
   // Parses the type and argument of a CBOR item from the input head. If parsed
-  // successfully and the type matches |expected_type|, returns the argument.
+  // successfully and the type matches `expected_type`, returns the argument.
   // Otherwise returns nullopt.
   std::optional<uint64_t> ReadCBORHeader(CBORType expected_type);
 
+  // Parses the type and argument of a CBOR item from the input head. If parsed
+  // successfully, returns type and:
+  //  * value for kUnsignedInt/kNegativeInt;
+  //  * value_size for kTextString/kByteString/kMap/kArray.
+  // Otherwise returns nullopt.
+  std::optional<CBORHeader> ReadCBORHeader();
+
  private:
   std::optional<std::pair<CBORType, uint64_t>> ReadTypeAndArgument();
 
diff --git a/components/web_package/signed_web_bundles/attribute_map_parser.cc b/components/web_package/signed_web_bundles/attribute_map_parser.cc
index 4978ee25..a9c135c 100644
--- a/components/web_package/signed_web_bundles/attribute_map_parser.cc
+++ b/components/web_package/signed_web_bundles/attribute_map_parser.cc
@@ -6,6 +6,7 @@
 
 #include "base/containers/contains.h"
 #include "base/containers/extend.h"
+#include "base/functional/overloaded.h"
 #include "base/strings/stringprintf.h"
 #include "base/types/expected_macros.h"
 #include "components/web_package/input_reader.h"
@@ -67,8 +68,7 @@
 void AttributeMapParser::ReadAttributeNameCborHeader(
     const std::optional<BinaryData>& data) {
   if (!data) {
-    RunErrorCallback(
-        "Error reading signature stack entry's attributes header.");
+    RunErrorCallback("Error reading the header for attribute name.");
     return;
   }
 
@@ -91,7 +91,7 @@
     uint64_t attribute_name_length,
     const std::optional<BinaryData>& data) {
   if (!data) {
-    RunErrorCallback("Error reading signature stack entry's attribute key.");
+    RunErrorCallback("Error reading attribute key.");
     return;
   }
 
@@ -101,15 +101,14 @@
       });
 
   if (!attribute_name) {
-    RunErrorCallback("Error reading signature stack entry's attribute key.");
+    RunErrorCallback("Error reading attribute key.");
     return;
   }
 
   if (base::Contains(attributes_map_, *attribute_name)) {
-    RunErrorCallback(
-        base::StringPrintf("Found duplicate attribute name <%s> in signature "
-                           "stack entry's attributes.",
-                           std::string(*attribute_name).c_str()));
+    RunErrorCallback(base::StringPrintf(
+        "Found duplicate attribute name <%s> in the attributes map.",
+        std::string(*attribute_name).c_str()));
     return;
   }
 
@@ -123,38 +122,81 @@
     std::string attribute_name,
     const std::optional<BinaryData>& data) {
   if (!data) {
-    RunErrorCallback("Error reading signature stack entry's attribute key.");
-    return;
-  }
-
-  std::optional<uint64_t> attribute_value_size =
-      ReadCborData(*data, [](InputReader* input) {
-        return input->ReadCBORHeader(CBORType::kByteString);
-      });
-  if (!attribute_value_size) {
     RunErrorCallback(
-        "The value of the signature stack entry attribute value must be a byte "
-        "string.");
+        base::StringPrintf("Error reading attribute value header for <%s>.",
+                           attribute_name.c_str()));
+    return;
+  }
+  std::optional<CBORHeader> result = ReadCborData(
+      *data, [](InputReader* input) { return input->ReadCBORHeader(); });
+  if (!result) {
+    RunErrorCallback(
+        base::StringPrintf("Error reading attribute value header for <%s>.",
+                           attribute_name.c_str()));
     return;
   }
 
-  data_source_->Read(
-      offset_in_stream_, *attribute_value_size,
-      base::BindOnce(&AttributeMapParser::ReadAttributeValue,
-                     weak_factory_.GetWeakPtr(), std::move(attribute_name)));
+  RETURN_IF_ERROR(
+      absl::visit(
+          base::Overloaded{
+              [&](bool value) -> base::expected<void, std::string> {
+                attributes_map_.emplace(std::move(attribute_name), value);
+                ReadNextAttributeEntry();
+                return base::ok();
+              },
+              [&](int64_t value) -> base::expected<void, std::string> {
+                attributes_map_.emplace(std::move(attribute_name), value);
+                ReadNextAttributeEntry();
+                return base::ok();
+              },
+              [&](const CBORHeader::StringInfo& info)
+                  -> base::expected<void, std::string> {
+                data_source_->Read(
+                    offset_in_stream_, info.byte_length,
+                    base::BindOnce(
+                        &AttributeMapParser::ReadStringAttributeValue,
+                        weak_factory_.GetWeakPtr(), std::move(attribute_name),
+                        info.type));
+                return base::ok();
+              },
+              [&](const CBORHeader::ContainerInfo&)
+                  -> base::expected<void, std::string> {
+                return base::unexpected(base::StringPrintf(
+                    "Attribute value for <%s> is a map/array; nested "
+                    "attributes are currently not supported.",
+                    attribute_name.c_str()));
+              }},
+          result->data),
+      [&](std::string error) { RunErrorCallback(std::move(error)); });
 }
 
-void AttributeMapParser::ReadAttributeValue(
+void AttributeMapParser::ReadStringAttributeValue(
     std::string attribute_name,
+    StringType string_type,
     const std::optional<BinaryData>& data) {
   if (!data) {
-    RunErrorCallback("Error reading signature stack entry's public key.");
+    RunErrorCallback(base::StringPrintf(
+        "Error reading attribute value for <%s>.", attribute_name.c_str()));
     return;
   }
 
-  attributes_map_[std::move(attribute_name)] = *data;
-
-  offset_in_stream_ += data->size();
+  switch (string_type) {
+    case StringType::kByteString: {
+      attributes_map_.emplace(std::move(attribute_name), *data);
+      offset_in_stream_ += data->size();
+    } break;
+    case StringType::kTextString: {
+      std::optional<std::string_view> value = ReadCborData(
+          *data,
+          [&](InputReader* input) { return input->ReadString(data->size()); });
+      if (!value) {
+        RunErrorCallback(base::StringPrintf(
+            "Error reading attribute value for <%s>.", attribute_name.c_str()));
+        return;
+      }
+      attributes_map_.emplace(std::move(attribute_name), *value);
+    }
+  }
 
   ReadNextAttributeEntry();
 }
diff --git a/components/web_package/signed_web_bundles/attribute_map_parser.h b/components/web_package/signed_web_bundles/attribute_map_parser.h
index b4e5d44..a3bfb11 100644
--- a/components/web_package/signed_web_bundles/attribute_map_parser.h
+++ b/components/web_package/signed_web_bundles/attribute_map_parser.h
@@ -14,14 +14,13 @@
 namespace web_package {
 
 // This class is responsible for parsing the attributes map of a signature entry
-// contained in the integrity block of a signed web bundle.
+// or of the integrity block itself.
 class AttributeMapParser {
  public:
   // In case of success the callback returns the attributes map and the offset
   // in the stream corresponding to the end of the attributes map.
   using AttributeMapParsedCallback = base::OnceCallback<void(
-      base::expected<std::pair<SignatureAttributesMap, uint64_t>,
-                     std::string>)>;
+      base::expected<std::pair<AttributesMap, uint64_t>, std::string>)>;
 
   explicit AttributeMapParser(mojom::BundleDataSource& data_source,
                               AttributeMapParsedCallback callback);
@@ -30,6 +29,8 @@
   void Parse(uint64_t offset_in_stream);
 
  private:
+  using StringType = CBORHeader::StringInfo::StringType;
+
   void ReadAttributesMapHeader(const std::optional<BinaryData>& data);
   void ReadNextAttributeEntry();
 
@@ -38,8 +39,9 @@
                          const std::optional<BinaryData>& data);
   void ReadAttributeValueCborHeader(std::string attribute_key,
                                     const std::optional<BinaryData>& data);
-  void ReadAttributeValue(std::string attribute_key,
-                          const std::optional<BinaryData>& data);
+  void ReadStringAttributeValue(std::string attribute_key,
+                                StringType string_type,
+                                const std::optional<BinaryData>& data);
 
   void RunSuccessCallback() {
     std::move(callback_).Run(
@@ -53,7 +55,7 @@
   uint64_t offset_in_stream_;
   const raw_ref<mojom::BundleDataSource> data_source_;
 
-  SignatureAttributesMap attributes_map_;
+  AttributesMap attributes_map_;
   uint64_t attributes_entries_left_;
 
   AttributeMapParsedCallback callback_;
diff --git a/components/web_package/signed_web_bundles/signature_entry_parser.cc b/components/web_package/signed_web_bundles/signature_entry_parser.cc
index 84b3e92..642f930 100644
--- a/components/web_package/signed_web_bundles/signature_entry_parser.cc
+++ b/components/web_package/signed_web_bundles/signature_entry_parser.cc
@@ -26,23 +26,23 @@
 using SignatureType = mojom::SignatureInfo::Tag;
 
 std::pair<SignatureType, BinaryData> GetSignatureType(
-    const SignatureAttributesMap& attributes_map) {
-  const BinaryData* ed25519_key =
+    const AttributesMap& attributes_map) {
+  const cbor::Value* ed25519_key =
       base::FindOrNull(attributes_map, kEd25519PublicKeyAttributeName);
-  const BinaryData* ecdsa_key =
+  const cbor::Value* ecdsa_key =
       base::FindOrNull(attributes_map, kEcdsaP256PublicKeyAttributeName);
 
   if (ed25519_key && ecdsa_key) {
     // The signature type cannot be determined if the attributes map contains
     // both keys.
     return {SignatureType::kUnknown, BinaryData()};
-  } else if (ecdsa_key) {
-    return {SignatureType::kEcdsaP256Sha256, *ecdsa_key};
-  } else if (ed25519_key) {
-    return {SignatureType::kEd25519, *ed25519_key};
+  } else if (ecdsa_key && ecdsa_key->is_bytestring()) {
+    return {SignatureType::kEcdsaP256Sha256, ecdsa_key->GetBytestring()};
+  } else if (ed25519_key && ed25519_key->is_bytestring()) {
+    return {SignatureType::kEd25519, ed25519_key->GetBytestring()};
   } else {
     // The signature type cannot be determined neither key is present in the
-    // attributes map.
+    // attributes map or the key is not a valid bytestring.
     return {SignatureType::kUnknown, BinaryData()};
   };
 }
@@ -104,8 +104,7 @@
 }
 
 void SignatureStackEntryParser::GetAttributesMap(
-    base::expected<std::pair<SignatureAttributesMap, uint64_t>, std::string>
-        result) {
+    base::expected<std::pair<AttributesMap, uint64_t>, std::string> result) {
   if (!result.has_value()) {
     RunErrorCallback(std::move(result.error()));
     return;
@@ -113,7 +112,7 @@
 
   auto [attributes_map, offset_to_end_of_map] = std::move(result.value());
 
-  attributes_map_ = attributes_map;
+  attributes_map_ = std::move(attributes_map);
   uint64_t attribute_map_size = offset_to_end_of_map - offset_in_stream_;
   data_source_->Read(
       offset_in_stream_, attribute_map_size,
diff --git a/components/web_package/signed_web_bundles/signature_entry_parser.h b/components/web_package/signed_web_bundles/signature_entry_parser.h
index afd24677..dfef974 100644
--- a/components/web_package/signed_web_bundles/signature_entry_parser.h
+++ b/components/web_package/signed_web_bundles/signature_entry_parser.h
@@ -37,8 +37,7 @@
  private:
   void ReadSignatureStructure(const std::optional<BinaryData>& data);
   void GetAttributesMap(
-      base::expected<std::pair<SignatureAttributesMap, uint64_t>, std::string>
-          result);
+      base::expected<std::pair<AttributesMap, uint64_t>, std::string> result);
   void ReadAttributesMapBytes(uint64_t num_bytes,
                               const std::optional<BinaryData>& data);
   void ReadSignatureHeader(const std::optional<BinaryData>& data);
@@ -47,7 +46,7 @@
   void RunErrorCallback(const std::string& message);
 
   mojom::BundleIntegrityBlockSignatureStackEntryPtr signature_stack_entry_;
-  SignatureAttributesMap attributes_map_;
+  AttributesMap attributes_map_;
   std::unique_ptr<AttributeMapParser> attribute_map_parser_;
 
   uint64_t offset_in_stream_;
diff --git a/components/web_package/signed_web_bundles/types.h b/components/web_package/signed_web_bundles/types.h
index 634cd647..3b3e8e54 100644
--- a/components/web_package/signed_web_bundles/types.h
+++ b/components/web_package/signed_web_bundles/types.h
@@ -9,12 +9,13 @@
 #include <vector>
 
 #include "base/containers/flat_map.h"
+#include "components/cbor/values.h"
 
 namespace web_package {
 
 using BinaryData = std::vector<uint8_t>;
 
-using SignatureAttributesMap = base::flat_map<std::string, BinaryData>;
+using AttributesMap = base::flat_map<std::string, cbor::Value>;
 
 }  // namespace web_package
 
diff --git a/components/web_package/test_support/signed_web_bundles/web_bundle_signer.cc b/components/web_package/test_support/signed_web_bundles/web_bundle_signer.cc
index 7a10dea7..7c77196 100644
--- a/components/web_package/test_support/signed_web_bundles/web_bundle_signer.cc
+++ b/components/web_package/test_support/signed_web_bundles/web_bundle_signer.cc
@@ -4,6 +4,8 @@
 
 #include "components/web_package/test_support/signed_web_bundles/web_bundle_signer.h"
 
+#include <limits>
+
 #include "base/check_is_test.h"
 #include "base/containers/extend.h"
 #include "base/containers/to_vector.h"
@@ -60,37 +62,63 @@
                                   kNoPublicKeySignatureStackEntryAttribute)) {
     if (errors_for_testing.Has(IntegritySignatureErrorForTesting::
                                    kMultipleValidPublicKeyAttributes)) {
-      attributes[cbor::Value(kEd25519PublicKeyAttributeName)] =
-          cbor::Value(public_key_bytes);
+      attributes.emplace(kEd25519PublicKeyAttributeName, public_key_bytes);
 
-      attributes[cbor::Value(kEcdsaP256PublicKeyAttributeName)] = cbor::Value(
+      attributes.emplace(
+          kEcdsaP256PublicKeyAttributeName,
           base::ToVector(WebBundleSigner::EcdsaP256KeyPair::CreateRandom()
                              .public_key.bytes()));
     } else if (errors_for_testing.Has(
                    IntegritySignatureErrorForTesting::
                        kWrongSignatureStackEntryAttributeName)) {
       // Add a typo: "ee" instead of "ed".
-      attributes[cbor::Value("ee25519PublicKey")] =
-          cbor::Value(public_key_bytes);
+      attributes.emplace("ee25519PublicKey", public_key_bytes);
     } else if (errors_for_testing.Has(
                    IntegritySignatureErrorForTesting::
                        kWrongSignatureStackEntryAttributeNameLength)) {
-      attributes[cbor::Value("ed25519")] = cbor::Value(public_key_bytes);
+      attributes.emplace("ed25519", public_key_bytes);
     } else {
-      attributes[cbor::Value(absl::visit(
-          base::Overloaded{[](const Ed25519PublicKey&) {
-                             return kEd25519PublicKeyAttributeName;
-                           },
-                           [](const EcdsaP256PublicKey&) {
-                             return kEcdsaP256PublicKeyAttributeName;
-                           }},
-          public_key))] = cbor::Value(public_key_bytes);
+      attributes.emplace(
+          absl::visit(
+              base::Overloaded{[](const Ed25519PublicKey&) {
+                                 return kEd25519PublicKeyAttributeName;
+                               },
+                               [](const EcdsaP256PublicKey&) {
+                                 return kEcdsaP256PublicKeyAttributeName;
+                               }},
+              public_key),
+          public_key_bytes);
     }
   }
 
   if (errors_for_testing.Has(IntegritySignatureErrorForTesting::
-                                 kAdditionalSignatureStackEntryAttribute)) {
-    attributes[cbor::Value("foo")] = cbor::Value(public_key_bytes);
+                                 kAdditionalSignatureStackEntryAttributes)) {
+    attributes.emplace("kBinaryString", public_key_bytes);
+    attributes.emplace("kTextString", "aaaaaaaaaaaaaaaaaaa");
+
+    attributes.emplace("kZero", 0);
+
+    attributes.emplace("kSimpleValue_true", true);
+    attributes.emplace("kSimpleValue_false", false);
+
+    // Integer values: one less than 24 & one large.
+    attributes.emplace("kUnsignedInt_small", 5);
+    attributes.emplace("kUnsignedInt", std::numeric_limits<int64_t>::max());
+
+    // Negative integer values: one less than 24 (modulo) & one large.
+    attributes.emplace("kNegativeInt_small", -12);
+    attributes.emplace("kNegativeInt", std::numeric_limits<int64_t>::min());
+  }
+
+  if (errors_for_testing.Has(
+          IntegritySignatureErrorForTesting::
+              kSignatureStackEntryUnsupportedArrayAttribute)) {
+    attributes.emplace("kArrayUnsupported", cbor::Value::ArrayValue());
+  }
+
+  if (errors_for_testing.Has(IntegritySignatureErrorForTesting::
+                                 kSignatureStackEntryUnsupportedMapAttribute)) {
+    attributes.emplace("kMapUnsupported", cbor::Value::MapValue());
   }
 
   return cbor::Value(attributes);
diff --git a/components/web_package/test_support/signed_web_bundles/web_bundle_signer.h b/components/web_package/test_support/signed_web_bundles/web_bundle_signer.h
index 05601e0..ef219e1 100644
--- a/components/web_package/test_support/signed_web_bundles/web_bundle_signer.h
+++ b/components/web_package/test_support/signed_web_bundles/web_bundle_signer.h
@@ -35,11 +35,13 @@
     kInvalidPublicKeyLength,
     kWrongSignatureStackEntryAttributeName,
     kNoPublicKeySignatureStackEntryAttribute,
-    kAdditionalSignatureStackEntryAttribute,
+    kAdditionalSignatureStackEntryAttributes,
     kAdditionalSignatureStackEntryElement,
     kWrongSignatureStackEntryAttributeNameLength,
     kMultipleValidPublicKeyAttributes,
-    kMaxValue = kMultipleValidPublicKeyAttributes
+    kSignatureStackEntryUnsupportedArrayAttribute,
+    kSignatureStackEntryUnsupportedMapAttribute,
+    kMaxValue = kSignatureStackEntryUnsupportedMapAttribute,
   };
 
   using IntegritySignatureErrorsForTesting =
diff --git a/components/web_package/web_bundle_parser_unittest.cc b/components/web_package/web_bundle_parser_unittest.cc
index daf17ce..aaa0a20 100644
--- a/components/web_package/web_bundle_parser_unittest.cc
+++ b/components/web_package/web_bundle_parser_unittest.cc
@@ -250,6 +250,7 @@
 using testing::AllOf;
 using testing::Eq;
 using testing::Field;
+using testing::HasSubstr;
 using testing::Pointee;
 
 class WebBundleParserTest : public testing::Test {
@@ -965,7 +966,7 @@
   auto bundle_and_keys = SignBundle(
       unsigned_bundle, {/*integrity_block_errors=*/{},
                         {{WebBundleSigner::IntegritySignatureErrorForTesting::
-                              kAdditionalSignatureStackEntryAttribute}}});
+                              kAdditionalSignatureStackEntryAttributes}}});
   TestDataSource data_source(bundle_and_keys.bundle);
 
   ASSERT_OK_AND_ASSIGN(auto integrity_block,
@@ -1002,6 +1003,40 @@
                         Eq("Unknown cipher type of the first signature."))))));
 }
 
+TEST_F(WebBundleParserTest, SignedBundleUnsupportedSignatureAttributeMap) {
+  auto unsigned_bundle = CreateSmallBundle();
+  auto bundle_and_keys = SignBundle(
+      unsigned_bundle, {/*integrity_block_errors=*/{},
+                        {{WebBundleSigner::IntegritySignatureErrorForTesting::
+                              kSignatureStackEntryUnsupportedMapAttribute}}});
+  TestDataSource data_source(bundle_and_keys.bundle);
+
+  EXPECT_THAT(
+      ParseSignedBundleIntegrityBlock(&data_source),
+      ErrorIs(Pointee(AllOf(
+          Field(&mojom::BundleIntegrityBlockParseError::type,
+                Eq(mojom::BundleParseErrorType::kFormatError)),
+          Field(&mojom::BundleIntegrityBlockParseError::message,
+                HasSubstr("nested attributes are currently not supported"))))));
+}
+
+TEST_F(WebBundleParserTest, SignedBundleUnsupportedSignatureAttributeArray) {
+  auto unsigned_bundle = CreateSmallBundle();
+  auto bundle_and_keys = SignBundle(
+      unsigned_bundle, {/*integrity_block_errors=*/{},
+                        {{WebBundleSigner::IntegritySignatureErrorForTesting::
+                              kSignatureStackEntryUnsupportedArrayAttribute}}});
+  TestDataSource data_source(bundle_and_keys.bundle);
+
+  EXPECT_THAT(
+      ParseSignedBundleIntegrityBlock(&data_source),
+      ErrorIs(Pointee(AllOf(
+          Field(&mojom::BundleIntegrityBlockParseError::type,
+                Eq(mojom::BundleParseErrorType::kFormatError)),
+          Field(&mojom::BundleIntegrityBlockParseError::message,
+                HasSubstr("nested attributes are currently not supported"))))));
+}
+
 TEST_F(WebBundleParserTest, SignedBundleNoPublicKeyAttribute) {
   auto unsigned_bundle = CreateSmallBundle();
   auto bundle_and_keys = SignBundle(
diff --git a/content/browser/gpu/peak_gpu_memory_tracker_impl.cc b/content/browser/gpu/peak_gpu_memory_tracker_impl.cc
index bd30b31c..cec8674b 100644
--- a/content/browser/gpu/peak_gpu_memory_tracker_impl.cc
+++ b/content/browser/gpu/peak_gpu_memory_tracker_impl.cc
@@ -10,13 +10,14 @@
 #include "content/browser/gpu/gpu_process_host.h"
 #include "content/common/peak_gpu_memory_callback.h"
 #include "content/public/browser/gpu_data_manager.h"
+#include "content/public/browser/peak_gpu_memory_tracker_factory.h"
 #include "services/viz/privileged/mojom/gl/gpu_service.mojom.h"
 
 namespace content {
 
 // static
-std::unique_ptr<PeakGpuMemoryTracker> PeakGpuMemoryTracker::Create(
-    PeakGpuMemoryTracker::Usage usage) {
+std::unique_ptr<input::PeakGpuMemoryTracker>
+PeakGpuMemoryTrackerFactory::Create(input::PeakGpuMemoryTracker::Usage usage) {
   return std::make_unique<PeakGpuMemoryTrackerImpl>(usage);
 }
 
@@ -24,7 +25,7 @@
 uint32_t PeakGpuMemoryTrackerImpl::next_sequence_number_ = 0;
 
 PeakGpuMemoryTrackerImpl::PeakGpuMemoryTrackerImpl(
-    PeakGpuMemoryTracker::Usage usage)
+    input::PeakGpuMemoryTracker::Usage usage)
     : usage_(usage) {
   // Actually performs request to GPU service to begin memory tracking for
   // |sequence_number_|.
diff --git a/content/browser/gpu/peak_gpu_memory_tracker_impl.h b/content/browser/gpu/peak_gpu_memory_tracker_impl.h
index a8cfb03..d8d30e3 100644
--- a/content/browser/gpu/peak_gpu_memory_tracker_impl.h
+++ b/content/browser/gpu/peak_gpu_memory_tracker_impl.h
@@ -8,7 +8,7 @@
 #include "base/functional/callback_forward.h"
 #include "base/functional/callback_helpers.h"
 #include "base/task/single_thread_task_runner.h"
-#include "content/public/common/peak_gpu_memory_tracker.h"
+#include "components/input/peak_gpu_memory_tracker.h"
 
 namespace content {
 
@@ -20,11 +20,11 @@
 // be no report to UMA Histograms. The same for if there is never a successful
 // GPU connection.
 //
-// This is instaniated via PeakGpuMemoryTracker::Create.
-class PeakGpuMemoryTrackerImpl : public PeakGpuMemoryTracker {
+// This is instaniated via `PeakGpuMemoryTrackerFactory::Create`.
+class PeakGpuMemoryTrackerImpl : public input::PeakGpuMemoryTracker {
  public:
   // Requests the GPU service to begin peak memory tracking.
-  PeakGpuMemoryTrackerImpl(PeakGpuMemoryTracker::Usage usage);
+  PeakGpuMemoryTrackerImpl(input::PeakGpuMemoryTracker::Usage usage);
   // Requests the GPU service provides the peak memory, the result is presented
   // to UMA Histograms.
   ~PeakGpuMemoryTrackerImpl() override;
@@ -45,7 +45,7 @@
   static uint32_t next_sequence_number_;
 
   bool canceled_ = false;
-  PeakGpuMemoryTracker::Usage usage_;
+  input::PeakGpuMemoryTracker::Usage usage_;
   uint32_t sequence_num_ = next_sequence_number_++;
 };
 
diff --git a/content/browser/gpu/peak_gpu_memory_tracker_impl_browsertest.cc b/content/browser/gpu/peak_gpu_memory_tracker_impl_browsertest.cc
index fe932136..aa78dd79 100644
--- a/content/browser/gpu/peak_gpu_memory_tracker_impl_browsertest.cc
+++ b/content/browser/gpu/peak_gpu_memory_tracker_impl_browsertest.cc
@@ -17,6 +17,7 @@
 #include "content/browser/gpu/gpu_process_host.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/peak_gpu_memory_tracker_factory.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/test_utils.h"
@@ -203,7 +204,7 @@
             std::move(receiver));
   }
 
-  void SetTestingCallback(PeakGpuMemoryTracker* tracker,
+  void SetTestingCallback(input::PeakGpuMemoryTracker* tracker,
                           base::OnceClosure callback) {
     static_cast<PeakGpuMemoryTrackerImpl*>(tracker)
         ->post_gpu_service_callback_for_testing_ = std::move(callback);
@@ -273,8 +274,9 @@
 IN_PROC_BROWSER_TEST_F(PeakGpuMemoryTrackerImplTest, PeakGpuMemoryCallback) {
   base::HistogramTester histogram;
   base::RunLoop run_loop;
-  std::unique_ptr<PeakGpuMemoryTracker> tracker =
-      PeakGpuMemoryTracker::Create(PeakGpuMemoryTracker::Usage::PAGE_LOAD);
+  std::unique_ptr<input::PeakGpuMemoryTracker> tracker =
+      PeakGpuMemoryTrackerFactory::Create(
+          input::PeakGpuMemoryTracker::Usage::PAGE_LOAD);
   SetTestingCallback(tracker.get(), run_loop.QuitClosure());
   FlushRemoteForTesting();
   // No report in response to creation.
diff --git a/content/browser/interest_group/interest_group_browsertest.cc b/content/browser/interest_group/interest_group_browsertest.cc
index d653230..d36c4be 100644
--- a/content/browser/interest_group/interest_group_browsertest.cc
+++ b/content/browser/interest_group/interest_group_browsertest.cc
@@ -24678,22 +24678,22 @@
   ASSERT_TRUE(version_it != map.end() && version_it->second.is_integer());
   EXPECT_EQ(1, version_it->second.GetInteger());
 
-  const auto histogram_it = map.find(cbor::Value("histogram"));
-  ASSERT_TRUE(histogram_it != map.end() &&
-              histogram_it->second.is_bytestring());
-  std::vector<uint8_t> histogram = histogram_it->second.GetBytestring();
-  CHECK_EQ(1024u, histogram.size());
-  EXPECT_TRUE(base::ranges::all_of(
-      histogram, [](uint8_t bit) { return bit == 0 || bit == 1; }));
-
-  const auto platform_histogram_it = map.find(cbor::Value("platformHistogram"));
-  ASSERT_TRUE(platform_histogram_it != map.end() &&
-              platform_histogram_it->second.is_bytestring());
-  std::vector<uint8_t> platform_histogram =
-      platform_histogram_it->second.GetBytestring();
-  CHECK_EQ(4u, platform_histogram.size());
-  EXPECT_TRUE(base::ranges::all_of(
-      platform_histogram, [](uint8_t bit) { return bit == 0 || bit == 1; }));
+  for (const std::string& field : {"histogram", "platformHistogram"}) {
+    const auto histogram_it = map.find(cbor::Value(field));
+    ASSERT_TRUE(histogram_it != map.end() && histogram_it->second.is_map());
+    const auto& histogram_map = histogram_it->second.GetMap();
+    const auto buckets_it = histogram_map.find(cbor::Value("buckets"));
+    ASSERT_TRUE(buckets_it != histogram_map.end() &&
+                buckets_it->second.is_bytestring());
+    std::vector<uint8_t> buckets = buckets_it->second.GetBytestring();
+    size_t expected_buckets_size = field == "histogram" ? 128u : 1u;
+    CHECK_EQ(expected_buckets_size, buckets.size());
+    const auto length_it = histogram_map.find(cbor::Value("length"));
+    ASSERT_TRUE(length_it != histogram_map.end() &&
+                length_it->second.is_integer());
+    int expected_length = field == "histogram" ? 1024 : 4;
+    EXPECT_EQ(expected_length, length_it->second.GetInteger());
+  }
 }
 
 // Opted-in sellers will receive real time histograms, even if they don't call
diff --git a/content/browser/interest_group/interest_group_manager_impl.cc b/content/browser/interest_group/interest_group_manager_impl.cc
index 9261a365..d54926c 100644
--- a/content/browser/interest_group/interest_group_manager_impl.cc
+++ b/content/browser/interest_group/interest_group_manager_impl.cc
@@ -154,9 +154,6 @@
       auction_worklet::RealTimeReportingPlatformError::kNumValues;
   CHECK_EQ(real_time_histogram.size(), num_user_buckets + num_platform_buckets);
 
-  cbor::Value::MapValue report;
-  report.emplace("version", kRealTimeReportDataVersion);
-
   std::vector<uint8_t> histogram_list;
   std::vector<uint8_t> platform_histogram_list;
   for (size_t i = 0; i < real_time_histogram.size(); i++) {
@@ -167,8 +164,20 @@
     }
   }
 
-  report.emplace("histogram", std::move(histogram_list));
-  report.emplace("platformHistogram", std::move(platform_histogram_list));
+  cbor::Value::MapValue histogram_map;
+  histogram_map.emplace("length", static_cast<int64_t>(histogram_list.size()));
+  histogram_map.emplace("buckets", BitPacking(std::move(histogram_list)));
+
+  cbor::Value::MapValue platform_histogram_map;
+  platform_histogram_map.emplace(
+      "length", static_cast<int64_t>(platform_histogram_list.size()));
+  platform_histogram_map.emplace(
+      "buckets", BitPacking(std::move(platform_histogram_list)));
+
+  cbor::Value::MapValue report;
+  report.emplace("version", kRealTimeReportDataVersion);
+  report.emplace("histogram", std::move(histogram_map));
+  report.emplace("platformHistogram", std::move(platform_histogram_map));
   std::optional<std::vector<uint8_t>> report_cbor =
       cbor::Writer::Write(cbor::Value(std::move(report)));
   if (!report_cbor.has_value()) {
diff --git a/content/browser/interest_group/interest_group_real_time_report_util.cc b/content/browser/interest_group/interest_group_real_time_report_util.cc
index 7206839..f432bf2c 100644
--- a/content/browser/interest_group/interest_group_real_time_report_util.cc
+++ b/content/browser/interest_group/interest_group_real_time_report_util.cc
@@ -124,4 +124,22 @@
          std::isfinite(contribution->priority_weight);
 }
 
+std::vector<uint8_t> BitPacking(std::vector<uint8_t> data) {
+  std::vector<uint8_t> packed;
+  packed.reserve((data.size() + 7) / 8);
+  uint8_t current_byte = 0;
+
+  for (size_t i = 0; i < data.size(); i++) {
+    current_byte = (current_byte << 1) | data[i];
+    if ((i + 1) % 8 == 0) {
+      packed.push_back(current_byte);
+      current_byte = 0;
+    } else if (i == data.size() - 1) {
+      current_byte <<= 8 - (i + 1) % 8;
+      packed.push_back(current_byte);
+    }
+  }
+  return packed;
+}
+
 }  // namespace content
diff --git a/content/browser/interest_group/interest_group_real_time_report_util.h b/content/browser/interest_group/interest_group_real_time_report_util.h
index c9f68ef8..6a06a9a4 100644
--- a/content/browser/interest_group/interest_group_real_time_report_util.h
+++ b/content/browser/interest_group/interest_group_real_time_report_util.h
@@ -56,6 +56,14 @@
     const auction_worklet::mojom::RealTimeReportingContributionPtr&
         contribution);
 
+// Bit-pack a vector of 0 and 1s, i.e., use a bit to represent a 0/1, instead of
+// a byte. The first 8 elements of `data` packs to byte 0, the next 8 elements
+// packs to byte 1, until all elements are packed into the output. Within each
+// group of 8 elements, the first element packs to the most significant bit of
+// a byte. For example, the result of packing [0,0,0,0,0,0,0,1, 1]
+// is output[0]: 1, output[1]: 128.
+CONTENT_EXPORT std::vector<uint8_t> BitPacking(std::vector<uint8_t> data);
+
 }  // namespace content
 
 #endif  // CONTENT_BROWSER_INTEREST_GROUP_INTEREST_GROUP_REAL_TIME_REPORT_UTIL_H_
diff --git a/content/browser/interest_group/interest_group_real_time_report_util_unittest.cc b/content/browser/interest_group/interest_group_real_time_report_util_unittest.cc
index b98e956..3450ead 100644
--- a/content/browser/interest_group/interest_group_real_time_report_util_unittest.cc
+++ b/content/browser/interest_group/interest_group_real_time_report_util_unittest.cc
@@ -272,4 +272,25 @@
   }
 }
 
+TEST_F(InterestGroupRealTimeReportUtilTest, BitPacking) {
+  const struct {
+    int id;
+    std::vector<uint8_t> input;
+    std::vector<uint8_t> expected_packed;
+  } kTestCases[] = {
+      {0, {}, {}},
+      {1, {1}, {128}},
+      {1, {1, 0, 0}, {128}},
+      {2, {0, 1, 0, 0}, {64}},
+      {3, {0, 0, 0, 0, 0, 0, 0, 1}, {1}},
+      {4, {0, 0, 0, 0, 0, 0, 0, 1, 1}, {1, 128}},
+      {5, {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0}, {1, 128 + 64}},
+  };
+
+  for (const auto& test_case : kTestCases) {
+    SCOPED_TRACE(test_case.id);
+    EXPECT_EQ(test_case.expected_packed, BitPacking(test_case.input));
+  }
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/DEPS b/content/browser/renderer_host/DEPS
index 8967221..41944bb 100644
--- a/content/browser/renderer_host/DEPS
+++ b/content/browser/renderer_host/DEPS
@@ -42,6 +42,9 @@
     # embedded in mus won't be able to talk to the native ozone.
     "+ui/ozone/public/ozone_switches.h",
   ],
+  "render_widget_host_view_base\.cc": [
+    "+ui/ozone/public/ozone_platform.h",
+  ],
   "render_widget_host_view_mac\.mm": [
     "+components/device_event_log/device_event_log.h",
     "+content/public/browser/web_contents.h",
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index b526933..8297580 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -122,6 +122,7 @@
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/browser/network_service_util.h"
 #include "content/public/browser/origin_trials_controller_delegate.h"
+#include "content/public/browser/peak_gpu_memory_tracker_factory.h"
 #include "content/public/browser/reduce_accept_language_controller_delegate.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/runtime_feature_state/runtime_feature_state_document_data.h"
@@ -132,7 +133,6 @@
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/origin_util.h"
-#include "content/public/common/peak_gpu_memory_tracker.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/common/url_utils.h"
 #include "mojo/public/cpp/system/data_pipe.h"
@@ -1770,8 +1770,8 @@
       common_params_->url, *common_params_->referrer);
 
   if (IsInPrimaryMainFrame()) {
-    loading_mem_tracker_ =
-        PeakGpuMemoryTracker::Create(PeakGpuMemoryTracker::Usage::PAGE_LOAD);
+    loading_mem_tracker_ = PeakGpuMemoryTrackerFactory::Create(
+        input::PeakGpuMemoryTracker::Usage::PAGE_LOAD);
   }
 
   if (frame_tree_node_->IsInFencedFrameTree()) {
@@ -9238,7 +9238,7 @@
   return true;
 }
 
-std::unique_ptr<PeakGpuMemoryTracker>
+std::unique_ptr<input::PeakGpuMemoryTracker>
 NavigationRequest::TakePeakGpuMemoryTracker() {
   return std::move(loading_mem_tracker_);
 }
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h
index b62d49b..70cf71e 100644
--- a/content/browser/renderer_host/navigation_request.h
+++ b/content/browser/renderer_host/navigation_request.h
@@ -755,7 +755,7 @@
   // CreateForCommit().
   bool IsNavigationStarted() const;
 
-  std::unique_ptr<PeakGpuMemoryTracker> TakePeakGpuMemoryTracker();
+  std::unique_ptr<input::PeakGpuMemoryTracker> TakePeakGpuMemoryTracker();
 
   std::unique_ptr<NavigationEarlyHintsManager> TakeEarlyHintsManager();
 
@@ -2470,7 +2470,7 @@
 
   std::unique_ptr<CrossOriginEmbedderPolicyReporter> coep_reporter_;
 
-  std::unique_ptr<PeakGpuMemoryTracker> loading_mem_tracker_;
+  std::unique_ptr<input::PeakGpuMemoryTracker> loading_mem_tracker_;
 
   // Structure tracking the effects of the CrossOriginOpenerPolicy on this
   // navigation.
diff --git a/content/browser/renderer_host/page_impl.cc b/content/browser/renderer_host/page_impl.cc
index 943811e..beebdd1 100644
--- a/content/browser/renderer_host/page_impl.cc
+++ b/content/browser/renderer_host/page_impl.cc
@@ -19,9 +19,9 @@
 #include "content/browser/renderer_host/render_view_host_delegate.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
 #include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/peak_gpu_memory_tracker_factory.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/common/content_client.h"
-#include "content/public/common/peak_gpu_memory_tracker.h"
 #include "services/viz/public/mojom/compositing/offset_tag.mojom.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/loader/loader_constants.h"
diff --git a/content/browser/renderer_host/page_impl.h b/content/browser/renderer_host/page_impl.h
index bdad9d1..895320a9 100644
--- a/content/browser/renderer_host/page_impl.h
+++ b/content/browser/renderer_host/page_impl.h
@@ -32,11 +32,14 @@
 #include "ui/base/ime/mojom/virtual_keyboard_types.mojom.h"
 #include "url/gurl.h"
 
+namespace input {
+class PeakGpuMemoryTracker;
+}  // namespace input
+
 namespace content {
 
 class NavigationRequest;
 class PageDelegate;
-class PeakGpuMemoryTracker;
 class RenderFrameHostImpl;
 
 // This implements the Page interface that is exposed to embedders of content,
@@ -370,7 +373,7 @@
   // Created by NavigationRequest; ownership is maintained until the frame has
   // stopped loading, or we navigate away from the page before it finishes
   // loading.
-  std::unique_ptr<PeakGpuMemoryTracker> loading_memory_tracker_;
+  std::unique_ptr<input::PeakGpuMemoryTracker> loading_memory_tracker_;
 
   // Whether the page is overriding the user agent or not.
   bool is_overriding_user_agent_ = false;
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 5e2ef22..b299d94f 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -203,7 +203,6 @@
 #include "content/public/common/isolated_world_ids.h"
 #include "content/public/common/origin_util.h"
 #include "content/public/common/page_visibility_state.h"
-#include "content/public/common/peak_gpu_memory_tracker.h"
 #include "content/public/common/referrer.h"
 #include "content/public/common/referrer_type_converters.h"
 #include "content/public/common/url_constants.h"
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
index 35336e0..855573c 100644
--- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -5265,8 +5265,9 @@
 // integrated into WebView.
 // This test is a temporary way of verifying that the renderer part
 // works as expected.
+// TODO(crbug.com/347691518): This test is flaky.
 IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
-                       RemoteObjectEnumerateProperties) {
+                       DISABLED_RemoteObjectEnumerateProperties) {
   GURL url(embedded_test_server()->GetURL("/empty.html"));
 
   RemoteObjectInjector injector(web_contents());
@@ -5327,8 +5328,9 @@
   EXPECT_EQ(kInnerObject.id, EvalJs(web_contents(), kScript));
 }
 
+// TODO(crbug.com/340869172): This test is flaky.
 IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
-                       RemoteObjectInvokeMethodException) {
+                       DISABLED_RemoteObjectInvokeMethodException) {
   GURL url(embedded_test_server()->GetURL("/empty.html"));
 
   RemoteObjectInjector injector(web_contents());
@@ -5349,7 +5351,9 @@
 }
 
 // Based on testReturnedObjectIsGarbageCollected.
-IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, RemoteObjectRelease) {
+// TODO(crbug.com/340928363): This test is flaky.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
+                       DISABLED_RemoteObjectRelease) {
   GURL url(embedded_test_server()->GetURL("/empty.html"));
 
   RemoteObjectInjector injector(web_contents());
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 64943808..82fa8af 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -92,6 +92,7 @@
 #include "content/public/browser/keyboard_event_processing_result.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_types.h"
+#include "content/public/browser/peak_gpu_memory_tracker_factory.h"
 #include "content/public/browser/render_frame_metadata_provider.h"
 #include "content/public/browser/render_process_host_priority_client.h"
 #include "content/public/browser/render_widget_host_iterator.h"
@@ -101,7 +102,6 @@
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/drop_data.h"
-#include "content/public/common/peak_gpu_memory_tracker.h"
 #include "content/public/common/result_codes.h"
 #include "gpu/GLES2/gl2extchromium.h"
 #include "gpu/command_buffer/service/gpu_switches.h"
@@ -2525,10 +2525,10 @@
   return delegate()->PreHandleGestureEvent(event);
 }
 
-std::unique_ptr<PeakGpuMemoryTracker>
+std::unique_ptr<input::PeakGpuMemoryTracker>
 RenderWidgetHostImpl::MakePeakGpuMemoryTracker(
-    PeakGpuMemoryTracker::Usage usage) {
-  return PeakGpuMemoryTracker::Create(usage);
+    input::PeakGpuMemoryTracker::Usage usage) {
+  return PeakGpuMemoryTrackerFactory::Create(usage);
 }
 
 void RenderWidgetHostImpl::ShowPopup(const gfx::Rect& initial_screen_rect,
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index d2ce4f02..b9e42fcb 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -378,8 +378,8 @@
       const blink::WebInputEvent& event) override;
   bool PreHandleGestureEvent(const blink::WebGestureEvent& event) override;
   TouchEmulatorImpl* GetTouchEmulator(bool create_if_necessary) override;
-  std::unique_ptr<PeakGpuMemoryTracker> MakePeakGpuMemoryTracker(
-      PeakGpuMemoryTracker::Usage usage) override;
+  std::unique_ptr<input::PeakGpuMemoryTracker> MakePeakGpuMemoryTracker(
+      input::PeakGpuMemoryTracker::Usage usage) override;
   void OnWheelEventAck(const input::MouseWheelEventWithLatencyInfo& event,
                        blink::mojom::InputEventResultSource ack_source,
                        blink::mojom::InputEventResultState ack_result) override;
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc
index d2a2794..adfbdf5 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -48,6 +48,10 @@
 #include "ui/gfx/geometry/size_conversions.h"
 #include "ui/gfx/geometry/size_f.h"
 
+#if BUILDFLAG(IS_OZONE)
+#include "ui/ozone/public/ozone_platform.h"
+#endif
+
 namespace content {
 
 RenderWidgetHostViewBase::RenderWidgetHostViewBase(RenderWidgetHost* host)
@@ -561,6 +565,32 @@
              << " for capture.";
   }
 
+#if BUILDFLAG(IS_OZONE)
+  // There are platforms where no global screen coordinates are available for
+  // client applications, and scaling is done in a per-window basis (rather than
+  // per-display) and controlled by the display server. In such cases, the
+  // ScreenInfo Web API is mostly pointless. To avoid distorted graphics in web
+  // contents, override the display scale with the preferred window scale here.
+  // TODO(crbug.com/336007385): Consolidate screen representation and a less
+  // hacky scale handling in platforms that support per-window scaling.
+  if (ui::OzonePlatform::GetInstance()
+          ->GetPlatformRuntimeProperties()
+          .supports_per_window_scaling) {
+    const float window_scale =
+        display::Screen::GetScreen()
+            ->GetPreferredScaleFactorForView(GetNativeView())
+            .value_or(1.0f);
+    auto& screen = new_screen_infos.mutable_current();
+    const float old = screen.device_scale_factor;
+    if (window_scale != old) {
+      VLOG(1) << __func__ << ": Overriding scale for screen '" << screen.label
+              << "' from " << old << " with windows scale " << window_scale;
+      screen.device_scale_factor = window_scale;
+      force_sync_visual_properties = true;
+    }
+  }
+#endif  // BUILDFLAG(IS_OZONE)
+
   if (screen_infos_ == new_screen_infos && !force_sync_visual_properties)
     return;
 
diff --git a/content/browser/renderer_host/renderer_sandboxed_process_launcher_delegate_unittest.cc b/content/browser/renderer_host/renderer_sandboxed_process_launcher_delegate_unittest.cc
index a533c73..271c175 100644
--- a/content/browser/renderer_host/renderer_sandboxed_process_launcher_delegate_unittest.cc
+++ b/content/browser/renderer_host/renderer_sandboxed_process_launcher_delegate_unittest.cc
@@ -51,8 +51,7 @@
   // PreSpawn
   ::sandbox::ResultCode result =
       ::sandbox::policy::SandboxWin::GeneratePolicyForSandboxedProcess(
-          cmd_line, ::sandbox::policy::switches::kRendererProcess,
-          handles_to_inherit, &test_renderer_delegate, policy.get());
+          cmd_line, handles_to_inherit, &test_renderer_delegate, policy.get());
   ASSERT_EQ(::sandbox::ResultCode::SBOX_ALL_OK, result);
 
   ValidateSecurityLevels(policy->GetConfig());
diff --git a/content/browser/serial/serial_unittest.cc b/content/browser/serial/serial_unittest.cc
index 04d6a22..1eadd88e 100644
--- a/content/browser/serial/serial_unittest.cc
+++ b/content/browser/serial/serial_unittest.cc
@@ -5,7 +5,6 @@
 #include "base/barrier_closure.h"
 #include "base/command_line.h"
 #include "base/memory/raw_ptr.h"
-#include "base/memory/raw_ptr_exclusion.h"
 #include "base/run_loop.h"
 #include "base/test/gmock_callback_support.h"
 #include "base/test/repeating_test_future.h"
@@ -31,6 +30,7 @@
 
 namespace {
 
+using ::base::test::InvokeFuture;
 using ::base::test::TestFuture;
 using ::testing::_;
 using ::testing::Invoke;
@@ -69,6 +69,10 @@
     ON_CALL(delegate(), GetPortManager).WillByDefault(Return(&port_manager_));
     ON_CALL(delegate(), AddObserver)
         .WillByDefault(testing::SaveArg<1>(&observer_));
+    ON_CALL(delegate(), RemoveObserver)
+        .WillByDefault([&](RenderFrameHost*, SerialDelegate::Observer*) {
+          observer_ = nullptr;
+        });
   }
 
   SerialTest(const SerialTest&) = delete;
@@ -97,9 +101,7 @@
   SerialTestContentBrowserClient test_client_;
   raw_ptr<ContentBrowserClient> original_client_ = nullptr;
   device::FakeSerialPortManager port_manager_;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #addr-of
-  RAW_PTR_EXCLUSION SerialDelegate::Observer* observer_ = nullptr;
+  raw_ptr<SerialDelegate::Observer> observer_ = nullptr;
 };
 
 }  // namespace
@@ -385,9 +387,7 @@
   // Connect the port.
   TestFuture<blink::mojom::SerialPortInfoPtr> connect_future;
   EXPECT_CALL(client, OnPortConnectedStateChanged)
-      .WillOnce([&connect_future](blink::mojom::SerialPortInfoPtr port) {
-        connect_future.SetValue(std::move(port));
-      });
+      .WillOnce(InvokeFuture(connect_future));
   port->connected = true;
   observer()->OnPortConnectedStateChanged(*port);
   EXPECT_EQ(connect_future.Get()->token, port->token);
@@ -396,9 +396,7 @@
   // Disconnect the port.
   TestFuture<blink::mojom::SerialPortInfoPtr> disconnect_future;
   EXPECT_CALL(client, OnPortConnectedStateChanged)
-      .WillOnce([&disconnect_future](blink::mojom::SerialPortInfoPtr port) {
-        disconnect_future.SetValue(std::move(port));
-      });
+      .WillOnce(InvokeFuture(disconnect_future));
   port->connected = false;
   observer()->OnPortConnectedStateChanged(*port);
   EXPECT_EQ(disconnect_future.Get()->token, port->token);
diff --git a/content/browser/webid/webid_browsertest.cc b/content/browser/webid/webid_browsertest.cc
index 98635644..b904430 100644
--- a/content/browser/webid/webid_browsertest.cc
+++ b/content/browser/webid/webid_browsertest.cc
@@ -437,6 +437,8 @@
     features.push_back(net::features::kSplitCacheByNetworkIsolationKey);
     features.push_back(features::kFedCm);
     features.push_back(features::kFedCmIdPRegistration);
+    // Multi IdP is needed to request registered providers.
+    features.push_back(features::kFedCmMultipleIdentityProviders);
     scoped_feature_list_.InitWithFeatures(features, {});
 
     command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
diff --git a/content/common/input/render_input_router.cc b/content/common/input/render_input_router.cc
index 713e151..481ec63 100644
--- a/content/common/input/render_input_router.cc
+++ b/content/common/input/render_input_router.cc
@@ -298,7 +298,7 @@
 
   if (gesture_event.GetType() == WebInputEvent::Type::kGestureScrollBegin) {
     scroll_peak_gpu_mem_tracker_ = delegate_->MakePeakGpuMemoryTracker(
-        PeakGpuMemoryTracker::Usage::SCROLL);
+        input::PeakGpuMemoryTracker::Usage::SCROLL);
   } else if (gesture_event.GetType() ==
              WebInputEvent::Type::kGestureScrollEnd) {
     if (scroll_peak_gpu_mem_tracker_ && !is_currently_scrolling_viewport()) {
diff --git a/content/common/input/render_input_router.h b/content/common/input/render_input_router.h
index 208b91d..d73d246 100644
--- a/content/common/input/render_input_router.h
+++ b/content/common/input/render_input_router.h
@@ -14,6 +14,7 @@
 #include "components/input/fling_scheduler_base.h"
 #include "components/input/input_disposition_handler.h"
 #include "components/input/input_router_impl.h"
+#include "components/input/peak_gpu_memory_tracker.h"
 #include "content/common/content_export.h"
 #include "content/common/input/input_injector.mojom-shared.h"
 #include "content/common/input/render_input_router_delegate.h"
@@ -29,10 +30,13 @@
 #include "third_party/blink/public/mojom/page/widget.mojom.h"
 #include "third_party/blink/public/mojom/widget/platform_widget.mojom.h"
 
+namespace input {
+class PeakGpuMemoryTracker;
+}  // namespace input
+
 namespace content {
 
 class MockRenderInputRouter;
-class PeakGpuMemoryTracker;
 
 // RenderInputRouter is currently owned by RenderWidgetHostImpl and is being
 // used for forwarding input events. It maintains mojo connections
@@ -208,7 +212,7 @@
   bool is_in_touchpad_gesture_fling_ = false;
   std::unique_ptr<RenderInputRouterLatencyTracker> latency_tracker_;
 
-  std::unique_ptr<PeakGpuMemoryTracker> scroll_peak_gpu_mem_tracker_;
+  std::unique_ptr<input::PeakGpuMemoryTracker> scroll_peak_gpu_mem_tracker_;
 
   raw_ptr<input::InputRouterImplClient> input_router_impl_client_;
   raw_ptr<RenderInputRouterDelegate> delegate_;
diff --git a/content/common/input/render_input_router_delegate.h b/content/common/input/render_input_router_delegate.h
index 142d4b7..6a206c8 100644
--- a/content/common/input/render_input_router_delegate.h
+++ b/content/common/input/render_input_router_delegate.h
@@ -8,7 +8,7 @@
 #include <memory>
 
 #include "cc/trees/render_frame_metadata.h"
-#include "content/public/common/peak_gpu_memory_tracker.h"
+#include "components/input/peak_gpu_memory_tracker.h"
 #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h"
 #include "ui/gfx/delegated_ink_point.h"
 
@@ -63,8 +63,8 @@
   // creation of a TouchEmulator.
   virtual TouchEmulator* GetTouchEmulator(bool create_if_necessary) = 0;
 
-  virtual std::unique_ptr<PeakGpuMemoryTracker> MakePeakGpuMemoryTracker(
-      PeakGpuMemoryTracker::Usage usage) = 0;
+  virtual std::unique_ptr<input::PeakGpuMemoryTracker> MakePeakGpuMemoryTracker(
+      input::PeakGpuMemoryTracker::Usage usage) = 0;
 
   // Called upon event ack receipt from the renderer.
   virtual void OnWheelEventAck(
diff --git a/content/common/peak_gpu_memory_callback.cc b/content/common/peak_gpu_memory_callback.cc
index e88d17b0..7c26bc389 100644
--- a/content/common/peak_gpu_memory_callback.cc
+++ b/content/common/peak_gpu_memory_callback.cc
@@ -24,7 +24,7 @@
 // These count values should be recalculated in case of changes to the number
 // of values in their respective enums.
 constexpr int kUsageTypeCount =
-    static_cast<int>(PeakGpuMemoryTracker::Usage::USAGE_MAX) + 1;
+    static_cast<int>(input::PeakGpuMemoryTracker::Usage::USAGE_MAX) + 1;
 constexpr int kAllocationSourceTypeCount =
     static_cast<int>(gpu::GpuPeakMemoryAllocationSource::
                          GPU_PEAK_MEMORY_ALLOCATION_SOURCE_MAX) +
@@ -39,13 +39,13 @@
 constexpr int kMemoryHistogramMax = 64000;
 constexpr int kMemoryHistogramBucketCount = 100;
 
-constexpr const char* GetUsageName(PeakGpuMemoryTracker::Usage usage) {
+constexpr const char* GetUsageName(input::PeakGpuMemoryTracker::Usage usage) {
   switch (usage) {
-    case PeakGpuMemoryTracker::Usage::CHANGE_TAB:
+    case input::PeakGpuMemoryTracker::Usage::CHANGE_TAB:
       return "ChangeTab2";
-    case PeakGpuMemoryTracker::Usage::PAGE_LOAD:
+    case input::PeakGpuMemoryTracker::Usage::PAGE_LOAD:
       return "PageLoad";
-    case PeakGpuMemoryTracker::Usage::SCROLL:
+    case input::PeakGpuMemoryTracker::Usage::SCROLL:
       return "Scroll";
   }
 }
@@ -66,12 +66,13 @@
   }
 }
 
-std::string GetPeakMemoryUsageUMAName(PeakGpuMemoryTracker::Usage usage) {
+std::string GetPeakMemoryUsageUMAName(
+    input::PeakGpuMemoryTracker::Usage usage) {
   return base::StrCat({"Memory.GPU.PeakMemoryUsage2.", GetUsageName(usage)});
 }
 
 std::string GetPeakMemoryAllocationSourceUMAName(
-    PeakGpuMemoryTracker::Usage usage,
+    input::PeakGpuMemoryTracker::Usage usage,
     gpu::GpuPeakMemoryAllocationSource source) {
   return base::StrCat({"Memory.GPU.PeakMemoryAllocationSource2.",
                        GetUsageName(usage), ".",
@@ -85,7 +86,7 @@
 // requested |usage|. Some tests may provide an optional |testing_callback| in
 // order to sync tests with the work done here on the UI thread.
 void PeakGpuMemoryCallback(
-    PeakGpuMemoryTracker::Usage usage,
+    input::PeakGpuMemoryTracker::Usage usage,
     base::OnceClosure testing_callback,
     const uint64_t peak_memory,
     const base::flat_map<gpu::GpuPeakMemoryAllocationSource, uint64_t>&
diff --git a/content/common/peak_gpu_memory_callback.h b/content/common/peak_gpu_memory_callback.h
index 6cdcaa1..5748f0a4 100644
--- a/content/common/peak_gpu_memory_callback.h
+++ b/content/common/peak_gpu_memory_callback.h
@@ -7,7 +7,7 @@
 
 #include "base/containers/flat_map.h"
 #include "base/functional/callback_forward.h"
-#include "content/public/common/peak_gpu_memory_tracker.h"
+#include "components/input/peak_gpu_memory_tracker.h"
 #include "gpu/ipc/common/gpu_peak_memory.h"
 
 namespace content {
@@ -26,7 +26,7 @@
 // - |allocation_per_source|: A breakdown of the peak memory usage, showing how
 //                            much was allocated by each source.
 void PeakGpuMemoryCallback(
-    PeakGpuMemoryTracker::Usage usage,
+    input::PeakGpuMemoryTracker::Usage usage,
     base::OnceClosure testing_callback,
     const uint64_t peak_memory,
     const base::flat_map<gpu::GpuPeakMemoryAllocationSource, uint64_t>&
diff --git a/content/common/sandbox_init_win.cc b/content/common/sandbox_init_win.cc
index 498f602..b96d6a87 100644
--- a/content/common/sandbox_init_win.cc
+++ b/content/common/sandbox_init_win.cc
@@ -45,7 +45,7 @@
   }
 
   return sandbox::policy::SandboxWin::StartSandboxedProcess(
-      full_command_line, type_str, handles_to_inherit, delegate, process);
+      full_command_line, handles_to_inherit, delegate, process);
 }
 
 }  // namespace content
diff --git a/content/common/service_worker/race_network_request_write_buffer_manager.cc b/content/common/service_worker/race_network_request_write_buffer_manager.cc
index 75fc1b4..3545a40 100644
--- a/content/common/service_worker/race_network_request_write_buffer_manager.cc
+++ b/content/common/service_worker/race_network_request_write_buffer_manager.cc
@@ -87,8 +87,12 @@
 }
 
 MojoResult RaceNetworkRequestWriteBufferManager::BeginWriteData() {
-  return producer_->BeginWriteData(mojo::DataPipeProducerHandle::kNoSizeHint,
-                                   MOJO_WRITE_DATA_FLAG_NONE, buffer_);
+  base::span<uint8_t> buffer = buffer_;
+  auto result =
+      producer_->BeginWriteData(mojo::DataPipeProducerHandle::kNoSizeHint,
+                                MOJO_WRITE_DATA_FLAG_NONE, buffer);
+  buffer_ = buffer;
+  return result;
 }
 
 MojoResult RaceNetworkRequestWriteBufferManager::EndWriteData(
diff --git a/content/common/service_worker/race_network_request_write_buffer_manager.h b/content/common/service_worker/race_network_request_write_buffer_manager.h
index b39fc67..0b3c63c 100644
--- a/content/common/service_worker/race_network_request_write_buffer_manager.h
+++ b/content/common/service_worker/race_network_request_write_buffer_manager.h
@@ -8,6 +8,7 @@
 #include <optional>
 
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "content/common/content_export.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "mojo/public/cpp/system/simple_watcher.h"
@@ -53,7 +54,7 @@
   bool is_data_pipe_created_;
   mojo::ScopedDataPipeProducerHandle producer_;
   mojo::ScopedDataPipeConsumerHandle consumer_;
-  base::span<uint8_t> buffer_;
+  base::raw_span<uint8_t> buffer_;
   mojo::SimpleWatcher watcher_;
   size_t num_bytes_written_ = 0;
 };
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index d42e49c..e7516fb7 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -303,6 +303,7 @@
     "page_user_data.h",
     "payment_app_provider.h",
     "payment_app_provider_util.h",
+    "peak_gpu_memory_tracker_factory.h",
     "peer_connection_tracker_host_observer.cc",
     "peer_connection_tracker_host_observer.h",
     "per_web_ui_browser_interface_broker.h",
diff --git a/content/public/browser/peak_gpu_memory_tracker_factory.h b/content/public/browser/peak_gpu_memory_tracker_factory.h
new file mode 100644
index 0000000..f667201
--- /dev/null
+++ b/content/public/browser/peak_gpu_memory_tracker_factory.h
@@ -0,0 +1,34 @@
+/// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_PEAK_GPU_MEMORY_TRACKER_FACTORY_H_
+#define CONTENT_PUBLIC_BROWSER_PEAK_GPU_MEMORY_TRACKER_FACTORY_H_
+
+#include <memory>
+
+#include "components/input/peak_gpu_memory_tracker.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class CONTENT_EXPORT PeakGpuMemoryTrackerFactory {
+ public:
+  PeakGpuMemoryTrackerFactory(const PeakGpuMemoryTrackerFactory&) = delete;
+  PeakGpuMemoryTrackerFactory& operator=(const PeakGpuMemoryTrackerFactory&) =
+      delete;
+
+  PeakGpuMemoryTrackerFactory() = delete;
+  ~PeakGpuMemoryTrackerFactory() = delete;
+
+  // Creates the PeakGpuMemoryTracker, which performs the registration with the
+  // GPU service. Destroy the PeakGpuMemoryTracker to request a report from the
+  // GPU service. The report will be recorded in UMA Histograms for the given
+  // |usage| type.
+  static std::unique_ptr<input::PeakGpuMemoryTracker> Create(
+      input::PeakGpuMemoryTracker::Usage usage);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_PUBLIC_BROWSER_PEAK_GPU_MEMORY_TRACKER_FACTORY_H_
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn
index ece2494..45c489e8 100644
--- a/content/public/common/BUILD.gn
+++ b/content/public/common/BUILD.gn
@@ -184,7 +184,6 @@
     "page_type.h",
     "page_visibility_state.h",
     "page_zoom.h",
-    "peak_gpu_memory_tracker.h",
     "persistent_notification_status.h",
     "process_type.h",
     "profiling.cc",
diff --git a/content/public/common/peak_gpu_memory_tracker.h b/content/public/common/peak_gpu_memory_tracker.h
deleted file mode 100644
index fec1348..0000000
--- a/content/public/common/peak_gpu_memory_tracker.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2019 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_COMMON_PEAK_GPU_MEMORY_TRACKER_H_
-#define CONTENT_PUBLIC_COMMON_PEAK_GPU_MEMORY_TRACKER_H_
-
-#include <memory>
-
-#include "content/common/content_export.h"
-
-namespace content {
-
-// Tracks the peak memory of the GPU service for its lifetime. Upon its
-// destruction a report will be requested from the GPU service. The peak will be
-// reported to UMA Histograms.
-//
-// If the GPU is lost during this objects lifetime, there will be no
-// corresponding report of usage. The same for if there is never a successful
-// GPU connection.
-//
-// See PeakGpuMemoryTracker::Create.
-class CONTENT_EXPORT PeakGpuMemoryTracker {
- public:
-  // The type of user interaction, for which the GPU Peak Memory Usage is being
-  // observed.
-  enum class Usage {
-    CHANGE_TAB,
-    PAGE_LOAD,
-    SCROLL,
-    USAGE_MAX = SCROLL,
-  };
-
-  // Creates the PeakGpuMemoryTracker, which performs the registration with the
-  // GPU service. Destroy the PeakGpuMemoryTracker to request a report from the
-  // GPU service. The report will be recorded in UMA Histograms for the given
-  // |usage| type.
-  static std::unique_ptr<PeakGpuMemoryTracker> Create(Usage usage);
-
-  virtual ~PeakGpuMemoryTracker() = default;
-
-  PeakGpuMemoryTracker(const PeakGpuMemoryTracker*) = delete;
-  PeakGpuMemoryTracker& operator=(const PeakGpuMemoryTracker&) = delete;
-
-  // Invalidates this tracker, no UMA Histogram report is generated.
-  virtual void Cancel() = 0;
-
- protected:
-  PeakGpuMemoryTracker() = default;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_PUBLIC_COMMON_PEAK_GPU_MEMORY_TRACKER_H_
diff --git a/content/shell/android/javatests/AndroidManifest.xml b/content/shell/android/javatests/AndroidManifest.xml
index d69828f6..7531f50 100644
--- a/content/shell/android/javatests/AndroidManifest.xml
+++ b/content/shell/android/javatests/AndroidManifest.xml
@@ -7,7 +7,6 @@
 {% block application_label %}Content Shell Test{% endblock %}
 
 {% block extra_uses_permissions %}
-    <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />
 {% endblock %}
 
diff --git a/content/test/content_test_bundle_data.filelist b/content/test/content_test_bundle_data.filelist
index 5160e0b..55fb5d59 100644
--- a/content/test/content_test_bundle_data.filelist
+++ b/content/test/content_test_bundle_data.filelist
@@ -7034,6 +7034,7 @@
 data/media/too_many_web_media_players_intervention_test.html
 data/media/tulip2.webm
 data/media/video-player-autoplay.html
+data/media/video-player-autoplay.html.mock-http-headers
 data/media/video-player.html
 data/media/video_audio_element_capture_test.html
 data/media/video_capture_test.html
diff --git a/content/test/data/media/video-player-autoplay.html.mock-http-headers b/content/test/data/media/video-player-autoplay.html.mock-http-headers
new file mode 100644
index 0000000..263e89c4
--- /dev/null
+++ b/content/test/data/media/video-player-autoplay.html.mock-http-headers
@@ -0,0 +1,2 @@
+HTTP/1.1 200 OK
+Supports-Loading-Mode: fenced-frame
\ No newline at end of file
diff --git a/crypto/aead.h b/crypto/aead.h
index faa89084..6a4bb24 100644
--- a/crypto/aead.h
+++ b/crypto/aead.h
@@ -15,6 +15,7 @@
 
 #include "base/containers/span.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_span.h"
 #include "crypto/crypto_export.h"
 
 struct evp_aead_st;
@@ -81,7 +82,7 @@
                              base::span<const uint8_t> additional_data,
                              base::span<uint8_t> out) const;
 
-  std::optional<base::span<const uint8_t>> key_;
+  std::optional<base::raw_span<const uint8_t, DanglingUntriaged>> key_;
   raw_ptr<const evp_aead_st> aead_;
 };
 
diff --git a/device/BUILD.gn b/device/BUILD.gn
index f6055d2..96f48b5 100644
--- a/device/BUILD.gn
+++ b/device/BUILD.gn
@@ -123,6 +123,7 @@
     "//components/apdu",
     "//components/cbor",
     "//components/device_event_log",
+    "//components/prefs:test_support",
     "//crypto:test_support",
     "//device/base",
     "//device/base/synchronization",
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn
index 05cce11f..cfb175b6 100644
--- a/device/bluetooth/BUILD.gn
+++ b/device/bluetooth/BUILD.gn
@@ -173,6 +173,7 @@
     "//base",
     "//build:chromeos_buildflags",
     "//components/device_event_log",
+    "//components/prefs",
     "//crypto",
     "//device/base",
     "//device/bluetooth/strings",
diff --git a/device/bluetooth/DEPS b/device/bluetooth/DEPS
index 906bc06a..9e4ce940 100644
--- a/device/bluetooth/DEPS
+++ b/device/bluetooth/DEPS
@@ -2,6 +2,7 @@
   "+chromecast/device/bluetooth",
   "+chromecast/public/bluetooth",
   "+chromeos/dbus",
+  "+components/prefs",
   "+crypto",
   "+dbus",
   "+device/bluetooth/jni_headers",
diff --git a/device/bluetooth/chromeos/bluetooth_utils.cc b/device/bluetooth/chromeos/bluetooth_utils.cc
index 2a1492c1..0acefa9 100644
--- a/device/bluetooth/chromeos/bluetooth_utils.cc
+++ b/device/bluetooth/chromeos/bluetooth_utils.cc
@@ -24,6 +24,7 @@
 #include <string_view>
 
 #include "ash/constants/ash_features.h"
+#include "ash/constants/ash_pref_names.h"
 #include "ash/constants/ash_switches.h"
 #include "chromeos/ash/services/nearby/public/cpp/nearby_client_uuids.h"
 #include "chromeos/ash/services/secure_channel/public/cpp/shared/ble_constants.h"
@@ -45,6 +46,10 @@
 
 constexpr base::TimeDelta kMaxDeviceSelectionDuration = base::Seconds(30);
 constexpr base::TimeDelta kConnectionTimeIntervalThreshold = base::Minutes(15);
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+constexpr base::TimeDelta kToastShownCountTimeIntervalThreshold =
+    base::Hours(24);
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 constexpr uint8_t kLimitedDiscoveryFlag = 0x01;
 constexpr uint8_t kGeneralDiscoveryFlag = 0x02;
@@ -595,4 +600,38 @@
       /*max=*/kConnectionTimeIntervalThreshold, 100);
 }
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+void MaybeRecordConnectionToastShownCount(PrefService* local_state_pref,
+                                          bool triggered_by_connect) {
+  bool is_within_24_hrs =
+      base::Time::Now() -
+          local_state_pref->GetTime(ash::prefs::kBluetoothToastCountStartTime) <
+      kToastShownCountTimeIntervalThreshold;
+  int toast_shown_count = local_state_pref->GetInteger(
+      ash::prefs::kBluetoothConnectionToastShownCount);
+
+  if (is_within_24_hrs && triggered_by_connect) {
+    // Increment the count if within 24 hours and it is triggered by connect.
+    local_state_pref->SetInteger(
+        ash::prefs::kBluetoothConnectionToastShownCount, toast_shown_count + 1);
+    return;
+  }
+
+  if (is_within_24_hrs) {
+    // Do nothing since we haven't exceeded the time interval.
+    return;
+  }
+
+  // Emit metric and reset count and timestamp if 24 hours have passed.
+  base::UmaHistogramCounts100(
+      "Bluetooth.ChromeOS.ConnectionToastShownIn24Hours.Count",
+      toast_shown_count);
+  // Reset the count, and update the start time.
+  local_state_pref->SetInteger(ash::prefs::kBluetoothConnectionToastShownCount,
+                               triggered_by_connect ? 1 : 0);
+  local_state_pref->SetTime(ash::prefs::kBluetoothToastCountStartTime,
+                            base::Time::Now().LocalMidnight());
+}
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
 }  // namespace device
diff --git a/device/bluetooth/chromeos/bluetooth_utils.h b/device/bluetooth/chromeos/bluetooth_utils.h
index 7d698da7..dc9597da 100644
--- a/device/bluetooth/chromeos/bluetooth_utils.h
+++ b/device/bluetooth/chromeos/bluetooth_utils.h
@@ -7,6 +7,7 @@
 
 #include <optional>
 
+#include "components/prefs/pref_service.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_device.h"
 #include "device/bluetooth/bluetooth_export.h"
@@ -197,6 +198,14 @@
 DEVICE_BLUETOOTH_EXPORT void RecordTimeIntervalBetweenConnections(
     base::TimeDelta time_interval_since_last_connection);
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+// Record the number of times the connection toast is shown to user in the
+// last 24 hours.
+DEVICE_BLUETOOTH_EXPORT void MaybeRecordConnectionToastShownCount(
+    PrefService* local_state_pref,
+    bool triggered_by_connect);
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
 }  // namespace device
 
 #endif  // DEVICE_BLUETOOTH_CHROMEOS_BLUETOOTH_UTILS_H_
diff --git a/device/bluetooth/chromeos/bluetooth_utils_unittest.cc b/device/bluetooth/chromeos/bluetooth_utils_unittest.cc
index e4f976b..a4612dd 100644
--- a/device/bluetooth/chromeos/bluetooth_utils_unittest.cc
+++ b/device/bluetooth/chromeos/bluetooth_utils_unittest.cc
@@ -4,12 +4,15 @@
 
 #include "device/bluetooth/chromeos/bluetooth_utils.h"
 
+#include "ash/constants/ash_pref_names.h"
 #include "base/command_line.h"
 #include "base/functional/callback_helpers.h"
 #include "base/run_loop.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
 #include "build/chromeos_buildflags.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/testing_pref_service.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 #include "device/bluetooth/bluetooth_device.h"
 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
@@ -48,6 +51,8 @@
 // indicates the device vendor. In this case, "64:16:7F:**:**:**" represents a
 // device manufactured by Poly.
 constexpr char kFakePolyDeviceAddress[] = "64:16:7F:12:34:56";
+constexpr char kConnectionToastShownLast24HoursCountHistogramName[] =
+    "Bluetooth.ChromeOS.ConnectionToastShownIn24Hours.Count";
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 const size_t kMaxDevicesForFilter = 5;
@@ -516,4 +521,83 @@
       kTimeIntervalBetweenConnectionsHistogramName, base::Minutes(1), 1);
 }
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+TEST_F(BluetoothUtilsTest, TestConnectionToastShownCount24HoursMetric) {
+  // Verify no initial histogram entries.
+  histogram_tester.ExpectTotalCount(
+      kConnectionToastShownLast24HoursCountHistogramName, 0);
+
+  // Initialize pref.
+  std::unique_ptr<TestingPrefServiceSimple> local_state =
+      std::make_unique<TestingPrefServiceSimple>();
+  local_state->registry()->RegisterIntegerPref(
+      ash::prefs::kBluetoothConnectionToastShownCount, 0);
+  local_state->registry()->RegisterTimePref(
+      ash::prefs::kBluetoothToastCountStartTime,
+      base::Time::Now().LocalMidnight());
+
+  // Simulate 1 minute passing and connect the Bluetooth device.
+  local_state->SetTime(ash::prefs::kBluetoothToastCountStartTime,
+                       base::Time::Now().LocalMidnight() - base::Minutes(1));
+  MaybeRecordConnectionToastShownCount(local_state.get(),
+                                       /*triggered_by_connect=*/true);
+
+  // Verify the toast count increments to 1, and no metric is recorded since
+  // it is within 24 hours.
+  EXPECT_EQ(1, local_state->GetInteger(
+                   ash::prefs::kBluetoothConnectionToastShownCount));
+  histogram_tester.ExpectTotalCount(
+      kConnectionToastShownLast24HoursCountHistogramName, 0);
+
+  // Simulate 15 minutes passing and connect again.
+  local_state->SetTime(ash::prefs::kBluetoothToastCountStartTime,
+                       base::Time::Now().LocalMidnight() - base::Minutes(15));
+  MaybeRecordConnectionToastShownCount(local_state.get(),
+                                       /*triggered_by_connect=*/true);
+
+  // Verify the toast count increments to 2, but still no metrics recorded.
+  EXPECT_EQ(2, local_state->GetInteger(
+                   ash::prefs::kBluetoothConnectionToastShownCount));
+  histogram_tester.ExpectTotalCount(
+      kConnectionToastShownLast24HoursCountHistogramName, 0);
+
+  // Simulate 30 hours passing and connect.
+  local_state->SetTime(ash::prefs::kBluetoothToastCountStartTime,
+                       base::Time::Now().LocalMidnight() - base::Hours(30));
+  MaybeRecordConnectionToastShownCount(local_state.get(),
+                                       /*triggered_by_connect=*/true);
+
+  // Verify the metric is emitted after the 24-hour threshold is crossed.
+  histogram_tester.ExpectTotalCount(
+      kConnectionToastShownLast24HoursCountHistogramName, 1);
+  histogram_tester.ExpectBucketCount(
+      kConnectionToastShownLast24HoursCountHistogramName, /*sample=*/2,
+      /*expected_count=*/1);
+
+  // Verify the toast count and start time are reset after emitting the metric.
+  EXPECT_EQ(1, local_state->GetInteger(
+                   ash::prefs::kBluetoothConnectionToastShownCount));
+  EXPECT_EQ(base::Time::Now().LocalMidnight(),
+            local_state->GetTime(ash::prefs::kBluetoothToastCountStartTime));
+
+  // Simulate passing more than 24 hours, but this time, triggered by device
+  // start.
+  local_state->SetTime(ash::prefs::kBluetoothToastCountStartTime,
+                       base::Time::Now().LocalMidnight() - base::Hours(30));
+  MaybeRecordConnectionToastShownCount(local_state.get(),
+                                       /*triggered_by_connect=*/false);
+
+  // Verify the metric is emitted.
+  histogram_tester.ExpectTotalCount(
+      kConnectionToastShownLast24HoursCountHistogramName, 2);
+  histogram_tester.ExpectBucketCount(
+      kConnectionToastShownLast24HoursCountHistogramName, /*sample=*/1,
+      /*expected_count=*/1);
+
+  // Verify the count is reset to 0, instead of 1 this time.
+  EXPECT_EQ(0, local_state->GetInteger(
+                   ash::prefs::kBluetoothConnectionToastShownCount));
+}
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
 }  // namespace device
diff --git a/device/fido/cable/fido_ble_frames.h b/device/fido/cable/fido_ble_frames.h
index 2474dcc1..dc44c77 100644
--- a/device/fido/cable/fido_ble_frames.h
+++ b/device/fido/cable/fido_ble_frames.h
@@ -13,6 +13,7 @@
 #include "base/component_export.h"
 #include "base/containers/queue.h"
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "device/fido/fido_constants.h"
 
 namespace device {
@@ -115,7 +116,7 @@
   virtual ~FidoBleFrameFragment();
 
  private:
-  base::span<const uint8_t> fragment_;
+  base::raw_span<const uint8_t> fragment_;
 };
 
 // An initialization fragment of a frame.
diff --git a/device/fido/cbor_extract.cc b/device/fido/cbor_extract.cc
index ada966e..852a4dd 100644
--- a/device/fido/cbor_extract.cc
+++ b/device/fido/cbor_extract.cc
@@ -8,6 +8,7 @@
 
 #include "base/check_op.h"
 #include "base/functional/callback.h"
+#include "base/memory/raw_span.h"
 #include "components/cbor/values.h"
 
 namespace device {
@@ -182,8 +183,8 @@
     return cbor::Value(std::move(key));
   }
 
-  base::span<const void*> outputs_;
-  base::span<const StepOrByte<void>> steps_;
+  base::raw_span<const void*> outputs_;
+  base::raw_span<const StepOrByte<void>> steps_;
   size_t step_i_ = 0;
 };
 
diff --git a/docs/graphics/scrolling/scroll_jank_metric.md b/docs/graphics/scrolling/scroll_jank_metric.md
new file mode 100644
index 0000000..c64abd3f
--- /dev/null
+++ b/docs/graphics/scrolling/scroll_jank_metric.md
@@ -0,0 +1,32 @@
+# Android Scroll Jank Metric.
+
+Chromium uses a scroll jank metric on Android that tracks the percentage of dropped frames in a given window of 64 frames, and uses this metric to benchmark the end user's scrolling experience.
+
+## How it works
+
+Chromium assumes that if scrolling input events arrive in sequence during a scroll, then frames should be produced in sequence, without any drops or delays.
+
+![Chromium Dropped Frame](chromium_dropped_frame.png)
+
+# How is it decided that scrolling events arrived in sequence
+
+If the time difference between two consecutive scrolling input events (i.e., the time between two consecutive screen touches during a scroll gesture) is less than the device's refresh rate interval (vsync interval), then it is expected that these two input events will generate two distinct frames, unless those inputs are coalesced for arriving too close within a single Vsync interval (input sampling rate higher than refresh rate).
+
+```
+scrolling_input_event_timestamp[i] - scrolling_input_event_timestamp[i - 1] < vsync_interval
+```
+
+Scrolling Input Events: These are moments when the user interacts with the touchscreen to initiate or continue a scrolling action.
+
+Timestamp: Each scrolling input event is recorded with a timestamp indicating the exact time it occurred.
+
+Vsync Interval: This is the time it takes for the device's screen to refresh its content. It's directly related to the screen's refresh rate (e.g., a 60Hz refresh rate has a vsync interval of approximately 16.67 milliseconds).
+
+# Where to find the metric
+
+The metric is emitted using UMA and there are multiple variants of it explained below:
+* ```Event.ScrollJank.DelayedFramesPercentage.FixedWindow``` for the percentage of delayed/dropped frames every 64 frame window.
+* ```Event.ScrollJank.MissedVsyncsSum.FixedWindow``` for the sum of missed vsyncs (presentation opportunities) every 64 frame window.
+* ```Event.ScrollJank.MissedVsyncsMax.FixedWindow``` for the maxiumum continuous interval of frame drops in a 64 frame window
+
+for more information, please check https://doc/1Y0u0Tq5eUZff75nYUzQVw6JxmbZAW9m64pJidmnGWsY
\ No newline at end of file
diff --git a/docs/images/chromium_dropped_frame.png b/docs/images/chromium_dropped_frame.png
new file mode 100644
index 0000000..354ff42
--- /dev/null
+++ b/docs/images/chromium_dropped_frame.png
Binary files differ
diff --git a/docs/ios/multiwindow_eg_tests.md b/docs/ios/multiwindow_eg_tests.md
index aab146a0..692f835 100644
--- a/docs/ios/multiwindow_eg_tests.md
+++ b/docs/ios/multiwindow_eg_tests.md
@@ -17,7 +17,7 @@
 unlikely case it is needed.  Depending on the needs of the test, you can decide
 on how to proceed, for example wanting to keep the left window as 0 and the
 right window as 1.  See
-[`[BrowserViewControllerTestCase testMultiWindowURLLoading]`](https://source.chromium.org/chromium/chromium/src/+/main:ios/chrome/browser/ui/browser_view/browser_view_controller_egtest.mm;l=209)
+[`[BrowserViewControllerTestCase testMultiWindowURLLoading]`](https://source.chromium.org/chromium/chromium/src/+/main:ios/chrome/browser/browser_view/ui_bundled/browser_view_controller_egtest.mm;l=209)
 as an example of this.
 
 ## Helpers
diff --git a/docs/security/shepherd.md b/docs/security/shepherd.md
index 4a9821a..b2ad95c 100644
--- a/docs/security/shepherd.md
+++ b/docs/security/shepherd.md
@@ -302,18 +302,31 @@
 OS, please [ask for help](#Ask-for-help), there is likely someone on the team
 that does and can help you.
 
-ChromeOS is in a separate issue tracker. VRP reports for ChromeOS should be
+ChromeOS is in the Google issue tracker. VRP reports for ChromeOS should be
 [directly reported to ChromeOS](https://bughunters.google.com/report). Please
-request the reporter submit direct to ChromeOS via that reporting route to
-ensure it is received by the appropriate team.
+request the reporter submit reports directly to ChromeOS in the future. For
+VRP and other human-submitted security bug reports specific to ChromeOS,
+please move the report corresponding component (componentid:1335705) in the
+Google issue tracker. Since this bug is being moved between trackers you will
+need to use your google.com account to move the bug into that tracker component.
+
+Some machine-discovered (Clusterfuzz, Crash AutoBugFiler, GWP-ASAN) may be
+specific to ChromeOS. If this is determined to be the case after investigation
+(please remember some GWP-ASAN or crash bug auto-filer bugs may have come from a
+ChromeOS crash, but the issue may not be specific to ChromeOS), move the bug
+to the appropriate ChromeOS component (componentid:1214738) in the Google
+issue tracker for these reports. Again, you will need to use your google.com
+account to move this bug into that component.
 
 ### Assign
 
 Security bugs are not automatically visible, so you must add people to get them
 fixed. For each bug, set:
 
-* The **Component Tags** – due to a limited set of auto-cc rules, this may add
-  some visibility.
+* The **Component** – due to a limited set of auto-cc rules, this may add
+  some visibility. This will "move" the bug into that component; this is the
+  expected outcome. It can also be helpful to set additional **Component Tags**
+  when a bug does not fall neatly into a single component.
 * An **assignee/owner**. Use `git blame` or look for similar past bugs in the
   tracker.
 * Lots of **cc**s. Copy everyone who could possibly be relevant. Use the owners
diff --git a/docs/website b/docs/website
index a685042..5bcb961 160000
--- a/docs/website
+++ b/docs/website
@@ -1 +1 @@
-Subproject commit a685042c1ed1a9772e7f824b314be89fdb8650b9
+Subproject commit 5bcb9612ba762a369ee54c1dab51fb6025c92652
diff --git a/extensions/browser/api/declarative_net_request/indexed_rule.cc b/extensions/browser/api/declarative_net_request/indexed_rule.cc
index 3c7d3836..de798fe9 100644
--- a/extensions/browser/api/declarative_net_request/indexed_rule.cc
+++ b/extensions/browser/api/declarative_net_request/indexed_rule.cc
@@ -491,7 +491,7 @@
     const dnr_api::HeaderInfo& header_info) {
   auto validate_header_values = [](const std::vector<std::string>& values) {
     return base::ranges::all_of(values, [](const std::string& value) {
-      return !value.empty() && net::HttpUtil::IsValidHeaderValue(value);
+      return net::HttpUtil::IsValidHeaderValue(value);
     });
   };
 
diff --git a/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc b/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc
index 54fbadf8..0151e6d 100644
--- a/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc
+++ b/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc
@@ -1134,6 +1134,10 @@
        HeaderInfoList({RawHeaderInfo("excluded-header")}),
        ParseResult::SUCCESS},
 
+      // An empty response header value should parse successfully.
+      {HeaderInfoList({{"header", HeaderValues({""}), std::nullopt}}),
+       std::nullopt, ParseResult::SUCCESS},
+
       // An empty matching response header list should trigger an error.
       {HeaderInfoList(), std::nullopt,
        ParseResult::ERROR_EMPTY_RESPONSE_HEADER_MATCHING_LIST},
@@ -1145,18 +1149,13 @@
 
       // Test that a rule with an empty or invalid response header name will
       // return an error.
-      {HeaderInfoList({{"", std::nullopt, std::nullopt}}), std::nullopt,
+      {HeaderInfoList({RawHeaderInfo("")}), std::nullopt,
        ParseResult::ERROR_INVALID_MATCHING_RESPONSE_HEADER_NAME},
 
       {std::nullopt, HeaderInfoList({RawHeaderInfo("<<invalid_header>>")}),
        ParseResult::ERROR_INVALID_MATCHING_EXCLUDED_RESPONSE_HEADER_NAME},
 
-      // Test that a rule with an empty or invalid response header value will
-      // return an error.
-      {HeaderInfoList({{"header", HeaderValues({""}), std::nullopt}}),
-       std::nullopt, ParseResult::ERROR_INVALID_MATCHING_RESPONSE_HEADER_VALUE},
-
-      // Test that a rule with an empty response header value will return an
+      // Test that a rule with an invalid response header value will return an
       // error.
       {std::nullopt,
        HeaderInfoList({{"invalid-header-value",
diff --git a/extensions/browser/verified_contents.h b/extensions/browser/verified_contents.h
index 2242b1c..85b7953 100644
--- a/extensions/browser/verified_contents.h
+++ b/extensions/browser/verified_contents.h
@@ -15,6 +15,7 @@
 
 #include "base/containers/span.h"
 #include "base/files/file_path.h"
+#include "base/memory/raw_span.h"
 #include "base/version.h"
 #include "extensions/browser/content_verifier/content_verifier_utils.h"
 #include "extensions/common/extension_id.h"
@@ -84,7 +85,7 @@
                        const std::string& signature_bytes);
 
   // The public key we should use for signature verification.
-  base::span<const uint8_t> public_key_;
+  base::raw_span<const uint8_t, DanglingUntriaged> public_key_;
 
   // Indicates whether the signature was successfully validated or not.
   bool valid_signature_;
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn
index 1dd96d3..179db98 100644
--- a/gpu/BUILD.gn
+++ b/gpu/BUILD.gn
@@ -76,94 +76,6 @@
   public_deps = [ "//gpu/command_buffer/client:webgpu_sources" ]
 }
 
-if (!use_static_angle) {
-  shared_library("command_buffer_gles2") {
-    sources = [
-      # TODO(hendrikw): Move egl out of gles2_conform_support.
-      "gles2_conform_support/egl/config.cc",
-      "gles2_conform_support/egl/config.h",
-      "gles2_conform_support/egl/context.cc",
-      "gles2_conform_support/egl/context.h",
-      "gles2_conform_support/egl/display.cc",
-      "gles2_conform_support/egl/display.h",
-      "gles2_conform_support/egl/egl.cc",
-      "gles2_conform_support/egl/surface.cc",
-      "gles2_conform_support/egl/surface.h",
-      "gles2_conform_support/egl/test_support.cc",
-      "gles2_conform_support/egl/test_support.h",
-      "gles2_conform_support/egl/thread_state.cc",
-      "gles2_conform_support/egl/thread_state.h",
-    ]
-
-    deps = [
-      ":gpu",
-      "//base",
-      "//gpu/command_buffer/client:gles2_c_lib",
-      "//gpu/command_buffer/client:gles2_cmd_helper",
-      "//gpu/command_buffer/client:gles2_implementation",
-      "//gpu/command_buffer/service:gles2",
-      "//ui/gl",
-      "//ui/gl/init",
-    ]
-
-    if (use_ozone) {
-      deps += [ "//ui/ozone" ]
-    }
-
-    defines = [
-      "COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY",
-      "EGLAPIENTRY=",
-    ]
-    if (is_android) {
-      configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
-    }
-    if (current_os == "win") {
-      defines += [ "EGLAPI=__declspec(dllexport)" ]
-    } else {
-      defines += [ "EGLAPI=__attribute__((visibility(\"default\")))" ]
-    }
-  }
-
-  test("command_buffer_gles2_tests") {
-    sources = [
-      "command_buffer/tests/command_buffer_gles2_tests_main.cc",
-      "command_buffer/tests/egl_test.cc",
-    ]
-
-    deps = [
-      ":command_buffer_gles2",
-      "//base",
-      "//base/test:test_support",
-      "//testing/gmock",
-      "//testing/gtest",
-    ]
-
-    defines = [
-      "COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY",
-      "EGLAPIENTRY=",
-    ]
-    if (current_os == "win") {
-      defines += [ "EGLAPI=__declspec(dllimport)" ]
-    } else {
-      defines += [ "EGLAPI=" ]
-    }
-
-    libs = []
-
-    if (is_android) {
-      libs += [ "android" ]
-      deps += [ "//ui/android:ui_java" ]
-    }
-    if ((is_linux || is_chromeos) && !is_component_build) {
-      configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
-    }
-
-    if (use_ozone) {
-      deps += [ "//ui/base:features" ]
-    }
-  }
-}  # if (!use_static_angle)
-
 static_library("test_support") {
   testonly = true
   sources = [
diff --git a/gpu/command_buffer/build_cmd_buffer_lib.py b/gpu/command_buffer/build_cmd_buffer_lib.py
index 613b775b..44915eb 100644
--- a/gpu/command_buffer/build_cmd_buffer_lib.py
+++ b/gpu/command_buffer/build_cmd_buffer_lib.py
@@ -424,7 +424,6 @@
         'type': 'GLenum',
         'enum': 'GL_GENERATE_MIPMAP_HINT',
         'default': 'GL_DONT_CARE',
-        'gl_version_flag': '!is_desktop_core_profile'
       },
       {
         'name': 'hint_fragment_shader_derivative',
diff --git a/gpu/command_buffer/client/BUILD.gn b/gpu/command_buffer/client/BUILD.gn
index c3ecd3d..345e3cb 100644
--- a/gpu/command_buffer/client/BUILD.gn
+++ b/gpu/command_buffer/client/BUILD.gn
@@ -359,10 +359,7 @@
 component("gles2_implementation_no_check") {
   sources = gles2_implementation_source_files
 
-  defines = [
-    "GLES2_IMPL_IMPLEMENTATION",
-    "GLES2_CONFORMANCE_TESTS=1",
-  ]
+  defines = [ "GLES2_IMPL_IMPLEMENTATION" ]
   if (enable_gpu_client_logging) {
     defines += [ "GPU_ENABLE_CLIENT_LOGGING" ]
   }
@@ -399,19 +396,3 @@
     "//gpu/command_buffer/common",
   ]
 }
-
-# Same as gles2_c_lib except with no parameter checking. Required for
-# OpenGL ES 2.0 conformance tests.
-component("gles2_c_lib_nocheck") {
-  sources = gles2_c_lib_source_files
-
-  defines = [
-    "GLES2_C_LIB_IMPLEMENTATION",
-    "GLES2_CONFORMANCE_TESTS=1",
-  ]
-  deps = [
-    ":gles2_interface",
-    "//base",
-    "//gpu/command_buffer/common",
-  ]
-}
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index f62a3f8..8a750b28b 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -83,8 +83,7 @@
 //
 // If it was up to us we'd just always write to the destination but the OpenGL
 // spec defines the behavior of OpenGL functions, not us. :-(
-#if defined(__native_client__) || defined(GLES2_CONFORMANCE_TESTS) || \
-    BUILDFLAG(IS_MINIMAL_TOOLCHAIN)
+#if defined(__native_client__) || BUILDFLAG(IS_MINIMAL_TOOLCHAIN)
 #define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(v)
 #define GPU_CLIENT_DCHECK(v)
 #elif defined(GPU_DCHECK)
diff --git a/gpu/command_buffer/client/logging.h b/gpu/command_buffer/client/logging.h
index 16b7a973..9abf433 100644
--- a/gpu/command_buffer/client/logging.h
+++ b/gpu/command_buffer/client/logging.h
@@ -37,9 +37,8 @@
 //   LogSettings log_settings_;
 // };
 
-#if (DCHECK_IS_ON() || defined(GPU_ENABLE_CLIENT_LOGGING)) &&           \
-    !defined(__native_client__) && !defined(GLES2_CONFORMANCE_TESTS) && \
-    !defined(GLES2_INLINE_OPTIMIZATION)
+#if (DCHECK_IS_ON() || defined(GPU_ENABLE_CLIENT_LOGGING)) && \
+    !defined(__native_client__) && !defined(GLES2_INLINE_OPTIMIZATION)
 #define GPU_CLIENT_DEBUG
 #endif
 
diff --git a/gpu/command_buffer/client/program_info_manager.cc b/gpu/command_buffer/client/program_info_manager.cc
index c5203d85..eea2ebb9 100644
--- a/gpu/command_buffer/client/program_info_manager.cc
+++ b/gpu/command_buffer/client/program_info_manager.cc
@@ -2,13 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "gpu/command_buffer/client/program_info_manager.h"
+
 #include <stddef.h>
 #include <stdint.h>
 #include <string.h>
 
 #include <string_view>
 
-#include "gpu/command_buffer/client/program_info_manager.h"
+#include "base/memory/raw_span.h"
 
 namespace {
 
@@ -48,7 +50,7 @@
   }
 
  private:
-  base::span<const int8_t> data_;
+  base::raw_span<const int8_t> data_;
 };
 
 // Writes the string pointed by name and of maximum size buffsize. If length is
diff --git a/gpu/command_buffer/service/context_state_impl_autogen.h b/gpu/command_buffer/service/context_state_impl_autogen.h
index 38accac..3cf77d9 100644
--- a/gpu/command_buffer/service/context_state_impl_autogen.h
+++ b/gpu/command_buffer/service/context_state_impl_autogen.h
@@ -254,10 +254,8 @@
       api()->glDepthRangeFn(z_near, z_far);
     if ((front_face != prev_state->front_face))
       api()->glFrontFaceFn(front_face);
-    if (!feature_info_->gl_version_info().is_desktop_core_profile) {
-      if (prev_state->hint_generate_mipmap != hint_generate_mipmap) {
-        api()->glHintFn(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap);
-      }
+    if (prev_state->hint_generate_mipmap != hint_generate_mipmap) {
+      api()->glHintFn(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap);
     }
     if (feature_info_->feature_flags().oes_standard_derivatives) {
       if (prev_state->hint_fragment_shader_derivative !=
@@ -336,9 +334,7 @@
     api()->glDepthMaskFn(cached_depth_mask);
     api()->glDepthRangeFn(z_near, z_far);
     api()->glFrontFaceFn(front_face);
-    if (!feature_info_->gl_version_info().is_desktop_core_profile) {
-      api()->glHintFn(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap);
-    }
+    api()->glHintFn(GL_GENERATE_MIPMAP_HINT, hint_generate_mipmap);
     if (feature_info_->feature_flags().oes_standard_derivatives) {
       api()->glHintFn(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES,
                       hint_fragment_shader_derivative);
diff --git a/gpu/command_buffer/service/context_state_test_helpers_autogen.h b/gpu/command_buffer/service/context_state_test_helpers_autogen.h
index 1fc37062..7b64b2c 100644
--- a/gpu/command_buffer/service/context_state_test_helpers_autogen.h
+++ b/gpu/command_buffer/service/context_state_test_helpers_autogen.h
@@ -62,11 +62,9 @@
   EXPECT_CALL(*gl, DepthMask(true)).Times(1).RetiresOnSaturation();
   EXPECT_CALL(*gl, DepthRange(0.0f, 1.0f)).Times(1).RetiresOnSaturation();
   EXPECT_CALL(*gl, FrontFace(GL_CCW)).Times(1).RetiresOnSaturation();
-  if (!feature_info->gl_version_info().is_desktop_core_profile) {
-    EXPECT_CALL(*gl, Hint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE))
-        .Times(1)
-        .RetiresOnSaturation();
-  }
+  EXPECT_CALL(*gl, Hint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE))
+      .Times(1)
+      .RetiresOnSaturation();
   if (feature_info->feature_flags().oes_standard_derivatives) {
     EXPECT_CALL(*gl, Hint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES, GL_DONT_CARE))
         .Times(1)
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index 521a3d54..f3db9ee 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -448,7 +448,7 @@
     if (gfx::HasExtension(extensions, "GL_ANGLE_instanced_arrays") ||
         (gfx::HasExtension(extensions, "GL_ARB_instanced_arrays") &&
          gfx::HasExtension(extensions, "GL_ARB_draw_instanced")) ||
-        gl_version_info_->is_es3 || gl_version_info_->is_desktop_core_profile) {
+        gl_version_info_->is_es3) {
       AddExtensionString("GL_ANGLE_instanced_arrays");
       feature_flags_.angle_instanced_arrays = true;
       validators_.vertex_attribute.AddValue(
@@ -463,8 +463,7 @@
     if (!is_passthrough_cmd_decoder_ ||
         gfx::HasExtension(extensions, "GL_ANGLE_multi_draw")) {
       if (gfx::HasExtension(extensions, "GL_ANGLE_instanced_arrays") ||
-          feature_flags_.angle_instanced_arrays || gl_version_info_->is_es3 ||
-          gl_version_info_->is_desktop_core_profile) {
+          feature_flags_.angle_instanced_arrays || gl_version_info_->is_es3) {
         feature_flags_.webgl_multi_draw = true;
         AddExtensionString("GL_WEBGL_multi_draw");
 
@@ -492,7 +491,7 @@
   // Really it's part of core OpenGL 2.1 and up, but let's assume the
   // extension is still advertised.
   bool has_pixel_buffers =
-      gl_version_info_->is_es3 || gl_version_info_->is_desktop_core_profile ||
+      gl_version_info_->is_es3 ||
       gfx::HasExtension(extensions, "GL_ARB_pixel_buffer_object") ||
       gfx::HasExtension(extensions, "GL_NV_pixel_buffer_object");
 
@@ -726,8 +725,7 @@
   if (!workarounds_.disable_depth_texture &&
       (gfx::HasExtension(extensions, "GL_ARB_depth_texture") ||
        gfx::HasExtension(extensions, "GL_OES_depth_texture") ||
-       gfx::HasExtension(extensions, "GL_ANGLE_depth_texture") ||
-       gl_version_info_->is_desktop_core_profile)) {
+       gfx::HasExtension(extensions, "GL_ANGLE_depth_texture"))) {
     // Note that we don't expose depth_texture extenion on top of ES3 if
     // the depth_texture extension isn't exposed by the ES3 driver.
     // This is because depth textures are filterable under linear mode in
@@ -752,7 +750,7 @@
   GLenum depth_stencil_texture_format = GL_NONE;
   if (gfx::HasExtension(extensions, "GL_EXT_packed_depth_stencil") ||
       gfx::HasExtension(extensions, "GL_OES_packed_depth_stencil") ||
-      gl_version_info_->is_es3 || gl_version_info_->is_desktop_core_profile) {
+      gl_version_info_->is_es3) {
     AddExtensionString("GL_OES_packed_depth_stencil");
     feature_flags_.packed_depth24_stencil8 = true;
     if (enable_depth_texture) {
@@ -782,7 +780,7 @@
     }
   }
 
-  if (gl_version_info_->is_es3 || gl_version_info_->is_desktop_core_profile ||
+  if (gl_version_info_->is_es3 ||
       gfx::HasExtension(extensions, "GL_OES_vertex_array_object") ||
       gfx::HasExtension(extensions, "GL_ARB_vertex_array_object") ||
       gfx::HasExtension(extensions, "GL_APPLE_vertex_array_object")) {
@@ -1066,7 +1064,7 @@
 
   // Check if we should allow GL_OES_texture_npot
   if (!disallowed_features_.npot_support &&
-      (gl_version_info_->is_es3 || gl_version_info_->is_desktop_core_profile ||
+      (gl_version_info_->is_es3 ||
        gfx::HasExtension(extensions, "GL_ARB_texture_non_power_of_two") ||
        gfx::HasExtension(extensions, "GL_OES_texture_npot"))) {
     AddExtensionString("GL_OES_texture_npot");
@@ -1081,7 +1079,7 @@
         gfx::HasExtension(extensions, "GL_ARB_framebuffer_object") ||
         (gfx::HasExtension(extensions, "GL_EXT_framebuffer_multisample") &&
          gfx::HasExtension(extensions, "GL_EXT_framebuffer_blit")) ||
-        gl_version_info_->is_es3 || gl_version_info_->is_desktop_core_profile;
+        gl_version_info_->is_es3;
     if (gl_version_info_->is_angle || gl_version_info_->is_swiftshader) {
       ext_has_multisample |=
           gfx::HasExtension(extensions, "GL_ANGLE_framebuffer_multisample");
@@ -1225,8 +1223,7 @@
   // they should use ordinary non-power-of-two textures. However, for unit
   // testing purposes we expose it on all supported platforms.
   if (gfx::HasExtension(extensions, "GL_ARB_texture_rectangle") ||
-      gfx::HasExtension(extensions, "GL_ANGLE_texture_rectangle") ||
-      gl_version_info_->is_desktop_core_profile) {
+      gfx::HasExtension(extensions, "GL_ANGLE_texture_rectangle")) {
     AddExtensionString("GL_ARB_texture_rectangle");
     feature_flags_.arb_texture_rectangle = true;
     // Rectangle textures are used as samplers via glBindTexture, framebuffer
@@ -1303,8 +1300,6 @@
   bool have_arb_occlusion_query2 =
       gfx::HasExtension(extensions, "GL_ARB_occlusion_query2");
   bool have_arb_occlusion_query =
-      (gl_version_info_->is_desktop_core_profile &&
-       gl_version_info_->IsAtLeastGL(1, 5)) ||
       gfx::HasExtension(extensions, "GL_ARB_occlusion_query");
 
   if (have_occlusion_query || have_ext_occlusion_query_boolean ||
@@ -1326,7 +1321,6 @@
   EnableANGLEInstancedArrayIfPossible(extensions);
 
   bool have_es2_draw_buffers_vendor_agnostic =
-      gl_version_info_->is_desktop_core_profile ||
       gfx::HasExtension(extensions, "GL_ARB_draw_buffers") ||
       gfx::HasExtension(extensions, "GL_EXT_draw_buffers");
   bool can_emulate_es2_draw_buffers_on_es3_nv =
@@ -1403,7 +1397,7 @@
   bool ui_gl_fence_works = gl::GLFence::IsSupported();
 
   feature_flags_.map_buffer_range =
-      gl_version_info_->is_es3 || gl_version_info_->is_desktop_core_profile ||
+      gl_version_info_->is_es3 ||
       gfx::HasExtension(extensions, "GL_ARB_map_buffer_range") ||
       gfx::HasExtension(extensions, "GL_EXT_map_buffer_range");
 
@@ -1462,7 +1456,7 @@
     }
   }
 
-  if ((gl_version_info_->is_es3 || gl_version_info_->is_desktop_core_profile ||
+  if ((gl_version_info_->is_es3 ||
        gfx::HasExtension(extensions, "GL_EXT_texture_rg") ||
        gfx::HasExtension(extensions, "GL_ARB_texture_rg")) &&
       IsGL_REDSupportedOnFBOs()) {
@@ -1495,8 +1489,7 @@
 
   const bool is_texture_norm16_supported_for_webgl2_or_es3 =
       IsWebGL2OrES3OrHigherContext() &&
-      (gl_version_info_->is_desktop_core_profile ||
-       (gl_version_info_->IsAtLeastGL(2, 1) &&
+      ((gl_version_info_->IsAtLeastGL(2, 1) &&
         gfx::HasExtension(extensions, "GL_ARB_texture_rg")) ||
        gfx::HasExtension(extensions, "GL_EXT_texture_norm16"));
   const bool is_texture_norm16_supported_for_angle_es2 =
@@ -1689,9 +1682,7 @@
 #else
   if ((!is_passthrough_cmd_decoder_ &&
        ((gl_version_info_->IsAtLeastGLES(3, 2) &&
-         gfx::HasExtension(extensions, "GL_EXT_base_instance")) ||
-        (gl_version_info_->is_desktop_core_profile &&
-         gl_version_info_->IsAtLeastGL(4, 2)))) ||
+         gfx::HasExtension(extensions, "GL_EXT_base_instance")))) ||
       gfx::HasExtension(extensions, "GL_ANGLE_base_vertex_base_instance")) {
 #endif
     // TODO(shrekshao): change condition to the following after workaround for
@@ -1853,8 +1844,7 @@
     enable_ext_color_buffer_half_float = true;
   }
 
-  if (gfx::HasExtension(extensions, "GL_ARB_texture_float") ||
-      gl_version_info_->is_desktop_core_profile) {
+  if (gfx::HasExtension(extensions, "GL_ARB_texture_float")) {
     enable_texture_float = true;
     enable_texture_float_linear = true;
     enable_texture_half_float = true;
diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc
index ae85ba7..13127c73 100644
--- a/gpu/command_buffer/service/feature_info_unittest.cc
+++ b/gpu/command_buffer/service/feature_info_unittest.cc
@@ -1380,28 +1380,6 @@
   EXPECT_TRUE(info_->feature_flags().occlusion_query_boolean);
 }
 
-TEST_P(FeatureInfoTest, InitializeGL33_occlusion_query2) {
-  SetupInitExpectationsWithGLVersion("", "", "3.3");
-  if (GetContextType() == CONTEXT_TYPE_OPENGLES2) {
-    EXPECT_TRUE(gfx::HasExtension(info_->extensions(),
-                                  "GL_EXT_occlusion_query_boolean"));
-  }
-  EXPECT_TRUE(info_->feature_flags().occlusion_query_boolean);
-  EXPECT_TRUE(info_->feature_flags(
-      ).use_arb_occlusion_query2_for_occlusion_query_boolean);
-}
-
-TEST_P(FeatureInfoTest, InitializeGL43_occlusion_query2) {
-  SetupInitExpectationsWithGLVersion("", "", "4.3");
-  if (GetContextType() == CONTEXT_TYPE_OPENGLES2) {
-    EXPECT_TRUE(gfx::HasExtension(info_->extensions(),
-                                  "GL_EXT_occlusion_query_boolean"));
-  }
-  EXPECT_TRUE(info_->feature_flags().occlusion_query_boolean);
-  EXPECT_FALSE(info_->feature_flags(
-      ).use_arb_occlusion_query2_for_occlusion_query_boolean);
-}
-
 TEST_P(FeatureInfoTest, InitializeOES_vertex_array_object) {
   SetupInitExpectations("GL_OES_vertex_array_object");
   EXPECT_TRUE(
diff --git a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
index 043171f2..45301ab3 100644
--- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
+++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
@@ -1246,9 +1246,7 @@
   if (vertex_array_object_id_) {
     glBindVertexArrayOES(vertex_array_object_id_);
   } else {
-    if (!gl_version_info.is_desktop_core_profile) {
-      decoder->ClearAllAttributes();
-    }
+    decoder->ClearAllAttributes();
     glEnableVertexAttribArray(kVertexPositionAttrib);
     glBindBuffer(GL_ARRAY_BUFFER, buffer_id_);
     glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index aa99596..76c4a43 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -3225,23 +3225,9 @@
       GLint depth_bits = 0;
       GLint stencil_bits = 0;
 
-      bool default_fb = (GetBackbufferServiceId() == 0);
-
-      if (gl_version_info().is_desktop_core_profile) {
-        api()->glGetFramebufferAttachmentParameterivEXTFn(
-            GL_FRAMEBUFFER, default_fb ? GL_BACK_LEFT : GL_COLOR_ATTACHMENT0,
-            GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &alpha_bits);
-        api()->glGetFramebufferAttachmentParameterivEXTFn(
-            GL_FRAMEBUFFER, default_fb ? GL_DEPTH : GL_DEPTH_ATTACHMENT,
-            GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depth_bits);
-        api()->glGetFramebufferAttachmentParameterivEXTFn(
-            GL_FRAMEBUFFER, default_fb ? GL_STENCIL : GL_STENCIL_ATTACHMENT,
-            GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencil_bits);
-      } else {
-        api()->glGetIntegervFn(GL_ALPHA_BITS, &alpha_bits);
-        api()->glGetIntegervFn(GL_DEPTH_BITS, &depth_bits);
-        api()->glGetIntegervFn(GL_STENCIL_BITS, &stencil_bits);
-      }
+      api()->glGetIntegervFn(GL_ALPHA_BITS, &alpha_bits);
+      api()->glGetIntegervFn(GL_DEPTH_BITS, &depth_bits);
+      api()->glGetIntegervFn(GL_STENCIL_BITS, &stencil_bits);
 
       back_buffer_color_format_ = alpha_bits > 0 ? GL_RGBA : GL_RGB;
       back_buffer_has_depth_ = depth_bits > 0;
@@ -3264,10 +3250,6 @@
   if (!gl_version_info().BehavesLikeGLES()) {
     api()->glEnableFn(GL_VERTEX_PROGRAM_POINT_SIZE);
     api()->glEnableFn(GL_POINT_SPRITE);
-  } else if (gl_version_info().is_desktop_core_profile) {
-    // The desktop core profile changed how program point size mode is
-    // enabled.
-    api()->glEnableFn(GL_PROGRAM_POINT_SIZE);
   }
 
   // ES3 requires seamless cubemap. ES2 does not.
@@ -6273,18 +6255,7 @@
         if (framebuffer) {
           if (framebuffer->HasAlphaMRT() &&
               framebuffer->HasSameInternalFormatsMRT()) {
-            if (gl_version_info().is_desktop_core_profile) {
-              for (uint32_t i = 0; i < group_->max_draw_buffers(); i++) {
-                if (framebuffer->HasColorAttachment(i)) {
-                  api()->glGetFramebufferAttachmentParameterivEXTFn(
-                      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
-                      GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &v);
-                  break;
-                }
-              }
-            } else {
-              api()->glGetIntegervFn(GL_ALPHA_BITS, &v);
-            }
+            api()->glGetIntegervFn(GL_ALPHA_BITS, &v);
           }
         } else {
           v = (ClientExposedBackBufferHasAlpha() ? 8 : 0);
@@ -6296,20 +6267,7 @@
       *num_written = 1;
       if (params) {
         GLint v = 0;
-        if (gl_version_info().is_desktop_core_profile) {
-          Framebuffer* framebuffer = GetBoundDrawFramebuffer();
-          if (framebuffer) {
-            if (framebuffer->HasDepthAttachment()) {
-              api()->glGetFramebufferAttachmentParameterivEXTFn(
-                  GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-                  GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &v);
-            }
-          } else {
-            v = (back_buffer_has_depth_ ? 24 : 0);
-          }
-        } else {
-          api()->glGetIntegervFn(GL_DEPTH_BITS, &v);
-        }
+        api()->glGetIntegervFn(GL_DEPTH_BITS, &v);
         params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
       }
       return true;
@@ -6319,37 +6277,7 @@
       *num_written = 1;
       if (params) {
         GLint v = 0;
-        if (gl_version_info().is_desktop_core_profile) {
-          Framebuffer* framebuffer = GetBoundDrawFramebuffer();
-          if (framebuffer) {
-            if (framebuffer->HasSameInternalFormatsMRT()) {
-              GLenum framebuffer_enum = 0;
-              switch (pname) {
-                case GL_RED_BITS:
-                  framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE;
-                  break;
-                case GL_GREEN_BITS:
-                  framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE;
-                  break;
-                case GL_BLUE_BITS:
-                  framebuffer_enum = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE;
-                  break;
-              }
-              for (uint32_t i = 0; i < group_->max_draw_buffers(); i++) {
-                if (framebuffer->HasColorAttachment(i)) {
-                  api()->glGetFramebufferAttachmentParameterivEXTFn(
-                      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
-                      framebuffer_enum, &v);
-                  break;
-                }
-              }
-            }
-          } else {
-            v = 8;
-          }
-        } else {
-          api()->glGetIntegervFn(pname, &v);
-        }
+        api()->glGetIntegervFn(pname, &v);
         params[0] = v;
       }
       return true;
@@ -6357,20 +6285,7 @@
       *num_written = 1;
       if (params) {
         GLint v = 0;
-        if (gl_version_info().is_desktop_core_profile) {
-          Framebuffer* framebuffer = GetBoundDrawFramebuffer();
-          if (framebuffer) {
-            if (framebuffer->HasStencilAttachment()) {
-              api()->glGetFramebufferAttachmentParameterivEXTFn(
-                  GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
-                  GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &v);
-            }
-          } else {
-            v = (back_buffer_has_stencil_ ? 8 : 0);
-          }
-        } else {
-          api()->glGetIntegervFn(GL_STENCIL_BITS, &v);
-        }
+        api()->glGetIntegervFn(GL_STENCIL_BITS, &v);
         params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
       }
       return true;
@@ -6712,10 +6627,6 @@
       features().use_img_for_multisampled_render_to_texture) {
     return GL_MAX_SAMPLES_IMG;
   }
-  if (GL_ALIASED_POINT_SIZE_RANGE == pname &&
-      gl_version_info().is_desktop_core_profile) {
-    return GL_POINT_SIZE_RANGE;
-  }
   return pname;
 }
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index 09f4b43..6e83d852 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -2200,9 +2200,7 @@
     case GL_GENERATE_MIPMAP_HINT:
       if (state_.hint_generate_mipmap != mode) {
         state_.hint_generate_mipmap = mode;
-        if (!feature_info_->gl_version_info().is_desktop_core_profile) {
-          api()->glHintFn(target, mode);
-        }
+        api()->glHintFn(target, mode);
       }
       break;
     case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index 34a02f8..4dd0a7cc 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -350,33 +350,15 @@
       .Times(1)
       .RetiresOnSaturation();
 
-  if (group_->feature_info()->gl_version_info().is_desktop_core_profile) {
-    EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(
-                          GL_FRAMEBUFFER, GL_BACK_LEFT,
-                          GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, _))
-        .WillOnce(SetArgPointee<3>(normalized_init.has_alpha ? 8 : 0))
-        .RetiresOnSaturation();
-    EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(
-                          GL_FRAMEBUFFER, GL_DEPTH,
-                          GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, _))
-        .WillOnce(SetArgPointee<3>(normalized_init.has_depth ? 24 : 0))
-        .RetiresOnSaturation();
-    EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(
-                          GL_FRAMEBUFFER, GL_STENCIL,
-                          GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, _))
-        .WillOnce(SetArgPointee<3>(normalized_init.has_stencil ? 8 : 0))
-        .RetiresOnSaturation();
-  } else {
-    EXPECT_CALL(*gl_, GetIntegerv(GL_ALPHA_BITS, _))
-        .WillOnce(SetArgPointee<1>(normalized_init.has_alpha ? 8 : 0))
-        .RetiresOnSaturation();
-    EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
-        .WillOnce(SetArgPointee<1>(normalized_init.has_depth ? 24 : 0))
-        .RetiresOnSaturation();
-    EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
-        .WillOnce(SetArgPointee<1>(normalized_init.has_stencil ? 8 : 0))
-        .RetiresOnSaturation();
-  }
+  EXPECT_CALL(*gl_, GetIntegerv(GL_ALPHA_BITS, _))
+      .WillOnce(SetArgPointee<1>(normalized_init.has_alpha ? 8 : 0))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
+      .WillOnce(SetArgPointee<1>(normalized_init.has_depth ? 24 : 0))
+      .RetiresOnSaturation();
+  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
+      .WillOnce(SetArgPointee<1>(normalized_init.has_stencil ? 8 : 0))
+      .RetiresOnSaturation();
 
   if (!group_->feature_info()->gl_version_info().BehavesLikeGLES()) {
     EXPECT_CALL(*gl_, Enable(GL_VERTEX_PROGRAM_POINT_SIZE))
@@ -386,12 +368,6 @@
     EXPECT_CALL(*gl_, Enable(GL_POINT_SPRITE))
         .Times(1)
         .RetiresOnSaturation();
-  } else if (group_->feature_info()
-                 ->gl_version_info()
-                 .is_desktop_core_profile) {
-    EXPECT_CALL(*gl_, Enable(GL_PROGRAM_POINT_SIZE))
-        .Times(1)
-        .RetiresOnSaturation();
   }
 
   if (group_->feature_info()->gl_version_info().IsAtLeastGL(3, 2)) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc
index 3b62ee7..f41bbe2 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_state.cc
@@ -557,20 +557,6 @@
   DoBindBuffer(GL_PIXEL_UNPACK_BUFFER, client_buffer_id_, kServiceBufferId);
 }
 
-TEST_P(GLES2DecoderManualInitTest, MipmapHintOnCoreProfile) {
-  // On a core profile, glHint(GL_GENERATE_MIPMAP_HINT) should be a noop
-  InitState init;
-  init.gl_version = "3.2";
-  InitDecoder(init);
-
-  cmds::Hint cmd;
-  cmd.Init(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
-
-  EXPECT_CALL(*gl_, Hint(GL_GENERATE_MIPMAP_HINT, GL_NICEST)).Times(0);
-  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
-  EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
 TEST_P(GLES2DecoderManualInitTest, MipmapHintOnCompatibilityProfile) {
   // On a compatibility profile, glHint(GL_GENERATE_MIPMAP_HINT) should be go
   // through
diff --git a/gpu/command_buffer/service/gles2_external_framebuffer_unittest.cc b/gpu/command_buffer/service/gles2_external_framebuffer_unittest.cc
index 704bdb5..d291f56 100644
--- a/gpu/command_buffer/service/gles2_external_framebuffer_unittest.cc
+++ b/gpu/command_buffer/service/gles2_external_framebuffer_unittest.cc
@@ -264,23 +264,9 @@
   GLint stencil_bits = 0;
   GLint alpha_bits = 0;
 
-  if (context_state_->feature_info()
-          ->gl_version_info()
-          .is_desktop_core_profile) {
-    api->glGetFramebufferAttachmentParameterivEXTFn(
-        GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-        GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, &alpha_bits);
-    api->glGetFramebufferAttachmentParameterivEXTFn(
-        GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-        GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depth_bits);
-    api->glGetFramebufferAttachmentParameterivEXTFn(
-        GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
-        GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencil_bits);
-  } else {
-    api->glGetIntegervFn(GL_ALPHA_BITS, &alpha_bits);
-    api->glGetIntegervFn(GL_DEPTH_BITS, &depth_bits);
-    api->glGetIntegervFn(GL_STENCIL_BITS, &stencil_bits);
-  }
+  api->glGetIntegervFn(GL_ALPHA_BITS, &alpha_bits);
+  api->glGetIntegervFn(GL_DEPTH_BITS, &depth_bits);
+  api->glGetIntegervFn(GL_STENCIL_BITS, &stencil_bits);
 
   // If we requested depth, expect it to be there.
   if (params.need_depth)
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory_unittest.cc b/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory_unittest.cc
index 4d3a401..a5f8f06 100644
--- a/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory_unittest.cc
+++ b/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory_unittest.cc
@@ -26,7 +26,6 @@
 #include "gpu/config/gpu_driver_bug_workarounds.h"
 #include "gpu/config/gpu_feature_info.h"
 #include "gpu/config/gpu_preferences.h"
-#include "gpu/config/gpu_test_config.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -433,14 +432,6 @@
 }
 
 TEST_P(GLTextureImageBackingFactoryWithFormatTest, Basic) {
-  // TODO(jonahr): Test fails on Mac with ANGLE/passthrough
-  // (crbug.com/1100975)
-  gpu::GPUTestBotConfig bot_config;
-  if (bot_config.LoadCurrentConfig(nullptr) &&
-      bot_config.Matches("mac passthrough")) {
-    GTEST_SKIP();
-  }
-
   viz::SharedImageFormat format = get_format();
   if (!IsFormatSupport(format)) {
     GTEST_SKIP();
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
index 5648396..4f3afb85 100644
--- a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
+++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
@@ -772,16 +772,22 @@
   const wgpu::TextureFormat wgpu_format_;
   const std::vector<wgpu::TextureFormat> view_formats_;
 
-  // NOTE: `usage_` and `texture_` are valid only within the duration of a
-  // BeginAccess()/EndAccess() pair.
+  // NOTE: `usage_`, `internal_usage_`, and `texture_` are valid only within
+  // the duration of a BeginAccess()/EndAccess() pair.
   wgpu::TextureUsage usage_;
+  wgpu::TextureUsage internal_usage_;
   wgpu::Texture texture_;
 };
 
 wgpu::Texture IOSurfaceImageBacking::DawnRepresentation::BeginAccess(
     wgpu::TextureUsage wgpu_texture_usage,
     wgpu::TextureUsage internal_usage) {
-  const bool readonly = (wgpu_texture_usage & ~kReadOnlyUsage) == 0;
+  const bool readonly =
+      (wgpu_texture_usage & ~kReadOnlyUsage) == 0 &&
+      (!base::FeatureList::IsEnabled(
+           features::kDawnSIRepsUseClientProvidedInternalUsages) ||
+       (internal_usage & ~kReadOnlyUsage) == 0);
+
   IOSurfaceImageBacking* iosurface_backing =
       static_cast<IOSurfaceImageBacking*>(backing());
   if (!iosurface_backing->BeginAccess(readonly)) {
@@ -798,6 +804,7 @@
       /*device_to_exclude=*/device_);
 
   usage_ = wgpu_texture_usage;
+  internal_usage_ = internal_usage;
 
   texture_ = iosurface_backing->GetCachedWGPUTexture(device_, usage_);
   if (!texture_) {
@@ -889,7 +896,11 @@
   // its state tracking.
   IOSurfaceImageBacking* iosurface_backing =
       static_cast<IOSurfaceImageBacking*>(backing());
-  const bool readonly = (usage_ & ~kReadOnlyUsage) == 0;
+  const bool readonly =
+      (usage_ & ~kReadOnlyUsage) == 0 &&
+      (!base::FeatureList::IsEnabled(
+           features::kDawnSIRepsUseClientProvidedInternalUsages) ||
+       (internal_usage_ & ~kReadOnlyUsage) == 0);
   iosurface_backing->EndAccess(readonly);
   int num_outstanding_accesses =
       iosurface_backing->TrackEndAccessToWGPUTexture(texture_);
@@ -900,7 +911,7 @@
   // will happen when the last ongoing Dawn access finishes.
   if (num_outstanding_accesses > 0) {
     texture_ = nullptr;
-    usage_ = wgpu::TextureUsage::None;
+    usage_ = internal_usage_ = wgpu::TextureUsage::None;
     return;
   }
 
@@ -947,7 +958,7 @@
   }
 
   texture_ = nullptr;
-  usage_ = wgpu::TextureUsage::None;
+  usage_ = internal_usage_ = wgpu::TextureUsage::None;
 }
 
 // Enabling this functionality reduces overhead in the compositor by lowering
diff --git a/gpu/command_buffer/service/test_helper.cc b/gpu/command_buffer/service/test_helper.cc
index b3ee156..44db616 100644
--- a/gpu/command_buffer/service/test_helper.cc
+++ b/gpu/command_buffer/service/test_helper.cc
@@ -205,7 +205,6 @@
     ::gl::MockGLInterface* gl,
     bool is_es3_enabled,
     bool is_es3_capable,
-    bool is_desktop_core_profile,
     const gfx::ExtensionSet& extensions,
     bool use_default_textures) {
   InSequence sequence;
@@ -231,7 +230,6 @@
   bool ext_image_external =
       gfx::HasExtension(extensions, "GL_OES_EGL_image_external");
   bool arb_texture_rectangle =
-      is_desktop_core_profile ||
       gfx::HasExtension(extensions, "GL_ARB_texture_rectangle");
 
   if (ext_image_external) {
@@ -283,7 +281,6 @@
 void TestHelper::SetupTextureManagerDestructionExpectations(
     ::gl::MockGLInterface* gl,
     bool is_es3_enabled,
-    bool is_desktop_core_profile,
     const gfx::ExtensionSet& extensions,
     bool use_default_textures) {
   SetupTextureDestructionExpectations(gl, GL_TEXTURE_2D, use_default_textures);
@@ -300,14 +297,13 @@
   bool ext_image_external =
       gfx::HasExtension(extensions, "GL_OES_EGL_image_external");
   bool arb_texture_rectangle =
-      is_desktop_core_profile ||
       gfx::HasExtension(extensions, "GL_ARB_texture_rectangle");
 
   if (ext_image_external) {
     SetupTextureDestructionExpectations(
         gl, GL_TEXTURE_EXTERNAL_OES, use_default_textures);
   }
-  if (arb_texture_rectangle || is_desktop_core_profile) {
+  if (arb_texture_rectangle) {
     SetupTextureDestructionExpectations(
         gl, GL_TEXTURE_RECTANGLE_ARB, use_default_textures);
   }
@@ -341,7 +337,7 @@
       gfx::HasExtension(extension_set, "GL_EXT_framebuffer_multisample") ||
       gfx::HasExtension(extension_set,
                         "GL_EXT_multisampled_render_to_texture") ||
-      gl_info.is_es3 || gl_info.is_desktop_core_profile) {
+      gl_info.is_es3) {
     EXPECT_CALL(*gl, GetIntegerv(GL_MAX_SAMPLES, _))
         .WillOnce(SetArgPointee<1>(kMaxSamples))
         .RetiresOnSaturation();
@@ -354,8 +350,7 @@
 
   if (enable_es3 ||
       (!enable_es3 &&
-       (gl_info.is_desktop_core_profile ||
-        gfx::HasExtension(extension_set, "GL_EXT_draw_buffers") ||
+       (gfx::HasExtension(extension_set, "GL_EXT_draw_buffers") ||
         gfx::HasExtension(extension_set, "GL_ARB_draw_buffers") ||
         (gl_info.is_es3 &&
          gfx::HasExtension(extension_set, "GL_NV_draw_buffers"))))) {
@@ -411,8 +406,7 @@
         .WillOnce(SetArgPointee<1>(kMaxArrayTextureLayers))
         .RetiresOnSaturation();
   }
-  if (gfx::HasExtension(extension_set, "GL_ARB_texture_rectangle") ||
-      gl_info.is_desktop_core_profile) {
+  if (gfx::HasExtension(extension_set, "GL_ARB_texture_rectangle")) {
     EXPECT_CALL(*gl, GetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE, _))
         .WillOnce(SetArgPointee<1>(kMaxRectangleTextureSize))
         .RetiresOnSaturation();
@@ -424,7 +418,7 @@
       .WillOnce(SetArgPointee<1>(kMaxVertexTextureImageUnits))
       .RetiresOnSaturation();
 
-  if (gl_info.is_es || gl_info.is_desktop_core_profile) {
+  if (gl_info.is_es) {
     EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, _))
         .WillOnce(SetArgPointee<1>(kMaxFragmentUniformVectors))
         .RetiresOnSaturation();
@@ -465,7 +459,6 @@
 
   bool use_default_textures = bind_generates_resource;
   SetupTextureManagerInitExpectations(gl, enable_es3, gl_info.is_es3_capable,
-                                      gl_info.is_desktop_core_profile,
                                       extension_set, use_default_textures);
 }
 
@@ -522,7 +515,7 @@
       .WillOnce(Return(reinterpret_cast<const uint8_t*>(gl_renderer)))
       .RetiresOnSaturation();
 
-  if (gl_info.is_es3 || gl_info.is_desktop_core_profile ||
+  if (gl_info.is_es3 ||
       gfx::HasExtension(extension_set, "GL_ARB_pixel_buffer_object") ||
       gfx::HasExtension(extension_set, "GL_NV_pixel_buffer_object")) {
     EXPECT_CALL(*gl, GetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, _))
@@ -530,8 +523,7 @@
       .RetiresOnSaturation();
   }
 
-  if ((gfx::HasExtension(extension_set, "GL_ARB_texture_float") ||
-       gl_info.is_desktop_core_profile) ||
+  if (gfx::HasExtension(extension_set, "GL_ARB_texture_float") ||
       (gl_info.is_es3 &&
        gfx::HasExtension(extension_set, "GL_OES_texture_float") &&
        gfx::HasExtension(extension_set, "GL_EXT_color_buffer_float"))) {
@@ -663,8 +655,7 @@
 
   if (enable_es3 ||
       (!enable_es3 &&
-       (gl_info.is_desktop_core_profile ||
-        gfx::HasExtension(extension_set, "GL_EXT_draw_buffers") ||
+       (gfx::HasExtension(extension_set, "GL_EXT_draw_buffers") ||
         gfx::HasExtension(extension_set, "GL_ARB_draw_buffers") ||
         (gl_info.is_es3 &&
          gfx::HasExtension(extension_set, "GL_NV_draw_buffers"))))) {
@@ -680,8 +671,7 @@
   // skipped universally on macOS, and by default (with a Finch
   // kill-switch) on Android.
 #if !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_ANDROID)
-  if (gl_info.is_es3 || gl_info.is_desktop_core_profile ||
-      gfx::HasExtension(extension_set, "GL_EXT_texture_rg") ||
+  if (gl_info.is_es3 || gfx::HasExtension(extension_set, "GL_EXT_texture_rg") ||
       (gfx::HasExtension(extension_set, "GL_ARB_texture_rg"))) {
 #if DCHECK_IS_ON()
     EXPECT_CALL(*gl, GetError())
diff --git a/gpu/command_buffer/service/test_helper.h b/gpu/command_buffer/service/test_helper.h
index 03a2c54..956e0d6e 100644
--- a/gpu/command_buffer/service/test_helper.h
+++ b/gpu/command_buffer/service/test_helper.h
@@ -121,13 +121,11 @@
       ::gl::MockGLInterface* gl,
       bool is_es3_enabled,
       bool is_es3_capable,
-      bool is_desktop_core_profile,
       const gfx::ExtensionSet& extensions,
       bool use_default_textures);
   static void SetupTextureManagerDestructionExpectations(
       ::gl::MockGLInterface* gl,
       bool is_es3_enabled,
-      bool is_desktop_core_profile,
       const gfx::ExtensionSet& extensions,
       bool use_default_textures);
 
diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc
index 5fed11c..4a06c1d 100644
--- a/gpu/command_buffer/service/texture_manager_unittest.cc
+++ b/gpu/command_buffer/service/texture_manager_unittest.cc
@@ -84,8 +84,8 @@
         kMaxRectangleTextureSize, kMax3DTextureSize, kMaxArrayTextureLayers,
         kUseDefaultTextures, nullptr, &discardable_manager_));
     SetupFeatureInfo("", "OpenGL ES 2.0", CONTEXT_TYPE_OPENGLES2);
-    TestHelper::SetupTextureManagerInitExpectations(
-        gl_.get(), false, false, false, {}, kUseDefaultTextures);
+    TestHelper::SetupTextureManagerInitExpectations(gl_.get(), false, false, {},
+                                                    kUseDefaultTextures);
     manager_->Initialize();
     error_state_.reset(new ::testing::StrictMock<MockErrorState>());
   }
@@ -208,9 +208,9 @@
 
 TEST_F(TextureManagerTest, UseDefaultTexturesTrue) {
   bool use_default_textures = true;
-  TestHelper::SetupTextureManagerInitExpectations(
-      gl_.get(), false, false, false, {"GL_ANGLE_texture_usage"},
-      use_default_textures);
+  TestHelper::SetupTextureManagerInitExpectations(gl_.get(), false, false,
+                                                  {"GL_ANGLE_texture_usage"},
+                                                  use_default_textures);
   TextureManager manager(nullptr, feature_info_.get(), kMaxTextureSize,
                          kMaxCubeMapTextureSize, kMaxRectangleTextureSize,
                          kMax3DTextureSize, kMaxArrayTextureLayers,
@@ -228,9 +228,9 @@
 
 TEST_F(TextureManagerTest, UseDefaultTexturesFalse) {
   bool use_default_textures = false;
-  TestHelper::SetupTextureManagerInitExpectations(
-      gl_.get(), false, false, false, {"GL_ANGLE_texture_usage"},
-      use_default_textures);
+  TestHelper::SetupTextureManagerInitExpectations(gl_.get(), false, false,
+                                                  {"GL_ANGLE_texture_usage"},
+                                                  use_default_textures);
   TextureManager manager(nullptr, feature_info_.get(), kMaxTextureSize,
                          kMaxCubeMapTextureSize, kMaxRectangleTextureSize,
                          kMax3DTextureSize, kMaxArrayTextureLayers,
@@ -249,8 +249,8 @@
 TEST_F(TextureManagerTest, UseDefaultTexturesTrueES3) {
   bool use_default_textures = true;
   SetupFeatureInfo("", "OpenGL ES 3.0", CONTEXT_TYPE_OPENGLES3);
-  TestHelper::SetupTextureManagerInitExpectations(gl_.get(), true, true, false,
-                                                  {}, use_default_textures);
+  TestHelper::SetupTextureManagerInitExpectations(gl_.get(), true, true, {},
+                                                  use_default_textures);
   TextureManager manager(nullptr, feature_info_.get(), kMaxTextureSize,
                          kMaxCubeMapTextureSize, kMaxRectangleTextureSize,
                          kMax3DTextureSize, kMaxArrayTextureLayers,
@@ -267,8 +267,8 @@
 TEST_F(TextureManagerTest, UseDefaultTexturesFalseES3) {
   bool use_default_textures = false;
   SetupFeatureInfo("", "OpenGL ES 3.0", CONTEXT_TYPE_OPENGLES3);
-  TestHelper::SetupTextureManagerInitExpectations(gl_.get(), true, true, false,
-                                                  {}, use_default_textures);
+  TestHelper::SetupTextureManagerInitExpectations(gl_.get(), true, true, {},
+                                                  use_default_textures);
   TextureManager manager(nullptr, feature_info_.get(), kMaxTextureSize,
                          kMaxCubeMapTextureSize, kMaxRectangleTextureSize,
                          kMax3DTextureSize, kMaxArrayTextureLayers,
@@ -284,8 +284,7 @@
 
 TEST_F(TextureManagerTest, TextureUsageExt) {
   TestHelper::SetupTextureManagerInitExpectations(
-      gl_.get(), false, false, false, {"GL_ANGLE_texture_usage"},
-      kUseDefaultTextures);
+      gl_.get(), false, false, {"GL_ANGLE_texture_usage"}, kUseDefaultTextures);
   TextureManager manager(nullptr, feature_info_.get(), kMaxTextureSize,
                          kMaxCubeMapTextureSize, kMaxRectangleTextureSize,
                          kMax3DTextureSize, kMaxArrayTextureLayers,
@@ -310,8 +309,8 @@
 TEST_F(TextureManagerTest, Destroy) {
   const GLuint kClient1Id = 1;
   const GLuint kService1Id = 11;
-  TestHelper::SetupTextureManagerInitExpectations(
-      gl_.get(), false, false, false, {}, kUseDefaultTextures);
+  TestHelper::SetupTextureManagerInitExpectations(gl_.get(), false, false, {},
+                                                  kUseDefaultTextures);
   TextureManager manager(nullptr, feature_info_.get(), kMaxTextureSize,
                          kMaxCubeMapTextureSize, kMaxRectangleTextureSize,
                          kMax3DTextureSize, kMaxArrayTextureLayers,
@@ -325,8 +324,8 @@
   EXPECT_CALL(*gl_, DeleteTextures(1, ::testing::Pointee(kService1Id)))
       .Times(1)
       .RetiresOnSaturation();
-  TestHelper::SetupTextureManagerDestructionExpectations(
-      gl_.get(), false, false, {}, kUseDefaultTextures);
+  TestHelper::SetupTextureManagerDestructionExpectations(gl_.get(), false, {},
+                                                         kUseDefaultTextures);
   manager.Destroy();
   // Check that resources got freed.
   texture = manager.GetTexture(kClient1Id);
@@ -488,8 +487,8 @@
   const GLuint kServiceId = 11;
 
   SetupFeatureInfo("", "2.1", CONTEXT_TYPE_OPENGLES2);
-  TestHelper::SetupTextureManagerInitExpectations(
-      gl_.get(), false, false, false, {}, kUseDefaultTextures);
+  TestHelper::SetupTextureManagerInitExpectations(gl_.get(), false, false, {},
+                                                  kUseDefaultTextures);
   TextureManager manager(nullptr, feature_info_.get(), kMaxTextureSize,
                          kMaxCubeMapTextureSize, kMaxRectangleTextureSize,
                          kMax3DTextureSize, kMaxArrayTextureLayers,
@@ -524,103 +523,6 @@
   manager.RemoveTexture(kClientId);
 }
 
-TEST_F(TextureManagerTest, AlphaLuminanceCoreProfileEmulation) {
-  const GLuint kClientId = 1;
-  const GLuint kServiceId = 11;
-
-  SetupFeatureInfo("", "4.2", CONTEXT_TYPE_OPENGLES3);
-  TestHelper::SetupTextureManagerInitExpectations(gl_.get(), true, true, true,
-                                                  {}, kUseDefaultTextures);
-  TextureManager manager(nullptr, feature_info_.get(), kMaxTextureSize,
-                         kMaxCubeMapTextureSize, kMaxRectangleTextureSize,
-                         kMax3DTextureSize, kMaxArrayTextureLayers,
-                         kUseDefaultTextures, nullptr, &discardable_manager_);
-  manager.Initialize();
-
-  // Create a texture.
-  manager.CreateTexture(kClientId, kServiceId);
-  scoped_refptr<TextureRef> texture_ref(manager.GetTexture(kClientId));
-  manager.SetTarget(texture_ref.get(), GL_TEXTURE_2D);
-
-  Texture* texture = texture_ref->texture();
-
-  // GL_ALPHA emulation
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_NONE))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_NONE))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_NONE))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED))
-      .Times(1)
-      .RetiresOnSaturation();
-
-  manager.SetLevelInfo(texture_ref.get(), GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 1,
-      0, GL_ALPHA, GL_UNSIGNED_BYTE, gfx::Rect(1, 1));
-  texture->ApplyFormatWorkarounds(feature_info_.get());
-
-  // GL_LUMINANCE emulation
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE))
-      .Times(1)
-      .RetiresOnSaturation();
-
-  manager.SetLevelInfo(texture_ref.get(), GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1,
-      1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, gfx::Rect(1, 1));
-  texture->ApplyFormatWorkarounds(feature_info_.get());
-
-  // GL_LUMINANCE_ALPHA emulation
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A,
-              GL_GREEN))
-      .Times(1)
-      .RetiresOnSaturation();
-
-  manager.SetLevelInfo(texture_ref.get(), GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA,
-      1, 1, 1, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, gfx::Rect(1, 1));
-  texture->ApplyFormatWorkarounds(feature_info_.get());
-
-  // Ensure explicitly setting swizzles while using emulated settings properly
-  // swizzles the swizzle.
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R,
-              GL_GREEN))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A,
-              GL_RED))
-      .Times(1)
-      .RetiresOnSaturation();
-
-  manager.SetParameteri("TexParameteri", error_state_.get(), texture_ref.get(),
-      GL_TEXTURE_SWIZZLE_R, GL_ALPHA);
-  manager.SetParameteri("TexParameteri", error_state_.get(), texture_ref.get(),
-      GL_TEXTURE_SWIZZLE_A, GL_GREEN);
-
-  EXPECT_CALL(*gl_, DeleteTextures(1, ::testing::Pointee(kServiceId)))
-      .Times(1)
-      .RetiresOnSaturation();
-  manager.RemoveTexture(kClientId);
-}
-
 class TextureTestBase : public GpuServiceTest {
  public:
   static const GLint kMaxTextureSize = 32;
@@ -2117,11 +2019,11 @@
         TextureManagerTest::kMaxArrayTextureLayers, kUseDefaultTextures,
         nullptr, &discardable_manager_));
     SetupFeatureInfo("", "OpenGL ES 2.0", CONTEXT_TYPE_OPENGLES2);
-    TestHelper::SetupTextureManagerInitExpectations(
-        gl_.get(), false, false, false, {}, kUseDefaultTextures);
+    TestHelper::SetupTextureManagerInitExpectations(gl_.get(), false, false, {},
+                                                    kUseDefaultTextures);
     texture_manager1_->Initialize();
-    TestHelper::SetupTextureManagerInitExpectations(
-        gl_.get(), false, false, false, {}, kUseDefaultTextures);
+    TestHelper::SetupTextureManagerInitExpectations(gl_.get(), false, false, {},
+                                                    kUseDefaultTextures);
     texture_manager2_->Initialize();
   }
 
diff --git a/gpu/command_buffer/service/webgpu_decoder_impl.cc b/gpu/command_buffer/service/webgpu_decoder_impl.cc
index 20f89da..85ae815 100644
--- a/gpu/command_buffer/service/webgpu_decoder_impl.cc
+++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -1978,6 +1978,13 @@
   }
 #endif
 
+  if ((usage & kAllowedWritableMailboxTextureUsages) &&
+      (!(shared_image->usage() & SHARED_IMAGE_USAGE_WEBGPU_WRITE))) {
+    LOG(ERROR) << "AssociateMailbox: Passing writable usages requires "
+                  "WebGPU write access to the SharedImage";
+    return nullptr;
+  }
+
   if ((internal_usage & kAllowedWritableMailboxTextureUsages) &&
       (!(shared_image->usage() & SHARED_IMAGE_USAGE_WEBGPU_WRITE))) {
     LOG(ERROR) << "AssociateMailbox: Passing writable internal usages requires "
@@ -2058,6 +2065,13 @@
     return nullptr;
   }
 
+  if ((usage & kAllowedWritableMailboxTextureUsages) &&
+      (!(shared_image->usage() & SHARED_IMAGE_USAGE_WEBGPU_WRITE))) {
+    LOG(ERROR) << "AssociateMailbox: Passing writable usages requires "
+                  "WebGPU write access to the SharedImage";
+    return nullptr;
+  }
+
   if ((internal_usage & kAllowedWritableMailboxTextureUsages) &&
       (!(shared_image->usage() & SHARED_IMAGE_USAGE_WEBGPU_WRITE))) {
     LOG(ERROR) << "AssociateMailbox: Passing writable internal usages requires "
diff --git a/gpu/command_buffer/tests/command_buffer_gles2_tests_main.cc b/gpu/command_buffer/tests/command_buffer_gles2_tests_main.cc
deleted file mode 100644
index d22a307f..0000000
--- a/gpu/command_buffer/tests/command_buffer_gles2_tests_main.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/functional/bind.h"
-#include "base/message_loop/message_pump_type.h"
-#include "base/task/single_thread_task_executor.h"
-#include "build/build_config.h"
-#if BUILDFLAG(IS_MAC)
-#include "base/apple/scoped_nsautorelease_pool.h"
-#endif
-#include "base/test/launcher/unit_test_launcher.h"
-#include "base/test/test_suite.h"
-#include "gpu/gles2_conform_support/egl/test_support.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-// This file implements the main entry point for tests for command_buffer_gles2,
-// the mode of command buffer where the code is compiled as a standalone dynamic
-// library and exposed through EGL API.
-namespace {
-
-int RunHelper(base::TestSuite* testSuite) {
-  base::MessagePumpType pump_type = base::MessagePumpType::IO;
-#if BUILDFLAG(IS_OZONE)
-  pump_type = base::MessagePumpType::UI;
-#endif
-  base::SingleThreadTaskExecutor executor(pump_type);
-  return testSuite->Run();
-}
-
-}  // namespace
-
-int main(int argc, char** argv) {
-// NOTE: we initialize globals through TestSuite constructor or through JNI
-// library registration process on Android.
-
-// However, when the system is compiled with component build,
-// command_buffer_gles2 library and this test runner share the globals, such
-// as AtExitManager and JVM references.  When command_buffer_gles2 is run with
-// the test runner, the globals may be populated.  Any other app linking to
-// command_buffer_gles2 of course can not provide the globals.
-
-// When the system is compiled without component build, command_buffer_gles2
-// gets its own globals, while the test runner gets its own. The runner
-// initialize different global variables than the ones command_buffer_gles2
-// library uses. For example, there should be a global AtExitManager for the
-// test runner, and there should be a global AtExitManager that the library
-// uses. Similarly, if the test runner would use JNI, it should have global
-// reference to the JNI environent. If the command_buffer_gles2 library would
-// use JNI, it should have its own global reference to the JNI that always
-// remains null. The reference of the library should always stay null, since
-// JNI is not part of command_buffer_gles2 exported API (EGL API), and thus
-// there is no way for the client of the library to populate the JNI
-// pointer. The client may not even be a Java app.
-
-// We signify that the globals have been initialized when running
-// the component build.
-#if defined(COMPONENT_BUILD)
-  g_command_buffer_gles_has_atexit_manager = true;
-#endif
-
-  base::TestSuite test_suite(argc, argv);
-#if BUILDFLAG(IS_MAC)
-  base::apple::ScopedNSAutoreleasePool pool;
-#endif
-  testing::InitGoogleMock(&argc, argv);
-  return base::LaunchUnitTestsSerially(
-      argc, argv, base::BindOnce(&RunHelper, base::Unretained(&test_suite)));
-}
diff --git a/gpu/command_buffer/tests/egl_test.cc b/gpu/command_buffer/tests/egl_test.cc
deleted file mode 100644
index a6283dc..0000000
--- a/gpu/command_buffer/tests/egl_test.cc
+++ /dev/null
@@ -1,636 +0,0 @@
-// Copyright 2015 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#include <EGL/egl.h>
-#include <GLES2/gl2.h>
-
-#include "base/functional/bind.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread.h"
-#include "build/build_config.h"
-#include "gpu/gles2_conform_support/egl/test_support.h"
-
-// This file tests EGL basic interface for command_buffer_gles2, the mode of
-// command buffer where the code is compiled as a standalone dynamic library and
-// exposed through EGL API.
-namespace gpu {
-
-class EGLTest : public testing::Test {
- public:
-  void TearDown() override;
-};
-
-void EGLTest::TearDown() {
-  EXPECT_TRUE(eglReleaseThread());
-}
-
-TEST_F(EGLTest, OnlyReleaseThread) {}
-
-TEST_F(EGLTest, GetDisplay) {
-  EGLDisplay display1 = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  EXPECT_NE(display1, EGL_NO_DISPLAY);
-
-  EGLDisplay display2 = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  EXPECT_EQ(display1, display2);
-
-#if BUILDFLAG(IS_OZONE)
-  EGLNativeDisplayType invalid_display_type =
-      static_cast<EGLNativeDisplayType>(0x1);
-#else
-  EGLNativeDisplayType invalid_display_type =
-      reinterpret_cast<EGLNativeDisplayType>(0x1);
-#endif
-  EXPECT_NE(invalid_display_type, EGL_DEFAULT_DISPLAY);
-  EXPECT_EQ(EGL_NO_DISPLAY, eglGetDisplay(invalid_display_type));
-  EXPECT_EQ(EGL_SUCCESS, eglGetError());
-
-  // eglTerminate can be called with uninitialized display.
-  EXPECT_TRUE(eglTerminate(display1));
-}
-
-TEST_F(EGLTest, GetError) {
-  // GetError returns success.
-  EXPECT_EQ(EGL_SUCCESS, eglGetError());
-
-  // "calling eglGetError twice without any other intervening EGL calls will
-  // always return EGL_SUCCESS on the second call"
-  EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  EXPECT_NE(display, EGL_NO_DISPLAY);
-  EXPECT_EQ(EGL_SUCCESS, eglGetError());
-  EXPECT_EQ(nullptr, eglQueryString(display, EGL_EXTENSIONS));
-  EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError());
-  EXPECT_EQ(EGL_SUCCESS, eglGetError());
-
-  EXPECT_TRUE(eglTerminate(display));
-  EXPECT_EQ(EGL_SUCCESS, eglGetError());
-}
-
-TEST_F(EGLTest, Initialize) {
-  EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  EXPECT_NE(display, EGL_NO_DISPLAY);
-
-  // Test for no crash even though passing nullptrs for major, minor.
-  EXPECT_TRUE(eglInitialize(display, nullptr, nullptr));
-
-  EGLint major = 0;
-  EGLint minor = 0;
-  EXPECT_TRUE(eglInitialize(display, &major, &minor));
-  EXPECT_EQ(major, 1);
-  EXPECT_EQ(minor, 4);
-
-  EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1);
-  EXPECT_FALSE(eglInitialize(invalid_display, nullptr, nullptr));
-  EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError());
-}
-
-TEST_F(EGLTest, Terminate) {
-  EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  EXPECT_NE(display, EGL_NO_DISPLAY);
-
-  // eglTerminate can be called multiple times without initialization.
-  EXPECT_TRUE(eglTerminate(display));
-  EXPECT_EQ(EGL_SUCCESS, eglGetError());
-  EXPECT_TRUE(eglTerminate(display));
-  EXPECT_EQ(EGL_SUCCESS, eglGetError());
-
-  EXPECT_TRUE(eglInitialize(display, nullptr, nullptr));
-
-  // eglTerminate can be called multiple times.
-  EXPECT_TRUE(eglTerminate(display));
-  EXPECT_EQ(EGL_SUCCESS, eglGetError());
-  EXPECT_TRUE(eglTerminate(display));
-  EXPECT_EQ(EGL_SUCCESS, eglGetError());
-
-  // After Terminate, an egl call returns not initialized.
-  EXPECT_EQ(nullptr, eglQueryString(display, EGL_EXTENSIONS));
-  EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError());
-
-  // Re-initialization of same display.
-  EXPECT_TRUE(eglInitialize(display, nullptr, nullptr));
-  EXPECT_NE(nullptr, eglQueryString(display, EGL_EXTENSIONS));
-  EXPECT_TRUE(eglTerminate(display));
-
-  EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1);
-  EXPECT_FALSE(eglTerminate(invalid_display));
-  EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError());
-}
-
-TEST_F(EGLTest, QueryString) {
-  EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  EXPECT_NE(display, EGL_NO_DISPLAY);
-  EXPECT_EQ(nullptr, eglQueryString(display, EGL_EXTENSIONS));
-  EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError());
-  EXPECT_STREQ("", eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS));
-
-  EXPECT_EQ(nullptr, eglQueryString(display, EGL_VERSION));
-  EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError());
-  EXPECT_STREQ("1.4", eglQueryString(EGL_NO_DISPLAY, EGL_VERSION));
-
-  EXPECT_EQ(nullptr, eglQueryString(display, EGL_CLIENT_APIS));
-  EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError());
-  EXPECT_EQ(nullptr, eglQueryString(EGL_NO_DISPLAY, EGL_CLIENT_APIS));
-  EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError());
-  EXPECT_EQ(nullptr, eglQueryString(display, EGL_VENDOR));
-  EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError());
-  EXPECT_EQ(nullptr, eglQueryString(EGL_NO_DISPLAY, EGL_VENDOR));
-  EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError());
-
-  EXPECT_TRUE(eglInitialize(display, nullptr, nullptr));
-  EXPECT_EQ(EGL_SUCCESS, eglGetError());
-
-  EXPECT_STREQ("", eglQueryString(display, EGL_EXTENSIONS));
-  EXPECT_EQ(EGL_SUCCESS, eglGetError());
-  EXPECT_STREQ("1.4", eglQueryString(display, EGL_VERSION));
-  EXPECT_EQ(EGL_SUCCESS, eglGetError());
-  EXPECT_STREQ("OpenGL_ES", eglQueryString(display, EGL_CLIENT_APIS));
-  EXPECT_EQ(EGL_SUCCESS, eglGetError());
-  EXPECT_STREQ("Google Inc.", eglQueryString(display, EGL_VENDOR));
-  EXPECT_EQ(EGL_SUCCESS, eglGetError());
-}
-
-TEST_F(EGLTest, GetConfigsUninitialized) {
-  EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  EXPECT_NE(display, EGL_NO_DISPLAY);
-
-  EGLint num_config = 0;
-  const int kConfigsSize = 5;
-  EGLConfig configs[kConfigsSize] = {
-      0,
-  };
-
-  EXPECT_FALSE(eglGetConfigs(display, configs, kConfigsSize, &num_config));
-  EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError());
-
-  EXPECT_FALSE(eglGetConfigs(display, configs, kConfigsSize, nullptr));
-  EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError());
-}
-
-TEST_F(EGLTest, ChooseConfigUninitialized) {
-  EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  EXPECT_NE(display, EGL_NO_DISPLAY);
-
-  EGLint num_config = 0;
-  EGLint attrib_list[] = {EGL_NONE};
-  const int kConfigsSize = 5;
-  EGLConfig configs[kConfigsSize] = {
-      0,
-  };
-
-  EXPECT_FALSE(eglChooseConfig(display, attrib_list, configs, kConfigsSize,
-                               &num_config));
-  EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError());
-
-  EXPECT_FALSE(
-      eglChooseConfig(display, attrib_list, configs, kConfigsSize, nullptr));
-  EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError());
-}
-
-class EGLConfigTest : public EGLTest {
- public:
-  void SetUp() override;
-
- protected:
-  void CheckConfigsExist(EGLint num_config);
-
-  enum { kConfigsSize = 5 };
-  EGLDisplay display_;
-  EGLConfig configs_[kConfigsSize];
-};
-
-void EGLConfigTest::SetUp() {
-  display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  ASSERT_NE(display_, EGL_NO_DISPLAY);
-  EXPECT_TRUE(eglInitialize(display_, nullptr, nullptr));
-  memset(configs_, 0, sizeof(configs_));
-}
-
-void EGLConfigTest::CheckConfigsExist(EGLint num_config) {
-  EGLint i;
-  if (num_config > kConfigsSize)
-    num_config = static_cast<EGLint>(kConfigsSize);
-  for (i = 0; i < num_config; ++i)
-    EXPECT_NE(nullptr, configs_[i]);
-  for (; i < kConfigsSize; ++i)
-    EXPECT_EQ(nullptr, configs_[i]);
-}
-
-TEST_F(EGLConfigTest, GetConfigsBadNumConfigs) {
-  EXPECT_FALSE(eglGetConfigs(display_, configs_, kConfigsSize, nullptr));
-  EXPECT_EQ(EGL_BAD_PARAMETER, eglGetError());
-}
-
-TEST_F(EGLConfigTest, GetConfigsNullConfigs) {
-  EGLint num_config = 0;
-  EXPECT_TRUE(eglGetConfigs(display_, nullptr, 55, &num_config));
-  EXPECT_GT(num_config, 0);
-}
-
-TEST_F(EGLConfigTest, GetConfigsZeroConfigsSize) {
-  EGLint num_config = 0;
-  EXPECT_TRUE(eglGetConfigs(display_, configs_, 0, &num_config));
-  EXPECT_GT(num_config, 0);
-  EXPECT_EQ(nullptr, configs_[0]);
-}
-
-TEST_F(EGLConfigTest, GetConfigs) {
-  EGLint num_config = 0;
-  EXPECT_TRUE(eglGetConfigs(display_, configs_, kConfigsSize, &num_config));
-  EXPECT_GT(num_config, 0);
-  CheckConfigsExist(num_config);
-}
-
-TEST_F(EGLConfigTest, ChooseConfigBadNumConfigs) {
-  EGLint attrib_list[] = {EGL_NONE};
-  EXPECT_FALSE(
-      eglChooseConfig(display_, attrib_list, configs_, kConfigsSize, nullptr));
-  EXPECT_EQ(EGL_BAD_PARAMETER, eglGetError());
-}
-
-TEST_F(EGLConfigTest, ChooseConfigNullConfigs) {
-  EGLint num_config = 0;
-  EGLint attrib_list[] = {EGL_NONE};
-  EXPECT_TRUE(eglChooseConfig(display_, attrib_list, nullptr, 55, &num_config));
-  EXPECT_GT(num_config, 0);
-}
-
-TEST_F(EGLConfigTest, ChooseConfigZeroConfigsSize) {
-  EGLint num_config = 0;
-  EGLint attrib_list[] = {EGL_NONE};
-  EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, 0, &num_config));
-  EXPECT_GT(num_config, 0);
-  EXPECT_EQ(nullptr, configs_[0]);
-}
-
-TEST_F(EGLConfigTest, ChooseConfig) {
-  EGLint num_config = 0;
-  EGLint attrib_list[] = {EGL_NONE};
-  EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, kConfigsSize,
-                              &num_config));
-  EXPECT_GT(num_config, 0);
-  CheckConfigsExist(num_config);
-}
-
-TEST_F(EGLConfigTest, ChooseConfigInvalidAttrib) {
-  const EGLint kNotModified = 55;
-  EGLint num_config = kNotModified;
-  EGLint invalid_attrib_list[] = {0xABCD};
-  EXPECT_FALSE(eglChooseConfig(display_, invalid_attrib_list, configs_,
-                               kConfigsSize, &num_config));
-  EXPECT_EQ(EGL_BAD_ATTRIBUTE, eglGetError());
-  EXPECT_EQ(kNotModified, num_config);
-}
-
-TEST_F(EGLConfigTest, ChooseConfigWindow) {
-  EGLint num_config = 0;
-  EGLint attrib_list[] = {EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE};
-  EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, kConfigsSize,
-                              &num_config));
-  EXPECT_GT(num_config, 0);
-  for (int i = 0; i < num_config; ++i) {
-    EGLint value = EGL_NONE;
-    eglGetConfigAttrib(display_, configs_[i], EGL_SURFACE_TYPE, &value);
-    EXPECT_NE(0, value & EGL_WINDOW_BIT);
-  }
-}
-
-TEST_F(EGLConfigTest, ChooseConfigPBuffer) {
-  EGLint num_config = 0;
-  EGLint attrib_list[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_NONE};
-  EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, kConfigsSize,
-                              &num_config));
-  EXPECT_GT(num_config, 0);
-  for (int i = 0; i < num_config; ++i) {
-    EGLint value = EGL_NONE;
-    eglGetConfigAttrib(display_, configs_[0], EGL_SURFACE_TYPE, &value);
-    EXPECT_NE(0, value & EGL_PBUFFER_BIT);
-  }
-}
-
-TEST_F(EGLConfigTest, ChooseConfigWindowPBufferNotPossible) {
-  EGLint num_config = 0;
-  EGLint attrib_list[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
-                          EGL_NONE};
-  EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, kConfigsSize,
-                              &num_config));
-  EXPECT_EQ(0, num_config);
-}
-
-TEST_F(EGLConfigTest, ChooseConfigBugExample) {
-  static const EGLint kConfigAttribs[] = {
-      EGL_RED_SIZE,       8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE,    8,
-      EGL_ALPHA_SIZE,     8, EGL_DEPTH_SIZE, 8, EGL_STENCIL_SIZE, 8,
-      EGL_SAMPLE_BUFFERS, 1, EGL_SAMPLES,    4, EGL_NONE};
-  EGLint num_config = 0;
-  EXPECT_TRUE(eglChooseConfig(display_, kConfigAttribs, configs_, kConfigsSize,
-                              &num_config));
-
-  // The EGL attribs are not really implemented at the moment.
-  EGLint value = EGL_NONE;
-  EXPECT_TRUE(eglGetConfigAttrib(display_, configs_[0], EGL_RED_SIZE, &value));
-  EXPECT_EQ(0, value);
-}
-
-TEST_F(EGLTest, MakeCurrent) {
-  EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  EXPECT_NE(display, EGL_NO_DISPLAY);
-  // "This is the only case where an uninitialized display may be passed to
-  //  eglMakeCurrent."
-  EXPECT_TRUE(
-      eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
-  EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1);
-  EXPECT_FALSE(eglMakeCurrent(invalid_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
-                              EGL_NO_CONTEXT));
-  EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError());
-
-  EXPECT_TRUE(eglInitialize(display, nullptr, nullptr));
-  EXPECT_TRUE(
-      eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
-  EXPECT_FALSE(eglMakeCurrent(invalid_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
-                              EGL_NO_CONTEXT));
-}
-
-class EGLSurfaceTest : public EGLTest {
- public:
-  void SetUp() override;
-  void CreateSurfaceAndContext(EGLSurface* surface, EGLContext* context);
-
- protected:
-  EGLDisplay display_;
-};
-
-void EGLSurfaceTest::SetUp() {
-  EGLTest::SetUp();
-  display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  EXPECT_TRUE(eglInitialize(display_, nullptr, nullptr));
-}
-
-void EGLSurfaceTest::CreateSurfaceAndContext(EGLSurface* surface,
-                                             EGLContext* context) {
-  static const EGLint config_attribs[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
-                                          EGL_NONE};
-  EGLint num_config;
-  EGLConfig config;
-  EXPECT_TRUE(
-      eglChooseConfig(display_, config_attribs, &config, 1, &num_config));
-  ASSERT_GT(num_config, 0);
-  static const EGLint surface_attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1,
-                                           EGL_NONE};
-  *surface = eglCreatePbufferSurface(display_, config, surface_attribs);
-  static const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2,
-                                           EGL_NONE};
-  *context = eglCreateContext(display_, config, nullptr, context_attribs);
-}
-
-class EGLMultipleSurfacesContextsTest : public EGLSurfaceTest {
- public:
-  void SetUp() override;
-  void TearDown() override;
-
- protected:
-  EGLSurface surface1_;
-  EGLSurface surface2_;
-  EGLContext context1_;
-  EGLContext context2_;
-};
-
-void EGLMultipleSurfacesContextsTest::SetUp() {
-  EGLSurfaceTest::SetUp();
-  CreateSurfaceAndContext(&surface1_, &context1_);
-  CreateSurfaceAndContext(&surface2_, &context2_);
-  EXPECT_NE(EGL_NO_SURFACE, surface1_);
-  EXPECT_NE(EGL_NO_SURFACE, surface2_);
-  EXPECT_NE(surface1_, surface2_);
-  EXPECT_NE(EGL_NO_CONTEXT, context1_);
-  EXPECT_NE(EGL_NO_CONTEXT, context2_);
-  EXPECT_NE(context1_, context2_);
-}
-
-void EGLMultipleSurfacesContextsTest::TearDown() {
-  EXPECT_TRUE(eglDestroyContext(display_, context1_));
-  EXPECT_TRUE(eglDestroySurface(display_, surface1_));
-  EXPECT_TRUE(eglDestroyContext(display_, context2_));
-  EXPECT_TRUE(eglDestroySurface(display_, surface2_));
-  EGLTest::TearDown();
-}
-
-TEST_F(EGLMultipleSurfacesContextsTest, NoMakeCurrent) {}
-
-TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSurfaces) {
-  EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_));
-  EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_));
-  EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context2_));
-  EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context1_));
-}
-
-TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSameSurface1) {
-  EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_));
-  EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context2_));
-}
-
-TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSameSurface2) {
-  EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_));
-  EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context1_));
-  EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_));
-}
-
-TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSurfacesAndReleases) {
-  EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_));
-  EXPECT_TRUE(
-      eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
-  EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_));
-  EXPECT_TRUE(
-      eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
-  EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context2_));
-  EXPECT_TRUE(
-      eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
-  EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context1_));
-  EXPECT_TRUE(
-      eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
-}
-
-TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSurfaceFails) {
-  EXPECT_FALSE(eglMakeCurrent(display_, surface1_, surface1_, EGL_NO_CONTEXT));
-  EXPECT_EQ(EGL_BAD_CONTEXT, eglGetError());
-  EXPECT_FALSE(eglMakeCurrent(display_, surface1_, EGL_NO_SURFACE, context1_));
-  EXPECT_EQ(EGL_BAD_SURFACE, eglGetError());
-  EXPECT_FALSE(eglMakeCurrent(display_, EGL_NO_SURFACE, surface1_, context1_));
-  EXPECT_EQ(EGL_BAD_SURFACE, eglGetError());
-
-  EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1);
-  EGLSurface invalid_surface = reinterpret_cast<EGLSurface>(0x1);
-  EGLSurface invalid_context = reinterpret_cast<EGLContext>(0x1);
-  EXPECT_FALSE(
-      eglMakeCurrent(invalid_display, surface1_, surface1_, context1_));
-  EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError());
-  EXPECT_FALSE(eglMakeCurrent(display_, surface1_, surface1_, invalid_context));
-  EXPECT_EQ(EGL_BAD_CONTEXT, eglGetError());
-  EXPECT_FALSE(eglMakeCurrent(display_, surface1_, invalid_surface, context1_));
-  EXPECT_EQ(EGL_BAD_SURFACE, eglGetError());
-  EXPECT_FALSE(eglMakeCurrent(display_, invalid_surface, surface1_, context1_));
-  EXPECT_EQ(EGL_BAD_SURFACE, eglGetError());
-
-  // Command buffer limitation:
-  // Different read and draw surfaces fail.
-  EXPECT_FALSE(eglMakeCurrent(display_, surface1_, surface2_, context1_));
-  EXPECT_EQ(EGL_BAD_MATCH, eglGetError());
-}
-
-TEST_F(EGLMultipleSurfacesContextsTest, CallGLOnMultipleContextNoCrash) {
-  EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_));
-
-  typedef void(GL_APIENTRY * glEnableProc)(GLenum);
-  glEnableProc glEnable =
-      reinterpret_cast<glEnableProc>(eglGetProcAddress("glEnable"));
-  EXPECT_NE(nullptr, glEnable);
-
-  glEnable(GL_BLEND);
-
-  EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_));
-  glEnable(GL_BLEND);
-}
-
-class EGLThreadTest : public EGLSurfaceTest {
- public:
-  EGLThreadTest();
-  void SetUp() override;
-  void TearDown() override;
-  void OtherThreadTearDown(base::WaitableEvent*);
-  void OtherThreadMakeCurrent(EGLSurface surface,
-                              EGLContext context,
-                              EGLBoolean* result,
-                              base::WaitableEvent*);
-  void OtherThreadGetError(EGLint* result, base::WaitableEvent*);
-
- protected:
-  base::Thread other_thread_;
-};
-
-EGLThreadTest::EGLThreadTest()
-    : EGLSurfaceTest(), other_thread_("EGLThreadTest thread") {}
-void EGLThreadTest::SetUp() {
-  EGLSurfaceTest::SetUp();
-  other_thread_.Start();
-}
-
-void EGLThreadTest::TearDown() {
-  base::WaitableEvent completion(
-      base::WaitableEvent::ResetPolicy::MANUAL,
-      base::WaitableEvent::InitialState::NOT_SIGNALED);
-  other_thread_.task_runner()->PostTask(
-      FROM_HERE, base::BindOnce(&EGLThreadTest::OtherThreadTearDown,
-                                base::Unretained(this), &completion));
-  completion.Wait();
-  other_thread_.Stop();
-  EGLSurfaceTest::TearDown();
-}
-
-void EGLThreadTest::OtherThreadTearDown(base::WaitableEvent* completion) {
-  EXPECT_TRUE(eglReleaseThread());
-  completion->Signal();
-}
-
-void EGLThreadTest::OtherThreadMakeCurrent(EGLSurface surface,
-                                           EGLContext context,
-                                           EGLBoolean* result,
-                                           base::WaitableEvent* completion) {
-  *result = eglMakeCurrent(display_, surface, surface, context);
-  completion->Signal();
-}
-
-void EGLThreadTest::OtherThreadGetError(EGLint* result,
-                                        base::WaitableEvent* completion) {
-  *result = eglGetError();
-  completion->Signal();
-}
-
-TEST_F(EGLThreadTest, OnlyReleaseThreadInOther) {}
-
-TEST_F(EGLThreadTest, Basic) {
-  EGLSurface surface;
-  EGLContext context;
-  CreateSurfaceAndContext(&surface, &context);
-  EXPECT_NE(EGL_NO_SURFACE, surface);
-  EXPECT_NE(EGL_NO_CONTEXT, context);
-
-  EXPECT_TRUE(eglMakeCurrent(display_, surface, surface, context));
-
-  base::WaitableEvent completion(
-      base::WaitableEvent::ResetPolicy::AUTOMATIC,
-      base::WaitableEvent::InitialState::NOT_SIGNALED);
-
-  EGLBoolean result = EGL_FALSE;
-  other_thread_.task_runner()->PostTask(
-      FROM_HERE, base::BindOnce(&EGLThreadTest::OtherThreadMakeCurrent,
-                                base::Unretained(this), surface, context,
-                                &result, &completion));
-  completion.Wait();
-  EXPECT_FALSE(result);
-  EXPECT_EQ(EGL_SUCCESS, eglGetError());
-
-  EGLint error = EGL_NONE;
-  other_thread_.task_runner()->PostTask(
-      FROM_HERE, base::BindOnce(&EGLThreadTest::OtherThreadGetError,
-                                base::Unretained(this), &error, &completion));
-  completion.Wait();
-  EXPECT_EQ(EGL_BAD_ACCESS, error);
-  EXPECT_EQ(EGL_SUCCESS, eglGetError());
-
-  other_thread_.task_runner()->PostTask(
-      FROM_HERE, base::BindOnce(&EGLThreadTest::OtherThreadGetError,
-                                base::Unretained(this), &error, &completion));
-  completion.Wait();
-  EXPECT_EQ(EGL_SUCCESS, error);
-
-  EXPECT_TRUE(
-      eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
-
-  other_thread_.task_runner()->PostTask(
-      FROM_HERE, base::BindOnce(&EGLThreadTest::OtherThreadMakeCurrent,
-                                base::Unretained(this), surface, context,
-                                &result, &completion));
-  completion.Wait();
-  EXPECT_TRUE(result);
-
-  EXPECT_FALSE(eglMakeCurrent(display_, surface, surface, context));
-  EXPECT_EQ(EGL_BAD_ACCESS, eglGetError());
-
-  EXPECT_TRUE(eglDestroySurface(display_, surface));
-  EXPECT_TRUE(eglDestroyContext(display_, context));
-}
-
-TEST_F(EGLTest, WindowlessNativeWindows) {
-  EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  EXPECT_TRUE(eglInitialize(display, nullptr, nullptr));
-
-  static const EGLint config_attribs[] = {EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
-                                          EGL_NONE};
-  EGLint num_config;
-  EGLConfig config;
-  EXPECT_TRUE(
-      eglChooseConfig(display, config_attribs, &config, 1, &num_config));
-  ASSERT_GT(num_config, 0);
-  static const EGLint surface_attribs[] = {EGL_NONE};
-  CommandBufferGLESSetNextCreateWindowSurfaceCreatesPBuffer(display, 100, 100);
-  EGLNativeWindowType win = 0;
-  EGLSurface surface =
-      eglCreateWindowSurface(display, config, win, surface_attribs);
-  EXPECT_NE(EGL_NO_SURFACE, surface);
-
-  // Test that SwapBuffers can be called on windowless window surfaces.
-
-  static const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2,
-                                           EGL_NONE};
-  EGLContext context =
-      eglCreateContext(display, config, nullptr, context_attribs);
-  EXPECT_TRUE(eglMakeCurrent(display, surface, surface, context));
-  EXPECT_TRUE(eglSwapBuffers(display, surface));
-
-  EXPECT_TRUE(eglDestroySurface(display, surface));
-  EXPECT_TRUE(eglDestroyContext(display, context));
-}
-
-}  // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc b/gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc
index c8ebbd705..6ae914e7 100644
--- a/gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc
+++ b/gpu/command_buffer/tests/gl_clear_framebuffer_unittest.cc
@@ -22,7 +22,6 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/extension_set.h"
 #include "ui/gl/gl_context.h"
-#include "ui/gl/gl_version_info.h"
 
 namespace gpu {
 
@@ -45,14 +44,6 @@
     }
   }
 
-  bool IsApplicable() {
-    // The workaround doesn't use VAOs which would cause a failure on a core
-    // context and the hardware for each the workaround is necessary has a buggy
-    // VAO implementation. So we skip testing the workaround on core profiles.
-    return !GetParam() ||
-           !gl_.context()->GetVersionInfo()->is_desktop_core_profile;
-  }
-
   void InitDraw();
   void SetDrawColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
   void SetDrawDepth(GLfloat depth);
@@ -118,10 +109,6 @@
                          ::testing::Values(true, false));
 
 TEST_P(GLClearFramebufferTest, ClearColor) {
-  if (!IsApplicable()) {
-    return;
-  }
-
   glClearColor(1.0f, 0.5f, 0.25f, 0.5f);
   glClear(GL_COLOR_BUFFER_BIT);
 
@@ -132,10 +119,6 @@
 }
 
 TEST_P(GLClearFramebufferTest, ClearColorWithMask) {
-  if (!IsApplicable()) {
-    return;
-  }
-
   glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
   glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
   glClear(GL_COLOR_BUFFER_BIT);
@@ -149,10 +132,6 @@
 // crbug.com/434094
 #if !BUILDFLAG(IS_MAC)
 TEST_P(GLClearFramebufferTest, ClearColorWithScissor) {
-  if (!IsApplicable()) {
-    return;
-  }
-
   // TODO(jonahr): Test fails on Linux with ANGLE/passthrough
   // (crbug.com/1099770)
   gpu::GPUTestBotConfig bot_config;
@@ -181,9 +160,6 @@
 #endif
 
 TEST_P(GLClearFramebufferTest, ClearDepthStencil) {
-  if (!IsApplicable()) {
-    return;
-  }
   // TODO(kainino): https://crbug.com/782317
   if (GPUTestBotConfig::CurrentConfigMatches("Intel")) {
     return;
@@ -242,7 +218,7 @@
   gfx::ExtensionSet extensions = gfx::MakeExtensionSet(extension_string);
   bool has_separate_framebuffer =
       gfx::HasExtension(extensions, "GL_CHROMIUM_framebuffer_multisample");
-  if (!IsApplicable() || !has_separate_framebuffer) {
+  if (!has_separate_framebuffer) {
     return;
   }
 
diff --git a/gpu/command_buffer/tests/webgpu_mailbox_unittest.cc b/gpu/command_buffer/tests/webgpu_mailbox_unittest.cc
index 587fb3e..77224fc4 100644
--- a/gpu/command_buffer/tests/webgpu_mailbox_unittest.cc
+++ b/gpu/command_buffer/tests/webgpu_mailbox_unittest.cc
@@ -642,6 +642,66 @@
   }
 }
 
+// Test that passing write usages when associating a mailbox fails if
+// the SharedImage associated with the mailbox doesn't have WEBGPU_WRITE access.
+TEST_P(WebGPUMailboxTest, PassWriteUsagesWhenAssociatingReadOnlyMailbox) {
+  // Create the shared image.
+  SharedImageInterface* sii = GetSharedImageInterface();
+  scoped_refptr<gpu::ClientSharedImage> shared_image =
+      sii->CreateSharedImage({GetParam().format,
+                              {1, 1},
+                              gfx::ColorSpace::CreateSRGB(),
+                              SHARED_IMAGE_USAGE_WEBGPU_READ,
+                              "TestLabel"},
+                             kNullSurfaceHandle);
+  SyncToken mailbox_produced_token = sii->GenVerifiedSyncToken();
+  webgpu()->WaitSyncTokenCHROMIUM(mailbox_produced_token.GetConstData());
+
+  // Set callback to expect a validation error.
+  device_.SetUncapturedErrorCallback(ToMockUncapturedErrorCallback, nullptr);
+
+  // Register the shared image as a Dawn texture in the wire.
+  gpu::webgpu::ReservedTexture reservation =
+      webgpu()->ReserveTexture(device_.Get());
+
+  // Create a texture for the mailbox, passing CopyDst as a usage.
+  webgpu()->AssociateMailbox(
+      reservation.deviceId, reservation.deviceGeneration, reservation.id,
+      reservation.generation,
+      WGPUTextureUsage_CopySrc | WGPUTextureUsage_CopyDst,
+      webgpu::WEBGPU_MAILBOX_NONE, shared_image->mailbox());
+  wgpu::Texture texture = wgpu::Texture::Acquire(reservation.texture);
+
+  // Copy the texture in a mappable buffer.
+  wgpu::BufferDescriptor buffer_desc;
+  buffer_desc.size = BytesPerTexel(GetParam().format);
+  buffer_desc.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
+  wgpu::Buffer readback_buffer = device_.CreateBuffer(&buffer_desc);
+
+  wgpu::ImageCopyTexture copy_src = {};
+  copy_src.texture = texture;
+  copy_src.mipLevel = 0;
+  copy_src.origin = {0, 0, 0};
+
+  wgpu::ImageCopyBuffer copy_dst = {};
+  copy_dst.buffer = readback_buffer;
+  copy_dst.layout.offset = 0;
+  copy_dst.layout.bytesPerRow = 256;
+
+  wgpu::Extent3D copy_size = {1, 1, 1};
+
+  wgpu::CommandEncoder encoder = device_.CreateCommandEncoder();
+  encoder.CopyTextureToBuffer(&copy_src, &copy_dst, &copy_size);
+
+  EXPECT_CALL(*mock_device_error_callback,
+              Call(WGPUErrorType_Validation, testing::_, testing::_))
+      .Times(1);
+
+  encoder.Finish();
+
+  WaitForCompletion(device_);
+}
+
 // Test that passing internal write usages when associating a mailbox fails if
 // the SharedImage associated with the mailbox doesn't have WEBGPU_WRITE access.
 TEST_P(WebGPUMailboxTest,
diff --git a/gpu/config/gpu_control_list.h b/gpu/config/gpu_control_list.h
index 72855f2..40fe01cd 100644
--- a/gpu/config/gpu_control_list.h
+++ b/gpu/config/gpu_control_list.h
@@ -14,6 +14,7 @@
 
 #include "base/containers/span.h"
 #include "base/memory/raw_ptr_exclusion.h"
+#include "base/memory/raw_span.h"
 #include "base/values.h"
 #include "gpu/config/gpu_info.h"
 #include "gpu/gpu_export.h"
@@ -352,7 +353,7 @@
 
   // These always point to built-in arrays of constants, so raw_ptr doesn't
   // add any protection but costs some overhead.
-  base::span<const Entry> entries_;
+  base::raw_span<const Entry> entries_;
 
   // This records all the entries that are applicable to the current user
   // machine.  It is updated everytime MakeDecision() is called and is used
diff --git a/gpu/config/gpu_finch_features.cc b/gpu/config/gpu_finch_features.cc
index 5b9c180b..03b8fdc 100644
--- a/gpu/config/gpu_finch_features.cc
+++ b/gpu/config/gpu_finch_features.cc
@@ -438,12 +438,6 @@
 #endif
 );
 
-// When the application is in background, whether to perform immediate GPU
-// cleanup when executing deferred requests.
-BASE_FEATURE(kGpuCleanupInBackground,
-             "GpuCleanupInBackground",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
 // On platforms with delegated compositing, try to release overlays later, when
 // no new frames are swapped.
 BASE_FEATURE(kDeferredOverlaysRelease,
diff --git a/gpu/config/gpu_finch_features.h b/gpu/config/gpu_finch_features.h
index 0949ef88..9cbbcf0 100644
--- a/gpu/config/gpu_finch_features.h
+++ b/gpu/config/gpu_finch_features.h
@@ -107,8 +107,6 @@
 
 GPU_EXPORT BASE_DECLARE_FEATURE(kIncreasedCmdBufferParseSlice);
 
-GPU_EXPORT BASE_DECLARE_FEATURE(kGpuCleanupInBackground);
-
 GPU_EXPORT BASE_DECLARE_FEATURE(kDeferredOverlaysRelease);
 
 #if BUILDFLAG(IS_WIN)
diff --git a/gpu/gles2_conform_support/BUILD.gn b/gpu/gles2_conform_support/BUILD.gn
deleted file mode 100644
index 4673e03..0000000
--- a/gpu/gles2_conform_support/BUILD.gn
+++ /dev/null
@@ -1,465 +0,0 @@
-# Copyright 2015 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-declare_args() {
-  # Set to true to compile with the OpenGL ES 2.0 conformance tests.
-  internal_gles2_conform_tests = false
-}
-
-config("gles2_conform_test_warnings") {
-  if (is_clang) {
-    cflags = [
-      "-Wno-array-bounds",
-      "-Wno-implicit-function-declaration",
-      "-Wno-logical-op-parentheses",
-
-      # Many struct initializers in the GTF_ES code are missing braces.
-      "-Wno-missing-braces",
-      "-Wno-parentheses-equality",
-      "-Wno-pointer-sign",
-      "-Wno-return-type",
-      "-Wno-sign-compare",
-      "-Wno-sizeof-pointer-memaccess",
-
-      # A few variables are unitialized if GLVersion != 2.0.
-      "-Wno-sometimes-uninitialized",
-      "-Wno-tautological-compare",
-
-      # GTFVecBase.h contains static no-inline functions in a header :-/
-      "-Wno-unused-function",
-      "-Wno-unused-variable",
-
-      # There are some implicit conversions from "int" to "char" in
-      # GTFExtensionTestSurfacelessContext.c.
-      "-Wno-constant-conversion",
-    ]
-  }
-}
-
-import("//testing/test.gni")
-
-executable("gles2_conform_support") {
-  sources = [
-    "gles2_conform_support.c",
-    "native/egl_native.cc",
-    "native/main.cc",
-  ]
-  defines = [
-    "GLES2_CONFORM_SUPPORT_ONLY",
-    "GTF_GLES20",
-    "EGLAPI=",
-    "EGLAPIENTRY=",
-  ]
-  deps = [
-    "//base",
-    "//build/win:default_exe_manifest",
-    "//gpu/command_buffer/client:gles2_c_lib_nocheck",
-    "//gpu/gles2_conform_support/egl",
-    "//ui/gl",
-  ]
-  if (is_linux || is_chromeos) {
-    sources += [
-      "native/egl_native_aura.cc",
-      "native/egl_native_x11.cc",
-    ]
-  }
-}
-
-if (internal_gles2_conform_tests) {
-  action("generate_gles2_conform_embedded_data") {
-    script = "generate_gles2_embedded_data.py"
-    outputs = [
-      "$target_gen_dir/gles2_conform_test_embedded_data/FilesDATA.c",
-      "$target_gen_dir/gles2_conform_test_embedded_data/FilesDATA.h",
-      "$target_gen_dir/gles2_conform_test_embedded_data/FilesTOC.c",
-    ]
-    args = [
-      rebase_path("//third_party/gles2_conform/GTF_ES/glsl/GTF"),
-      rebase_path("$target_gen_dir/gles2_conform_test_embedded_data"),
-    ]
-  }
-  action("generate_gles2_conform_tests") {
-    script = "generate_gles2_conform_tests.py"
-    outputs = [ "$target_gen_dir/gles2_conform_test_autogen.cc" ]
-    args = [ rebase_path("$target_gen_dir") ]
-  }
-  executable("gles2_conform_test_windowless") {
-    testonly = true
-
-    # Include a dummy c++ file to force linking of libstdc++.
-    sources = [ "dummy.cc" ]
-
-    gtf_source = "//third_party/gles2_conform/GTF_ES/glsl/GTF/Source"
-    sources += [
-      # Bootstrapping files commented out. We have different bootstrapping
-      # files for each platform.
-      "$gtf_source/FilesTOC.h",
-      "$gtf_source/GL/GTFAttDataGL.c",
-      "$gtf_source/GL/GTFAttDataGL.h",
-      "$gtf_source/GL/GTFDepthRangeParamGL.c",
-      "$gtf_source/GL/GTFDepthRangeParamGL.h",
-      "$gtf_source/GL/GTFModelDataGL.c",
-      "$gtf_source/GL/GTFModelDataGL.h",
-      "$gtf_source/GL/GTFPointParamGL.c",
-      "$gtf_source/GL/GTFPointParamGL.h",
-      "$gtf_source/GL/GTFReadPixelsGL.c",
-      "$gtf_source/GL/GTFReadPixelsGL.h",
-      "$gtf_source/GL/GTFShaderDataGL.c",
-      "$gtf_source/GL/GTFShaderDataGL.h",
-      "$gtf_source/GL/GTFShaderTextGL.c",
-      "$gtf_source/GL/GTFShaderTextGL.h",
-      "$gtf_source/GL/GTFStateDataGL.c",
-      "$gtf_source/GL/GTFStateDataGL.h",
-      "$gtf_source/GL/GTFTexDataGL.c",
-      "$gtf_source/GL/GTFTexDataGL.h",
-      "$gtf_source/GL/GTFTexParamGL.c",
-      "$gtf_source/GL/GTFTexParamGL.h",
-      "$gtf_source/GL/GTFUniDataGL.c",
-      "$gtf_source/GL/GTFUniDataGL.h",
-
-      #"$gtf_source/main.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestCompressedETC1RGB8Texture.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestCompressedETC1RGB8Texture.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestCompressedPalettedTexture.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestCompressedPalettedTexture.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestConditionalQuery.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestConditionalQuery.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestDataType1010102.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestDataType1010102.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestDebug.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestDebug.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestDepth24.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestDepth24.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestDepth32.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestDepth32.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestDepthTexture.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestDepthTexture.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestDepthTextureCubeMap.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestDepthTextureCubeMap.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestEGLCreateContext.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestEGLCreateContext.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestEGLImage.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestEGLImage.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestEGLImageExternal.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestEGLImageExternal.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestElementIndexUINT.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestElementIndexUINT.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestFBORenderMipmap.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestFBORenderMipmap.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestFragmentPrecisionHigh.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestFragmentPrecisionHigh.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestFramebufferObject.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestFramebufferObject.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestMapBuffer.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestMapBuffer.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestOcclusionQuery.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestOcclusionQuery.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestPackedDepthStencil.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestPackedDepthStencil.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestPointSizeArray.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestPointSizeArray.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestPointSprite.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestPointSprite.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestRGB8RGBA8.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestRGB8RGBA8.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestReadFormat.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestReadFormat.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestRequiredInternalformat.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestRequiredInternalformat.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestStencil1.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestStencil1.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestStencil4.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestStencil4.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestStencil8.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestStencil8.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestSurfacelessContext.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestSurfacelessContext.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestTexture3D.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestTexture3D.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestTextureCompressionASTCLDR.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestTextureCompressionASTCLDR.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestTextureCompressionASTCLDRVectors.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestTextureFloat.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestTextureFloat.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestTextureFloatLinear.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestTextureFloatLinear.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestTextureNPOT.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestTextureNPOT.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestUtilp.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestUtilp.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestVertexArrayObject.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestVertexArrayObject.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestVertexHalfFloat.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestVertexHalfFloat.h",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestVisibilityQuery.c",
-      "$gtf_source/GL2ExtensionTests/GTFExtensionTestVisibilityQuery.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestBlend.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestBlend.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestBufferClear.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestBufferClear.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestBufferColor.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestBufferColor.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestBufferCorners.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestBufferCorners.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestBufferObjects.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestBufferObjects.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestClip.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestClip.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestColorRamp.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestColorRamp.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestCopyTexture.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestCopyTexture.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestDepthBufferClear.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestDepthBufferClear.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestDepthBufferFunctions.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestDepthBufferFunctions.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestDither.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestDither.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestDivideByZero.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestDivideByZero.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestGets.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestGets.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestMipmapsInterpolation.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestMipmapsInterpolation.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestMipmapsSelection.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestMipmapsSelection.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestPointRasterization.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestPointRasterization.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestPointSprites.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestPointSprites.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestPolygonCull.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestPolygonCull.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestScissor.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestScissor.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestStencilPlaneClear.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestStencilPlaneClear.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestStencilPlaneCorners.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestStencilPlaneCorners.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestStencilPlaneFunction.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestStencilPlaneFunction.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestStencilPlaneOperation.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestStencilPlaneOperation.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestTextureEdgeClamp.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestTextureEdgeClamp.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestTransformViewport.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestTransformViewport.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestTriangleRasterization.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestTriangleRasterization.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestTriangleTiling.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestTriangleTiling.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestUserClipPlanes.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestUserClipPlanes.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestVertexOrder.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestVertexOrder.h",
-      "$gtf_source/GL2FixedTests/GTFFixedTestViewportClamp.c",
-      "$gtf_source/GL2FixedTests/GTFFixedTestViewportClamp.h",
-      "$gtf_source/GL2FixedTests/GTFFixedUtilg.c",
-      "$gtf_source/GL2FixedTests/GTFFixedUtilg.h",
-      "$gtf_source/GL2FixedTests/GTFFixedUtilr.c",
-      "$gtf_source/GL2FixedTests/GTFFixedUtilr.h",
-      "$gtf_source/GL2Tests/GTFGL2TestAttributeGL.c",
-      "$gtf_source/GL2Tests/GTFGL2TestAttributeGL.h",
-      "$gtf_source/GL2Tests/GTFGL2TestBindAllAttributes.c",
-      "$gtf_source/GL2Tests/GTFGL2TestBindAllAttributes.h",
-      "$gtf_source/GL2Tests/GTFGL2TestCreateObjectGL.c",
-      "$gtf_source/GL2Tests/GTFGL2TestCreateObjectGL.h",
-      "$gtf_source/GL2Tests/GTFGL2TestDetachGL.c",
-      "$gtf_source/GL2Tests/GTFGL2TestDetachGL.h",
-      "$gtf_source/GL2Tests/GTFGL2TestFixedDataType.c",
-      "$gtf_source/GL2Tests/GTFGL2TestFixedDataType.h",
-      "$gtf_source/GL2Tests/GTFGL2TestFramebufferObjects.c",
-      "$gtf_source/GL2Tests/GTFGL2TestFramebufferObjects.h",
-      "$gtf_source/GL2Tests/GTFGL2TestGetAttachedObjects.c",
-      "$gtf_source/GL2Tests/GTFGL2TestGetAttachedObjects.h",
-      "$gtf_source/GL2Tests/GTFGL2TestGetAttributeLocation.c",
-      "$gtf_source/GL2Tests/GTFGL2TestGetAttributeLocation.h",
-      "$gtf_source/GL2Tests/GTFGL2TestGetBIFD.c",
-      "$gtf_source/GL2Tests/GTFGL2TestGetBIFD.h",
-      "$gtf_source/GL2Tests/GTFGL2TestGetExtensions.c",
-      "$gtf_source/GL2Tests/GTFGL2TestGetExtensions.h",
-      "$gtf_source/GL2Tests/GTFGL2TestGetProgramInfoLog.c",
-      "$gtf_source/GL2Tests/GTFGL2TestGetProgramInfoLog.h",
-      "$gtf_source/GL2Tests/GTFGL2TestGetProgramiv.c",
-      "$gtf_source/GL2Tests/GTFGL2TestGetProgramiv.h",
-      "$gtf_source/GL2Tests/GTFGL2TestGetShaderInfoLog.c",
-      "$gtf_source/GL2Tests/GTFGL2TestGetShaderInfoLog.h",
-      "$gtf_source/GL2Tests/GTFGL2TestGetShaderiv.c",
-      "$gtf_source/GL2Tests/GTFGL2TestGetShaderiv.h",
-      "$gtf_source/GL2Tests/GTFGL2TestGetUniform.c",
-      "$gtf_source/GL2Tests/GTFGL2TestGetUniform.h",
-      "$gtf_source/GL2Tests/GTFGL2TestGetVertexAttrib.c",
-      "$gtf_source/GL2Tests/GTFGL2TestGetVertexAttrib.h",
-      "$gtf_source/GL2Tests/GTFGL2TestMaxVertexAttrib.c",
-      "$gtf_source/GL2Tests/GTFGL2TestMaxVertexAttrib.h",
-      "$gtf_source/GL2Tests/GTFGL2TestMultipleShaders.c",
-      "$gtf_source/GL2Tests/GTFGL2TestMultipleShaders.h",
-      "$gtf_source/GL2Tests/GTFGL2TestRelinkProgram.c",
-      "$gtf_source/GL2Tests/GTFGL2TestRelinkProgram.h",
-      "$gtf_source/GL2Tests/GTFGL2TestUniform.c",
-      "$gtf_source/GL2Tests/GTFGL2TestUniform.h",
-      "$gtf_source/GL2Tests/GTFGL2TestUniformQueryGL.c",
-      "$gtf_source/GL2Tests/GTFGL2TestUniformQueryGL.h",
-      "$gtf_source/GL2Tests/GTFGL2TestVertexAttribPointer.c",
-      "$gtf_source/GL2Tests/GTFGL2TestVertexAttribPointer.h",
-      "$gtf_source/GL2Tests/GTFGL2TestVertexAttributes.c",
-      "$gtf_source/GL2Tests/GTFGL2TestVertexAttributes.h",
-      "$gtf_source/GL2Tests/GTFGL2TestVertexProgramPointSize.c",
-      "$gtf_source/GL2Tests/GTFGL2TestVertexProgramPointSize.h",
-      "$gtf_source/GTFArguments.c",
-      "$gtf_source/GTFArguments.h",
-      "$gtf_source/GTFCoverageDict.c",
-      "$gtf_source/GTFCoverageGL.c",
-      "$gtf_source/GTFCoverageGL.h",
-      "$gtf_source/GTFDict.h",
-      "$gtf_source/GTFDictBase.h",
-      "$gtf_source/GTFFileReader.c",
-      "$gtf_source/GTFFileReader.h",
-      "$gtf_source/GTFInitEGL.c",
-      "$gtf_source/GTFLog.c",
-      "$gtf_source/GTFLog.h",
-      "$gtf_source/GTFMain.c",
-      "$gtf_source/GTFMain.h",
-      "$gtf_source/GTFMatrix.h",
-      "$gtf_source/GTFMemFile.c",
-      "$gtf_source/GTFMemFile.h",
-      "$gtf_source/GTFModelData.c",
-      "$gtf_source/GTFModelData.h",
-      "$gtf_source/GTFPort.c",
-      "$gtf_source/GTFPort.h",
-      "$gtf_source/GTFString.h",
-      "$gtf_source/GTFStringUtils.c",
-      "$gtf_source/GTFStringUtils.h",
-      "$gtf_source/GTFTest.c",
-      "$gtf_source/GTFTest.h",
-      "$gtf_source/GTFTestBuildGL.c",
-      "$gtf_source/GTFTestBuildGL.h",
-      "$gtf_source/GTFTestCompareGL.c",
-      "$gtf_source/GTFTestCompareGL.h",
-      "$gtf_source/GTFTestComplexityGL.c",
-      "$gtf_source/GTFTestComplexityGL.h",
-      "$gtf_source/GTFTestCoverageGL.c",
-      "$gtf_source/GTFTestCoverageGL.h",
-      "$gtf_source/GTFTestDriver.c",
-      "$gtf_source/GTFTestDriver.h",
-      "$gtf_source/GTFTestElement.c",
-      "$gtf_source/GTFTestElement.h",
-      "$gtf_source/GTFTestExtension.c",
-      "$gtf_source/GTFTestExtension.h",
-      "$gtf_source/GTFTestFixedGL.c",
-      "$gtf_source/GTFTestFixedGL.h",
-      "$gtf_source/GTFTestGL2Test.c",
-      "$gtf_source/GTFTestGL2Test.h",
-      "$gtf_source/GTFTestRasterizationGL.c",
-      "$gtf_source/GTFTestRasterizationGL.h",
-      "$gtf_source/GTFTestShaderLoadGL.c",
-      "$gtf_source/GTFTestShaderLoadGL.h",
-      "$gtf_source/GTFTestUtil.c",
-      "$gtf_source/GTFTestUtil.h",
-      "$gtf_source/GTFVec.h",
-      "$gtf_source/GTFVecBase.h",
-      "$gtf_source/GTFVector.h",
-      "$gtf_source/GTFVersion.h",
-      "$gtf_source/GTFgl.c",
-      "$gtf_source/GTFgl.h",
-      "$gtf_source/MIMG.c",
-      "$gtf_source/MIMG.h",
-
-      #"$gtf_source/Win32Console.h",
-      "$gtf_source/XmlUtils.c",
-      "$gtf_source/XmlUtils.h",
-
-      #"$gtf_source/eglNative.c",
-      "$gtf_source/eglNative.h",
-      "$gtf_source/egl_config_select.c",
-      "$gtf_source/egl_config_select.h",
-      "$gtf_source/eglu.c",
-      "$gtf_source/eglu.h",
-      "$gtf_source/eglut.c",
-      "$gtf_source/eglut.h",
-      "$gtf_source/gl2Native.c",
-      "$gtf_source/gl2Native.h",
-      "$gtf_source/gl2ext_missing.h",
-    ]
-
-    # Also compile the sources generated by this action.
-    sources += get_target_outputs(":generate_gles2_conform_embedded_data")
-
-    # Do not apply Chromium code rules to this third-party code.
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-
-    defines = [
-      "GTF_API=GTF_GLES20",
-      "HKEMBEDDEDFILESYSTEM",
-    ]
-    include_dirs = [
-      rebase_path("$target_gen_dir/gles2_conform_test_embedded_data"),
-      "//third_party/gles2_conform/GTF_ES/glsl/GTF/Source",
-    ]
-    deps = [
-      ":generate_gles2_conform_embedded_data",
-      "//gpu/command_buffer/client:gles2_c_lib_nocheck",
-      "//gpu/gles2_conform_support/egl",
-      "//gpu/gles2_conform_support/native:windowless",
-      "//third_party/expat:expat",
-    ]
-    configs += [
-      "//build/config/compiler:no_incompatible_pointer_warnings",
-
-      # Must be done this way for warning flags to be ordered correctly.
-      ":gles2_conform_test_warnings",
-    ]
-    if (is_win) {
-      deps += [
-        "//third_party/angle:libEGL",
-        "//third_party/angle:libGLESv2",
-      ]
-      defines += [
-        "EGLAPI=",
-        "EGLAPIENTRY=",
-      ]
-      configs -= [ "//build/config/win:nominmax" ]
-    }
-    if (is_mac) {
-      defines += [
-        "_STDINT",
-        "_STDINT_H",
-      ]
-    }
-
-    #'run_as': {
-    #     'conditions': [
-    #       ['OS=="win"', {
-    #         'action': [
-    #           '$(TargetPath)',
-    #           '-noimagefileio',
-    #           '-run=<(DEPTH)/third_party/gles2_conform/GTF_ES/glsl/GTF/mustpass.run',
-    #         ],
-    #       }],
-    #     ],
-    #    },
-  }
-}
-
-test("gles2_conform_test") {
-  sources = [
-    "gles2_conform_test.cc",
-    "gles2_conform_test.h",
-  ]
-  deps = [
-    "//base",
-    "//base/test:test_support",
-    "//gpu/config",
-    "//testing/gtest",
-  ]
-
-  data = [ "gles2_conform_test_expectations.txt" ]
-
-  if (internal_gles2_conform_tests) {
-    data_deps = [ ":gles2_conform_test_windowless" ]
-    deps += [ ":generate_gles2_conform_tests" ]
-    sources += [ "$target_gen_dir/gles2_conform_test_autogen.cc" ]
-    data += [ "//third_party/gles2_conform/GTF_ES/" ]
-  }
-}
diff --git a/gpu/gles2_conform_support/DEPS b/gpu/gles2_conform_support/DEPS
deleted file mode 100644
index 45eed75..0000000
--- a/gpu/gles2_conform_support/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
-  "+third_party/gles2_conform",
-]
diff --git a/gpu/gles2_conform_support/README b/gpu/gles2_conform_support/README
deleted file mode 100644
index d58910d5..0000000
--- a/gpu/gles2_conform_support/README
+++ /dev/null
@@ -1,19 +0,0 @@
-To run OpenGL ES 2.0 conformance tests, do the following:
-(These require access to Google-internal sources.)
-1. Generate build files:
-   [GYP]
-     "python build/gyp_chromium gpu/gles2_conform_support/gles2_conform_test.gyp"
-     or set "GYP_DEFINES=internal_gles2_conform_tests=1" and rebuild your
-     projects using your standard method. Example:
-     "GYP_DEFINES=internal_gles2_conform_tests=1 gclient runhooks"
-   [GN]
-     "gn args out/gn" and add the config
-     "internal_gles2_conform_tests = true"
-2. Build any of the two targets:
-   - gles2_conform_test_angle which tests ANGLE
-   - gles2_conform_test_native which tests command-buffer service
-   - gles2_conform_test_windowless which tests command-buffer service on most platforms
-   - gles2_conform_test_pepper will be added later
-3. Run the targets as: "<path to>gles2_conform_test_native -noimagefileio
-   -run=<path to>third_party\gles2_conform\GTF_ES\glsl\GTF\mustpass.run"
-
diff --git a/gpu/gles2_conform_support/dummy.cc b/gpu/gles2_conform_support/dummy.cc
deleted file mode 100644
index e2d96491..0000000
--- a/gpu/gles2_conform_support/dummy.cc
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2013 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// gles2_conform_test_windowless target contains only .c files, and it no
-// longer links against libstdc++. We have to create this empty dummy.cc
-// file and add it to the target.
diff --git a/gpu/gles2_conform_support/egl/BUILD.gn b/gpu/gles2_conform_support/egl/BUILD.gn
deleted file mode 100644
index 5043ac93..0000000
--- a/gpu/gles2_conform_support/egl/BUILD.gn
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2015 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/ozone.gni")
-
-source_set("egl") {
-  output_name = "egl_native"
-  sources = [
-    "config.cc",
-    "config.h",
-    "context.cc",
-    "context.h",
-    "display.cc",
-    "display.h",
-    "egl.cc",
-    "surface.cc",
-    "surface.h",
-    "test_support.cc",
-    "test_support.h",
-    "thread_state.cc",
-    "thread_state.h",
-  ]
-
-  defines = [
-    "EGLAPI=",
-    "EGLAPIENTRY=",
-  ]
-
-  deps = [
-    "//base",
-    "//gpu",
-    "//gpu/command_buffer/client:gles2_c_lib_nocheck",
-    "//gpu/command_buffer/client:gles2_cmd_helper",
-    "//gpu/command_buffer/client:gles2_implementation_no_check",
-    "//gpu/command_buffer/service",
-    "//gpu/command_buffer/service:gles2",
-    "//ui/base",
-    "//ui/gfx",
-    "//ui/gfx/geometry",
-    "//ui/gl",
-    "//ui/gl/init",
-  ]
-
-  if (use_ozone) {
-    deps += [ "//ui/ozone" ]
-  }
-}
diff --git a/gpu/gles2_conform_support/egl/config.cc b/gpu/gles2_conform_support/egl/config.cc
deleted file mode 100644
index 0ab5d00a..0000000
--- a/gpu/gles2_conform_support/egl/config.cc
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2011 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "gpu/gles2_conform_support/egl/config.h"
-#include "base/check.h"
-
-namespace gles2_conform_support {
-namespace egl {
-
-Config::Config(EGLint surface_type)
-    : buffer_size_(0),
-      red_size_(0),
-      green_size_(0),
-      blue_size_(0),
-      luminance_size_(0),
-      alpha_size_(0),
-      alpha_mask_size_(0),
-      bind_to_texture_rgb_(EGL_FALSE),
-      bind_to_texture_rgba_(EGL_FALSE),
-      color_buffer_type_(EGL_RGB_BUFFER),
-      config_caveat_(EGL_NONE),
-      config_id_(EGL_DONT_CARE),
-      conformant_(EGL_OPENGL_ES2_BIT),
-      depth_size_(0),
-      level_(0),
-      max_pbuffer_width_(0),
-      max_pbuffer_height_(0),
-      max_pbuffer_pixels_(0),
-      min_swap_interval_(EGL_DONT_CARE),
-      max_swap_interval_(EGL_DONT_CARE),
-      native_renderable_(EGL_TRUE),
-      native_visual_id_(0),
-      native_visual_type_(EGL_DONT_CARE),
-      renderable_type_(EGL_OPENGL_ES2_BIT),
-      sample_buffers_(0),
-      samples_(0),
-      stencil_size_(0),
-      surface_type_(surface_type),
-      transparent_type_(EGL_NONE),
-      transparent_red_value_(EGL_DONT_CARE),
-      transparent_green_value_(EGL_DONT_CARE),
-      transparent_blue_value_(EGL_DONT_CARE) {
-  DCHECK(surface_type == EGL_WINDOW_BIT || surface_type == EGL_PBUFFER_BIT);
-}
-
-Config::~Config() = default;
-
-bool Config::Matches(const EGLint* attrib_list) const {
-  DCHECK(ValidateAttributeList(attrib_list));
-  if (attrib_list) {
-    for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
-      switch (attrib_list[i]) {
-        case EGL_SURFACE_TYPE: {
-          EGLint requested_surface_type = attrib_list[i + 1];
-          if (requested_surface_type != EGL_DONT_CARE &&
-              (requested_surface_type & surface_type_) !=
-                  requested_surface_type)
-            return false;
-          break;
-        }
-        default:
-          break;
-      }
-    }
-  }
-  return true;
-}
-
-bool Config::GetAttrib(EGLint attribute, EGLint* value) const {
-  // TODO(alokp): Find out how to get correct values.
-  switch (attribute) {
-    case EGL_BUFFER_SIZE:
-      *value = buffer_size_;
-      break;
-    case EGL_RED_SIZE:
-      *value = red_size_;
-      break;
-    case EGL_GREEN_SIZE:
-      *value = green_size_;
-      break;
-    case EGL_BLUE_SIZE:
-      *value = blue_size_;
-      break;
-    case EGL_LUMINANCE_SIZE:
-      *value = luminance_size_;
-      break;
-    case EGL_ALPHA_SIZE:
-      *value = alpha_size_;
-      break;
-    case EGL_ALPHA_MASK_SIZE:
-      *value = alpha_mask_size_;
-      break;
-    case EGL_BIND_TO_TEXTURE_RGB:
-      *value = bind_to_texture_rgb_;
-      break;
-    case EGL_BIND_TO_TEXTURE_RGBA:
-      *value = bind_to_texture_rgba_;
-      break;
-    case EGL_COLOR_BUFFER_TYPE:
-      *value = color_buffer_type_;
-      break;
-    case EGL_CONFIG_CAVEAT:
-      *value = config_caveat_;
-      break;
-    case EGL_CONFIG_ID:
-      *value = config_id_;
-      break;
-    case EGL_CONFORMANT:
-      *value = conformant_;
-      break;
-    case EGL_DEPTH_SIZE:
-      *value = depth_size_;
-      break;
-    case EGL_LEVEL:
-      *value = level_;
-      break;
-    case EGL_MAX_PBUFFER_WIDTH:
-      *value = max_pbuffer_width_;
-      break;
-    case EGL_MAX_PBUFFER_HEIGHT:
-      *value = max_pbuffer_height_;
-      break;
-    case EGL_MAX_PBUFFER_PIXELS:
-      *value = max_pbuffer_pixels_;
-      break;
-    case EGL_MIN_SWAP_INTERVAL:
-      *value = min_swap_interval_;
-      break;
-    case EGL_MAX_SWAP_INTERVAL:
-      *value = max_swap_interval_;
-      break;
-    case EGL_NATIVE_RENDERABLE:
-      *value = native_renderable_;
-      break;
-    case EGL_NATIVE_VISUAL_ID:
-      *value = native_visual_id_;
-      break;
-    case EGL_NATIVE_VISUAL_TYPE:
-      *value = native_visual_type_;
-      break;
-    case EGL_RENDERABLE_TYPE:
-      *value = renderable_type_;
-      break;
-    case EGL_SAMPLE_BUFFERS:
-      *value = sample_buffers_;
-      break;
-    case EGL_SAMPLES:
-      *value = samples_;
-      break;
-    case EGL_STENCIL_SIZE:
-      *value = stencil_size_;
-      break;
-    case EGL_SURFACE_TYPE:
-      *value = surface_type_;
-      break;
-    case EGL_TRANSPARENT_TYPE:
-      *value = transparent_type_;
-      break;
-    case EGL_TRANSPARENT_RED_VALUE:
-      *value = transparent_red_value_;
-      break;
-    case EGL_TRANSPARENT_GREEN_VALUE:
-      *value = transparent_green_value_;
-      break;
-    case EGL_TRANSPARENT_BLUE_VALUE:
-      *value = transparent_blue_value_;
-      break;
-    default:
-      return false;
-  }
-  return true;
-}
-
-bool Config::ValidateAttributeList(const EGLint* attrib_list) {
-  if (attrib_list) {
-    for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
-      switch (attrib_list[i]) {
-        case EGL_ALPHA_MASK_SIZE:
-        case EGL_ALPHA_SIZE:
-        case EGL_BIND_TO_TEXTURE_RGB:
-        case EGL_BIND_TO_TEXTURE_RGBA:
-        case EGL_BLUE_SIZE:
-        case EGL_BUFFER_SIZE:
-        case EGL_COLOR_BUFFER_TYPE:
-        case EGL_CONFIG_CAVEAT:
-        case EGL_CONFIG_ID:
-        case EGL_CONFORMANT:
-        case EGL_DEPTH_SIZE:
-        case EGL_GREEN_SIZE:
-        case EGL_LEVEL:
-        case EGL_LUMINANCE_SIZE:
-        case EGL_MATCH_NATIVE_PIXMAP:
-        case EGL_NATIVE_RENDERABLE:
-        case EGL_MAX_SWAP_INTERVAL:
-        case EGL_MIN_SWAP_INTERVAL:
-        case EGL_RED_SIZE:
-        case EGL_SAMPLE_BUFFERS:
-        case EGL_SAMPLES:
-        case EGL_STENCIL_SIZE:
-        case EGL_RENDERABLE_TYPE:
-        case EGL_SURFACE_TYPE:
-        case EGL_MULTISAMPLE_RESOLVE_BOX_BIT:
-        case EGL_PBUFFER_BIT:
-        case EGL_PIXMAP_BIT:
-        case EGL_SWAP_BEHAVIOR_PRESERVED_BIT:
-        case EGL_VG_ALPHA_FORMAT_PRE_BIT:
-        case EGL_VG_COLORSPACE_LINEAR_BIT:
-        case EGL_WINDOW_BIT:
-        case EGL_TRANSPARENT_TYPE:
-        case EGL_TRANSPARENT_RED_VALUE:
-        case EGL_TRANSPARENT_GREEN_VALUE:
-        case EGL_TRANSPARENT_BLUE_VALUE:
-          break;
-        default:
-          return false;
-      }
-    }
-  }
-  return true;
-}
-
-}  // namespace egl
-}  // namespace gles2_conform_support
\ No newline at end of file
diff --git a/gpu/gles2_conform_support/egl/config.h b/gpu/gles2_conform_support/egl/config.h
deleted file mode 100644
index fe571001..0000000
--- a/gpu/gles2_conform_support/egl/config.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2011 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef GPU_GLES2_CONFORM_SUPPORT_EGL_CONFIG_H_
-#define GPU_GLES2_CONFORM_SUPPORT_EGL_CONFIG_H_
-
-#include <EGL/egl.h>
-
-namespace gles2_conform_support {
-namespace egl {
-
-class Config {
- public:
-  explicit Config(EGLint surface_type);
-
-  Config(const Config&) = delete;
-  Config& operator=(const Config&) = delete;
-
-  ~Config();
-  bool Matches(const EGLint* attrib_list) const;
-  bool GetAttrib(EGLint attribute, EGLint* value) const;
-  static bool ValidateAttributeList(const EGLint* attrib_list);
-
- private:
-  // Total color component bits in the color buffer.
-  EGLint buffer_size_;
-  // Bits of Red in the color buffer.
-  EGLint red_size_;
-  // Bits of Green in the color buffer.
-  EGLint green_size_;
-  // Bits of Blue in the color buffer.
-  EGLint blue_size_;
-  // Bits of Luminance in the color buffer.
-  EGLint luminance_size_;
-  // Bits of Alpha in the color buffer.
-  EGLint alpha_size_;
-  // Bits of Alpha Mask in the mask buffer.
-  EGLint alpha_mask_size_;
-  // True if bindable to RGB textures.
-  EGLBoolean bind_to_texture_rgb_;
-  // True if bindable to RGBA textures.
-  EGLBoolean bind_to_texture_rgba_;
-  // Color buffer type.
-  EGLenum color_buffer_type_;
-  // Any caveats for the configuration.
-  EGLenum config_caveat_;
-  // Unique EGLConfig identifier.
-  EGLint config_id_;
-  // Whether contexts created with this config are conformant.
-  EGLint conformant_;
-  // Bits of Z in the depth buffer.
-  EGLint depth_size_;
-  // Frame buffer level.
-  EGLint level_;
-  // Maximum width of pbuffer.
-  EGLint max_pbuffer_width_;
-  // Maximum height of pbuffer.
-  EGLint max_pbuffer_height_;
-  // Maximum size of pbuffer.
-  EGLint max_pbuffer_pixels_;
-  // Minimum swap interval.
-  EGLint min_swap_interval_;
-  // Maximum swap interval.
-  EGLint max_swap_interval_;
-  // True if native rendering APIs can render to surface.
-  EGLBoolean native_renderable_;
-  // Handle of corresponding native visual.
-  EGLint native_visual_id_;
-  // Native visual type of the associated visual.
-  EGLint native_visual_type_;
-  // Which client rendering APIs are supported.
-  EGLint renderable_type_;
-  // Number of multisample buffers.
-  EGLint sample_buffers_;
-  // Number of samples per pixel.
-  EGLint samples_;
-  // Bits of Stencil in the stencil buffer.
-  EGLint stencil_size_;
-  // Which types of EGL surfaces are supported.
-  EGLint surface_type_;
-  // Type of transparency supported
-  EGLenum transparent_type_;
-  // Transparent red value
-  EGLint transparent_red_value_;
-  // Transparent green value
-  EGLint transparent_green_value_;
-  // Transparent blue value
-  EGLint transparent_blue_value_;
-};
-
-}  // namespace egl
-}  // namespace gles2_conform_support
-
-#endif  // GPU_GLES2_CONFORM_SUPPORT_EGL_CONFIG_H_
diff --git a/gpu/gles2_conform_support/egl/context.cc b/gpu/gles2_conform_support/egl/context.cc
deleted file mode 100644
index 7be38717..0000000
--- a/gpu/gles2_conform_support/egl/context.cc
+++ /dev/null
@@ -1,401 +0,0 @@
-// Copyright 2016 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "gpu/gles2_conform_support/egl/context.h"
-
-#include "base/command_line.h"
-#include "base/functional/bind.h"
-#include "base/functional/callback_helpers.h"
-#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "gpu/command_buffer/client/gles2_lib.h"
-#include "gpu/command_buffer/client/shared_memory_limits.h"
-#include "gpu/command_buffer/client/transfer_buffer.h"
-#include "gpu/command_buffer/service/context_group.h"
-#include "gpu/command_buffer/service/memory_tracking.h"
-#include "gpu/command_buffer/service/service_discardable_manager.h"
-#include "gpu/command_buffer/service/shared_image/shared_image_manager.h"
-#include "gpu/gles2_conform_support/egl/config.h"
-#include "gpu/gles2_conform_support/egl/display.h"
-#include "gpu/gles2_conform_support/egl/surface.h"
-#include "gpu/gles2_conform_support/egl/thread_state.h"
-#include "ui/gl/init/gl_factory.h"
-
-// The slight complexification in this file comes from following properties:
-// 1) Command buffer connection (context) can not be established without a
-// GLSurface. EGL Context can be created independent of a surface.  This is why
-// the connection is created only during first MakeCurrent.
-// 2) Command buffer MakeCurrent calls need the real gl context and surface be
-// current.
-// 3) Client can change real EGL context behind the scenes and then still expect
-// command buffer MakeCurrent re-set the command buffer context. This is why all
-// MakeCurrent calls must actually reset the real context, even though command
-// buffer current context does not change.
-// 4) EGL context can be destroyed without surface, but command buffer would
-// need the surface to run various cleanups. If context is destroyed
-// surfaceless, the context is marked lost before destruction. This is avoided
-// if possible, since command buffer at the time of writing prints out debug
-// text in this case.
-
-namespace {
-const bool kBindGeneratesResources = true;
-const bool kLoseContextWhenOutOfMemory = false;
-const bool kSupportClientSideArrays = true;
-}
-
-namespace gles2_conform_support {
-namespace egl {
-// static
-gpu::GpuFeatureInfo Context::platform_gpu_feature_info_;
-
-// static
-void Context::SetPlatformGpuFeatureInfo(
-    const gpu::GpuFeatureInfo& gpu_feature_info) {
-  platform_gpu_feature_info_ = gpu_feature_info;
-}
-
-Context::Context(Display* display, const Config* config)
-    : display_(display),
-      config_(config),
-      is_current_in_some_thread_(false),
-      is_destroyed_(false),
-      gpu_driver_bug_workarounds_(
-          platform_gpu_feature_info_.enabled_gpu_driver_bug_workarounds),
-      discardable_manager_(gpu::GpuPreferences()),
-      passthrough_discardable_manager_(gpu::GpuPreferences()),
-      translator_cache_(gpu::GpuPreferences()) {}
-
-Context::~Context() {
-  // We might not have a surface, so we must lose the context.  Cleanup will
-  // execute GL commands otherwise. TODO: if shared contexts are ever
-  // implemented, this will leak the GL resources. For pbuffer contexts, one
-  // could track the last current surface or create a surface for destroying
-  // purposes only. Other option would be to make the service usable without
-  // surface.
-  if (HasService()) {
-    if (!WasServiceContextLost())
-      MarkServiceContextLost();
-    DestroyService();
-  }
-}
-
-void Context::MarkDestroyed() {
-  is_destroyed_ = true;
-}
-
-bool Context::SwapBuffers(Surface* current_surface) {
-  DCHECK(HasService() && is_current_in_some_thread_);
-  if (WasServiceContextLost())
-    return false;
-  client_gl_context_->SwapBuffers(1);
-  return true;
-}
-
-bool Context::MakeCurrent(Context* current_context,
-                          Surface* current_surface,
-                          Context* new_context,
-                          Surface* new_surface) {
-  if (!new_context && !current_context) {
-    return true;
-  }
-  bool cleanup_old_current_context = false;
-  if (current_context) {
-    if (current_context->Flush(current_surface->gl_surface()))
-      cleanup_old_current_context = new_context != current_context;
-  }
-
-  if (new_context) {
-    if (!new_context->IsCompatibleSurface(new_surface))
-      return false;
-
-    if (new_context->HasService()) {
-      if (new_context->WasServiceContextLost())
-        return false;
-      if (new_context != current_context) {
-        // If Flush did not set the current context, set it now. Otherwise
-        // calling into the decoder is not ok.
-        if (!new_context->gl_context_->MakeCurrent(new_surface->gl_surface())) {
-          new_context->MarkServiceContextLost();
-          return false;
-        }
-      }
-      if (new_context != current_context || new_surface != current_surface)
-        new_context->decoder_->SetSurface(new_surface->gl_surface());
-      if (!new_context->decoder_->MakeCurrent()) {
-        new_context->MarkServiceContextLost();
-        return false;
-      }
-    } else {
-      if (!new_context->CreateService(new_surface->gl_surface())) {
-        return false;
-      }
-    }
-  }
-
-  // The current_surface will be released when MakeCurrent succeeds.
-  // Cleanup in this case only.
-  if (cleanup_old_current_context) {
-    if (current_context->is_destroyed_ && current_surface != new_surface) {
-      current_context->gl_context_->MakeCurrent(current_surface->gl_surface());
-      // If we are releasing the context and we have one ref, it means that the
-      // ref will be lost and the object will be destroyed.  Destroy the service
-      // explicitly here, so that cleanup can happen and client GL
-      // implementation does not print errors.
-      current_context->DestroyService();
-    } else {
-      current_context->decoder_->ReleaseSurface();
-    }
-  }
-
-  return true;
-}
-
-bool Context::ValidateAttributeList(const EGLint* attrib_list) {
-  if (attrib_list) {
-    for (int i = 0; attrib_list[i] != EGL_NONE; attrib_list += 2) {
-      switch (attrib_list[i]) {
-        case EGL_CONTEXT_CLIENT_VERSION:
-          break;
-        default:
-          return false;
-      }
-    }
-  }
-  return true;
-}
-
-void Context::SetGpuControlClient(gpu::GpuControlClient*) {
-  // The client is not currently called, so don't store it.
-}
-
-const gpu::Capabilities& Context::GetCapabilities() const {
-  return capabilities_;
-}
-
-const gpu::GLCapabilities& Context::GetGLCapabilities() const {
-  return gl_capabilities_;
-}
-
-void Context::SignalQuery(uint32_t query, base::OnceClosure callback) {
-  NOTREACHED_IN_MIGRATION();
-}
-
-void Context::CancelAllQueries() {
-  NOTREACHED_IN_MIGRATION();
-}
-
-void Context::CreateGpuFence(uint32_t gpu_fence_id, ClientGpuFence source) {
-  NOTREACHED_IN_MIGRATION();
-}
-
-void Context::GetGpuFence(
-    uint32_t gpu_fence_id,
-    base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)> callback) {
-  NOTREACHED_IN_MIGRATION();
-}
-
-void Context::SetLock(base::Lock*) {
-  NOTREACHED_IN_MIGRATION();
-}
-
-void Context::EnsureWorkVisible() {
-  NOTREACHED_IN_MIGRATION();
-}
-
-gpu::CommandBufferNamespace Context::GetNamespaceID() const {
-  return gpu::CommandBufferNamespace::INVALID;
-}
-
-gpu::CommandBufferId Context::GetCommandBufferID() const {
-  return gpu::CommandBufferId();
-}
-
-void Context::FlushPendingWork() {
-  NOTREACHED_IN_MIGRATION();
-}
-
-uint64_t Context::GenerateFenceSyncRelease() {
-  NOTREACHED_IN_MIGRATION();
-  return 0;
-}
-
-bool Context::IsFenceSyncReleased(uint64_t release) {
-  NOTREACHED_IN_MIGRATION();
-  return false;
-}
-
-void Context::SignalSyncToken(const gpu::SyncToken& sync_token,
-                              base::OnceClosure callback) {
-  NOTREACHED_IN_MIGRATION();
-}
-
-void Context::WaitSyncToken(const gpu::SyncToken& sync_token) {
-  NOTREACHED_IN_MIGRATION();
-}
-
-bool Context::CanWaitUnverifiedSyncToken(const gpu::SyncToken& sync_token) {
-  return false;
-}
-
-void Context::ApplyCurrentContext(gl::GLSurface* current_surface) {
-  DCHECK(HasService());
-  // The current_surface will be the same as
-  // the surface of the decoder. We can not DCHECK as there is
-  // no accessor.
-  if (!WasServiceContextLost()) {
-    if (!gl_context_->MakeCurrent(current_surface))
-      MarkServiceContextLost();
-  }
-  gles2::SetGLContext(client_gl_context_.get());
-}
-
-void Context::ApplyContextReleased() {
-  gles2::SetGLContext(nullptr);
-}
-
-bool Context::CreateService(gl::GLSurface* gl_surface) {
-  gpu::SharedMemoryLimits limits;
-  gpu::GpuPreferences gpu_preferences;
-  gpu::GpuFeatureInfo gpu_feature_info;
-  scoped_refptr<gpu::gles2::FeatureInfo> feature_info(
-      new gpu::gles2::FeatureInfo(gpu_driver_bug_workarounds_,
-                                  gpu_feature_info));
-  scoped_refptr<gpu::gles2::ContextGroup> group(new gpu::gles2::ContextGroup(
-      gpu_preferences, true, nullptr /* memory_tracker */, &translator_cache_,
-      &completeness_cache_, feature_info, true, nullptr /* progress_reporter */,
-      gpu_feature_info, &discardable_manager_,
-      &passthrough_discardable_manager_, &shared_image_manager_));
-
-  auto command_buffer = std::make_unique<gpu::CommandBufferDirect>();
-
-  std::unique_ptr<gpu::gles2::GLES2Decoder> decoder(
-      gpu::gles2::GLES2Decoder::Create(command_buffer.get(),
-                                       command_buffer->service(), &outputter_,
-                                       group.get()));
-
-  command_buffer->set_handler(decoder.get());
-
-  gl::GLContextAttribs context_attribs;
-  context_attribs.gpu_preference = gl::GpuPreference::kHighPerformance;
-  scoped_refptr<gl::GLContext> gl_context(
-      gl::init::CreateGLContext(nullptr, gl_surface, context_attribs));
-  if (!gl_context)
-    return false;
-  platform_gpu_feature_info_.ApplyToGLContext(gl_context.get());
-
-  gl_context->MakeCurrent(gl_surface);
-
-  EGLint alpha_size, depth_size, stencil_size;
-  config_->GetAttrib(EGL_ALPHA_SIZE, &alpha_size);
-  config_->GetAttrib(EGL_DEPTH_SIZE, &depth_size);
-  config_->GetAttrib(EGL_STENCIL_SIZE, &stencil_size);
-
-  CHECK_EQ(alpha_size, 0);
-  CHECK_EQ(depth_size, 0);
-  CHECK_EQ(stencil_size, 0);
-
-  gpu::ContextCreationAttribs helper;
-  helper.bind_generates_resource = kBindGeneratesResources;
-  helper.fail_if_major_perf_caveat = false;
-  helper.lose_context_when_out_of_memory = kLoseContextWhenOutOfMemory;
-  helper.context_type = gpu::CONTEXT_TYPE_OPENGLES2;
-  helper.offscreen_framebuffer_size_for_testing = gl_surface->GetSize();
-
-  auto result = decoder->Initialize(gl_surface, gl_context.get(),
-                                    gl_surface->IsOffscreen(),
-                                    gpu::gles2::DisallowedFeatures(), helper);
-  if (result != gpu::ContextResult::kSuccess)
-    return false;
-
-  auto gles2_cmd_helper =
-      std::make_unique<gpu::gles2::GLES2CmdHelper>(command_buffer.get());
-  result = gles2_cmd_helper->Initialize(limits.command_buffer_size);
-  if (result != gpu::ContextResult::kSuccess) {
-    decoder->Destroy(true);
-    return false;
-  }
-  // Client side Capabilities queries return reference, service side return
-  // value. Here two sides are joined together.
-  capabilities_ = decoder->GetCapabilities();
-  gl_capabilities_ = decoder->GetGLCapabilities();
-
-  auto transfer_buffer =
-      std::make_unique<gpu::TransferBuffer>(gles2_cmd_helper.get());
-
-  gles2_cmd_helper_ = std::move(gles2_cmd_helper);
-  transfer_buffer_ = std::move(transfer_buffer);
-  command_buffer_ = std::move(command_buffer);
-  decoder_ = std::move(decoder);
-  gl_context_ = gl_context.get();
-
-  auto context = std::make_unique<gpu::gles2::GLES2Implementation>(
-      gles2_cmd_helper_.get(), nullptr, transfer_buffer_.get(),
-      kBindGeneratesResources, kLoseContextWhenOutOfMemory,
-      kSupportClientSideArrays, this);
-
-  result = context->Initialize(limits);
-  if (result != gpu::ContextResult::kSuccess) {
-    DestroyService();
-    return false;
-  }
-
-  context->EnableFeatureCHROMIUM("pepper3d_allow_buffers_on_multiple_targets");
-  context->EnableFeatureCHROMIUM("pepper3d_support_fixed_attribs");
-  client_gl_context_ = std::move(context);
-  return true;
-}
-
-void Context::DestroyService() {
-  DCHECK(HasService());
-  bool have_context = !WasServiceContextLost();
-  // The client gl interface might still be set to current global
-  // interface. This will be cleaned up in ApplyContextReleased
-  // with AutoCurrentContextRestore.
-  client_gl_context_.reset();
-  gl_context_ = nullptr;
-
-  transfer_buffer_.reset();
-  gles2_cmd_helper_.reset();
-  if (decoder_)
-    decoder_->Destroy(have_context);
-  decoder_.reset();
-  command_buffer_.reset();
-}
-
-bool Context::HasService() const {
-  return decoder_ != nullptr;
-}
-
-void Context::MarkServiceContextLost() {
-  decoder_->GetContextGroup()->LoseContexts(gpu::error::kMakeCurrentFailed);
-}
-
-bool Context::WasServiceContextLost() const {
-  return decoder_->WasContextLost();
-}
-
-bool Context::IsCompatibleSurface(Surface* surface) const {
-  // Inspect current_surface->config() instead of gl_surface()->IsOffscreen()
-  // because GTF windowless window surfaces might be emulated with offscreen
-  // surfaces.
-  EGLint value = EGL_NONE;
-  config_->GetAttrib(EGL_SURFACE_TYPE, &value);
-  bool context_config_is_offscreen = (value & EGL_PBUFFER_BIT) != 0;
-  surface->config()->GetAttrib(EGL_SURFACE_TYPE, &value);
-  bool surface_config_is_offscreen = (value & EGL_PBUFFER_BIT) != 0;
-  return surface_config_is_offscreen == context_config_is_offscreen;
-}
-
-bool Context::Flush(gl::GLSurface* gl_surface) {
-  if (WasServiceContextLost())
-    return false;
-  if (!gl_context_->MakeCurrent(gl_surface)) {
-    MarkServiceContextLost();
-    return false;
-  }
-  client_gl_context_->Flush();
-  return true;
-}
-
-}  // namespace egl
-}  // namespace gles2_conform_support
diff --git a/gpu/gles2_conform_support/egl/context.h b/gpu/gles2_conform_support/egl/context.h
deleted file mode 100644
index 2d71ab0..0000000
--- a/gpu/gles2_conform_support/egl/context.h
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2011 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef GPU_GLES2_CONFORM_SUPPORT_EGL_CONTEXT_H_
-#define GPU_GLES2_CONFORM_SUPPORT_EGL_CONTEXT_H_
-
-#include <memory>
-
-#include <EGL/egl.h>
-#include "base/memory/raw_ptr.h"
-#include "base/memory/ref_counted.h"
-#include "gpu/command_buffer/client/gles2_cmd_helper.h"
-#include "gpu/command_buffer/client/gpu_control.h"
-#include "gpu/command_buffer/service/command_buffer_direct.h"
-#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
-#include "gpu/command_buffer/service/gpu_tracer.h"
-#include "gpu/command_buffer/service/passthrough_discardable_manager.h"
-#include "gpu/command_buffer/service/service_discardable_manager.h"
-#include "gpu/command_buffer/service/shared_image/shared_image_manager.h"
-#include "gpu/config/gpu_driver_bug_workarounds.h"
-#include "gpu/config/gpu_preferences.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_surface.h"
-
-namespace gpu {
-class ServiceDiscardableManager;
-class TransferBuffer;
-
-namespace gles2 {
-class GLES2CmdHelper;
-class GLES2Interface;
-}  // namespace gles2
-}  // namespace gpu
-
-namespace gles2_conform_support {
-namespace egl {
-class Display;
-class Surface;
-class Config;
-
-class Context : public base::RefCountedThreadSafe<Context>,
-                public gpu::GpuControl {
- public:
-  Context(Display* display, const Config* config);
-
-  Context(const Context&) = delete;
-  Context& operator=(const Context&) = delete;
-
-  bool is_current_in_some_thread() const { return is_current_in_some_thread_; }
-  void set_is_current_in_some_thread(bool flag) {
-    is_current_in_some_thread_ = flag;
-  }
-  void MarkDestroyed();
-  bool SwapBuffers(Surface* current_surface);
-
-  static bool MakeCurrent(Context* current_context,
-                          Surface* current_surface,
-                          Context* new_context,
-                          Surface* new_surface);
-
-  static bool ValidateAttributeList(const EGLint* attrib_list);
-
-  // GpuControl implementation.
-  void SetGpuControlClient(gpu::GpuControlClient*) override;
-  const gpu::Capabilities& GetCapabilities() const override;
-  const gpu::GLCapabilities& GetGLCapabilities() const override;
-  void SignalQuery(uint32_t query, base::OnceClosure callback) override;
-  void CancelAllQueries() override;
-  void CreateGpuFence(uint32_t gpu_fence_id, ClientGpuFence source) override;
-  void GetGpuFence(uint32_t gpu_fence_id,
-                   base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)>
-                       callback) override;
-  void SetLock(base::Lock*) override;
-  void EnsureWorkVisible() override;
-  gpu::CommandBufferNamespace GetNamespaceID() const override;
-  gpu::CommandBufferId GetCommandBufferID() const override;
-  void FlushPendingWork() override;
-  uint64_t GenerateFenceSyncRelease() override;
-  bool IsFenceSyncReleased(uint64_t release) override;
-  void SignalSyncToken(const gpu::SyncToken& sync_token,
-                       base::OnceClosure callback) override;
-  void WaitSyncToken(const gpu::SyncToken& sync_token) override;
-  bool CanWaitUnverifiedSyncToken(const gpu::SyncToken& sync_token) override;
-
-  // Called by ThreadState to set the needed global variables when this context
-  // is current.
-  void ApplyCurrentContext(gl::GLSurface* current_surface);
-  static void ApplyContextReleased();
-
-  static void SetPlatformGpuFeatureInfo(
-      const gpu::GpuFeatureInfo& gpu_feature_info);
-
- private:
-  friend class base::RefCountedThreadSafe<Context>;
-  ~Context() override;
-  bool CreateService(gl::GLSurface* gl_surface);
-  void DestroyService();
-  // Returns true if the object has GL service, either a working one or one
-  // that has lost its GL context.
-  bool HasService() const;
-  void MarkServiceContextLost();
-  bool WasServiceContextLost() const;
-  bool IsCompatibleSurface(Surface* surface) const;
-  bool Flush(gl::GLSurface* gl_surface);
-
-  static gpu::GpuFeatureInfo platform_gpu_feature_info_;
-
-  raw_ptr<Display> display_;
-  raw_ptr<const Config> config_;
-  bool is_current_in_some_thread_;
-  bool is_destroyed_;
-  const gpu::GpuDriverBugWorkarounds gpu_driver_bug_workarounds_;
-  std::unique_ptr<gpu::CommandBufferDirect> command_buffer_;
-  std::unique_ptr<gpu::gles2::GLES2CmdHelper> gles2_cmd_helper_;
-
-  gpu::gles2::TraceOutputter outputter_;
-  gpu::ServiceDiscardableManager discardable_manager_;
-  gpu::PassthroughDiscardableManager passthrough_discardable_manager_;
-  gpu::SharedImageManager shared_image_manager_;
-  gpu::gles2::ShaderTranslatorCache translator_cache_;
-  gpu::gles2::FramebufferCompletenessCache completeness_cache_;
-  std::unique_ptr<gpu::gles2::GLES2Decoder> decoder_;
-  std::unique_ptr<gpu::TransferBuffer> transfer_buffer_;
-
-  scoped_refptr<gl::GLContext> gl_context_;
-
-  std::unique_ptr<gpu::gles2::GLES2Interface> client_gl_context_;
-
-  gpu::Capabilities capabilities_;
-  gpu::GLCapabilities gl_capabilities_;
-};
-
-}  // namespace egl
-}  // namespace gles2_conform_support
-
-#endif  // GPU_GLES2_CONFORM_SUPPORT_EGL_CONTEXT_H_
diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc
deleted file mode 100644
index 8d0b4bd..0000000
--- a/gpu/gles2_conform_support/egl/display.cc
+++ /dev/null
@@ -1,402 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "gpu/gles2_conform_support/egl/display.h"
-
-#include <memory>
-
-#include "base/ranges/algorithm.h"
-#include "build/build_config.h"
-#include "gpu/gles2_conform_support/egl/config.h"
-#include "gpu/gles2_conform_support/egl/context.h"
-#include "gpu/gles2_conform_support/egl/surface.h"
-#include "gpu/gles2_conform_support/egl/thread_state.h"
-#include "ui/gl/gl_display.h"
-#include "ui/gl/gl_utils.h"
-#include "ui/gl/init/gl_factory.h"
-
-namespace gles2_conform_support {
-namespace egl {
-
-Display::Display()
-    : is_initialized_(false),
-      next_create_window_surface_creates_pbuffer_(false),
-      window_surface_pbuffer_width_(0),
-      window_surface_pbuffer_height_(0) {}
-
-Display::~Display() {
-  surfaces_.clear();
-  contexts_.clear();
-}
-void Display::SetNextCreateWindowSurfaceCreatesPBuffer(EGLint width,
-                                                       EGLint height) {
-  next_create_window_surface_creates_pbuffer_ = true;
-  window_surface_pbuffer_width_ = width;
-  window_surface_pbuffer_height_ = height;
-}
-
-EGLBoolean Display::Initialize(ThreadState* ts, EGLint* major, EGLint* minor) {
-  base::AutoLock auto_lock(lock_);
-  is_initialized_ = true;
-
-  if (major)
-    *major = 1;
-  if (minor)
-    *minor = 4;
-  return ts->ReturnSuccess(EGL_TRUE);
-}
-
-EGLBoolean Display::Terminate(ThreadState* ts) {
-  base::AutoLock auto_lock(lock_);
-  is_initialized_ = false;
-  surfaces_.clear();
-  for (const auto& context : contexts_)
-    context->MarkDestroyed();
-  contexts_.clear();
-  return ts->ReturnSuccess(EGL_TRUE);
-}
-
-const char* Display::QueryString(ThreadState* ts, EGLint name) {
-  base::AutoLock auto_lock(lock_);
-  if (!is_initialized_)
-    return ts->ReturnError<const char*>(EGL_NOT_INITIALIZED, nullptr);
-  switch (name) {
-    case EGL_CLIENT_APIS:
-      return ts->ReturnSuccess("OpenGL_ES");
-    case EGL_EXTENSIONS:
-      return ts->ReturnSuccess("");
-    case EGL_VENDOR:
-      return ts->ReturnSuccess("Google LLC");
-    case EGL_VERSION:
-      return ts->ReturnSuccess("1.4");
-    default:
-      return ts->ReturnError<const char*>(EGL_BAD_PARAMETER, nullptr);
-  }
-}
-
-EGLBoolean Display::ChooseConfig(ThreadState* ts,
-                                 const EGLint* attrib_list,
-                                 EGLConfig* configs,
-                                 EGLint config_size,
-                                 EGLint* num_config) {
-  base::AutoLock auto_lock(lock_);
-  if (!is_initialized_)
-    return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
-  if (num_config == nullptr)
-    return ts->ReturnError(EGL_BAD_PARAMETER, EGL_FALSE);
-  if (!Config::ValidateAttributeList(attrib_list))
-    return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
-  InitializeConfigsIfNeeded();
-  if (!configs)
-    config_size = 0;
-  *num_config = 0;
-  for (size_t i = 0; i < std::size(configs_); ++i) {
-    if (configs_[i]->Matches(attrib_list)) {
-      if (*num_config < config_size) {
-        configs[*num_config] = configs_[i].get();
-      }
-      ++*num_config;
-    }
-  }
-  return ts->ReturnSuccess(EGL_TRUE);
-}
-
-EGLBoolean Display::GetConfigs(ThreadState* ts,
-                               EGLConfig* configs,
-                               EGLint config_size,
-                               EGLint* num_config) {
-  base::AutoLock auto_lock(lock_);
-  if (!is_initialized_)
-    return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
-  if (num_config == nullptr)
-    return ts->ReturnError(EGL_BAD_PARAMETER, EGL_FALSE);
-  InitializeConfigsIfNeeded();
-  if (!configs)
-    config_size = 0;
-  *num_config = std::size(configs_);
-  size_t count =
-      std::min(std::size(configs_), static_cast<size_t>(config_size));
-  for (size_t i = 0; i < count; ++i)
-    configs[i] = configs_[i].get();
-  return ts->ReturnSuccess(EGL_TRUE);
-}
-
-bool Display::IsValidNativeWindow(EGLNativeWindowType win) {
-#if BUILDFLAG(IS_WIN)
-  return ::IsWindow(win) != FALSE;
-#else
-  // TODO(alokp): Validate window handle.
-  return true;
-#endif  // BUILDFLAG(IS_WIN)
-}
-
-EGLBoolean Display::GetConfigAttrib(ThreadState* ts,
-                                    EGLConfig cfg,
-                                    EGLint attribute,
-                                    EGLint* value) {
-  base::AutoLock auto_lock(lock_);
-  if (!is_initialized_)
-    return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
-  const egl::Config* config = GetConfig(cfg);
-  if (!config)
-    return ts->ReturnError(EGL_BAD_CONFIG, EGL_FALSE);
-  if (!config->GetAttrib(attribute, value))
-    return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
-  return ts->ReturnSuccess(EGL_TRUE);
-}
-
-EGLSurface Display::CreatePbufferSurface(ThreadState* ts,
-                                         EGLConfig cfg,
-                                         const EGLint* attrib_list) {
-  base::AutoLock auto_lock(lock_);
-  if (!is_initialized_)
-    return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_NO_SURFACE);
-  const egl::Config* config = GetConfig(cfg);
-  if (!config)
-    return ts->ReturnError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
-  EGLint value = EGL_NONE;
-  config->GetAttrib(EGL_SURFACE_TYPE, &value);
-  if ((value & EGL_PBUFFER_BIT) == 0)
-    return ts->ReturnError(EGL_BAD_MATCH, EGL_NO_SURFACE);
-  if (!egl::Surface::ValidatePbufferAttributeList(attrib_list))
-    return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-
-  int width = 1;
-  int height = 1;
-  if (attrib_list) {
-    for (const int32_t* attr = attrib_list; attr[0] != EGL_NONE; attr += 2) {
-      switch (attr[0]) {
-        case EGL_WIDTH:
-          width = attr[1];
-          break;
-        case EGL_HEIGHT:
-          height = attr[1];
-          break;
-      }
-    }
-  }
-  return DoCreatePbufferSurface(ts, config, width, height);
-}
-
-EGLSurface Display::DoCreatePbufferSurface(ThreadState* ts,
-                                           const Config* config,
-                                           EGLint width,
-                                           EGLint height) {
-  lock_.AssertAcquired();
-  scoped_refptr<gl::GLSurface> gl_surface;
-  gl_surface = gl::init::CreateOffscreenGLSurface(gl::GetDefaultDisplay(),
-                                                  gfx::Size(width, height));
-  if (!gl_surface)
-    return ts->ReturnError(EGL_BAD_ALLOC, nullptr);
-  surfaces_.emplace_back(new Surface(gl_surface.get(), config));
-  return ts->ReturnSuccess<EGLSurface>(surfaces_.back().get());
-}
-
-EGLSurface Display::CreateWindowSurface(ThreadState* ts,
-                                        EGLConfig cfg,
-                                        EGLNativeWindowType win,
-                                        const EGLint* attrib_list) {
-  base::AutoLock auto_lock(lock_);
-  if (!is_initialized_)
-    return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_NO_SURFACE);
-  const egl::Config* config = GetConfig(cfg);
-  if (!config)
-    return ts->ReturnError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
-  EGLint value = EGL_NONE;
-  config->GetAttrib(EGL_SURFACE_TYPE, &value);
-  if ((value & EGL_WINDOW_BIT) == 0)
-    return ts->ReturnError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
-  if (!next_create_window_surface_creates_pbuffer_ && !IsValidNativeWindow(win))
-    return ts->ReturnError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
-  if (!Surface::ValidateWindowAttributeList(attrib_list))
-    return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-  if (next_create_window_surface_creates_pbuffer_) {
-    EGLSurface result = DoCreatePbufferSurface(ts, config,
-                                               window_surface_pbuffer_width_,
-                                               window_surface_pbuffer_height_);
-    next_create_window_surface_creates_pbuffer_ = false;
-    window_surface_pbuffer_width_ = 0;
-    window_surface_pbuffer_height_ = 0;
-    return result;
-  }
-  scoped_refptr<gl::GLSurface> gl_surface;
-#if BUILDFLAG(IS_MAC)
-  gfx::AcceleratedWidget widget = gfx::kNullAcceleratedWidget;
-#else
-  gfx::AcceleratedWidget widget = static_cast<gfx::AcceleratedWidget>(win);
-#endif
-  gl_surface = gl::init::CreateViewGLSurface(gl::GetDefaultDisplay(), widget);
-  if (!gl_surface)
-    return ts->ReturnError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
-  surfaces_.emplace_back(new Surface(gl_surface.get(), config));
-  return ts->ReturnSuccess(surfaces_.back().get());
-}
-
-EGLBoolean Display::DestroySurface(ThreadState* ts, EGLSurface sfe) {
-  base::AutoLock auto_lock(lock_);
-  if (!is_initialized_)
-    return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
-  auto it = base::ranges::find(surfaces_, sfe);
-  if (it == surfaces_.end())
-    return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
-  surfaces_.erase(it);
-  return ts->ReturnSuccess(EGL_TRUE);
-}
-
-EGLBoolean Display::ReleaseCurrent(ThreadState* ts) {
-  base::AutoLock auto_lock(lock_);
-  if (!is_initialized_)
-    return ts->ReturnSuccess(EGL_TRUE);
-  ThreadState::AutoCurrentContextRestore accr(ts);
-  if (ts->current_context()) {
-    Context::MakeCurrent(ts->current_context(), ts->current_surface(), nullptr,
-                         nullptr);
-    accr.SetCurrent(nullptr, nullptr);
-  }
-  return ts->ReturnSuccess(EGL_TRUE);
-}
-
-EGLBoolean Display::MakeCurrent(ThreadState* ts,
-                                EGLSurface draw,
-                                EGLSurface read,
-                                EGLSurface ctx) {
-  base::AutoLock auto_lock(lock_);
-  if (!is_initialized_)
-    return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
-  ThreadState::AutoCurrentContextRestore accr(ts);
-  // Client might have called use because it changed some other gl binding
-  // global state. For example, the client might have called eglMakeCurrent on
-  // the same EGL as what command buffer uses. The client probably knows that
-  // this invalidates the internal state of command buffer, too. So reset the
-  // current context with accr in any case, regardless whether context or
-  // surface pointer changes.
-  Surface* new_surface = GetSurface(draw);
-  if (!new_surface)
-    return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
-  new_surface = GetSurface(read);
-  if (!new_surface)
-    return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
-  egl::Context* new_context = GetContext(ctx);
-  if (!new_context)
-    return ts->ReturnError(EGL_BAD_CONTEXT, EGL_FALSE);
-  if (draw != read)
-    return ts->ReturnError(EGL_BAD_MATCH, EGL_FALSE);
-
-  Surface* current_surface = ts->current_surface();
-  Context* current_context = ts->current_context();
-
-  if (current_context != new_context &&
-      new_context->is_current_in_some_thread())
-    return ts->ReturnError(EGL_BAD_ACCESS, EGL_FALSE);
-
-  if (current_surface != new_surface &&
-      new_surface->is_current_in_some_thread())
-    return ts->ReturnError(EGL_BAD_ACCESS, EGL_FALSE);
-
-  if (!Context::MakeCurrent(current_context,
-                            current_context ? current_surface : nullptr,
-                            new_context, new_context ? new_surface : nullptr))
-    return ts->ReturnError(EGL_BAD_MATCH, EGL_FALSE);
-
-  accr.SetCurrent(new_surface, new_context);
-  return ts->ReturnSuccess(EGL_TRUE);
-}
-
-EGLBoolean Display::SwapBuffers(ThreadState* ts, EGLSurface sfe) {
-  base::AutoLock auto_lock(lock_);
-  if (!is_initialized_)
-    return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
-  egl::Surface* surface = GetSurface(sfe);
-  if (!surface)
-    return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
-  if (ts->current_surface() != surface)
-    return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
-  if (!ts->current_context()->SwapBuffers(surface))
-    ts->ReturnError(EGL_CONTEXT_LOST, EGL_FALSE);
-  return ts->ReturnSuccess(EGL_TRUE);
-}
-
-EGLContext Display::CreateContext(ThreadState* ts,
-                                  EGLConfig cfg,
-                                  EGLContext share_ctx,
-                                  const EGLint* attrib_list) {
-  base::AutoLock auto_lock(lock_);
-  if (!is_initialized_)
-    return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_NO_CONTEXT);
-  if (share_ctx != EGL_NO_CONTEXT) {
-    egl::Context* share_context = GetContext(share_ctx);
-    if (!share_context)
-      return ts->ReturnError(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
-    // TODO(alokp): Add support for shared contexts.
-    return ts->ReturnError(EGL_BAD_MATCH, EGL_NO_CONTEXT);
-  }
-
-  if (!egl::Context::ValidateAttributeList(attrib_list))
-    return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
-  const egl::Config* config = GetConfig(cfg);
-  if (!config)
-    return ts->ReturnError(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
-  scoped_refptr<Context> context(new Context(this, config));
-  if (!context)
-    return ts->ReturnError(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
-  contexts_.emplace_back(context.get());
-  return ts->ReturnSuccess<EGLContext>(context.get());
-}
-
-EGLBoolean Display::DestroyContext(ThreadState* ts, EGLContext ctx) {
-  base::AutoLock auto_lock(lock_);
-  if (!is_initialized_)
-    return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
-  auto it = base::ranges::find(contexts_, ctx);
-  if (it == contexts_.end())
-    return ts->ReturnError(EGL_BAD_CONTEXT, EGL_FALSE);
-  (*it)->MarkDestroyed();
-  contexts_.erase(it);
-  return ts->ReturnSuccess(EGL_TRUE);
-}
-
-uint64_t Display::GenerateFenceSyncRelease() {
-  base::AutoLock auto_lock(lock_);
-  return next_fence_sync_release_++;
-}
-
-void Display::InitializeConfigsIfNeeded() {
-  lock_.AssertAcquired();
-  if (!configs_[0]) {
-    // The interface offers separate configs for window and pbuffer.
-    // This way we can record the client intention at context creation time.
-    // The GL implementation (gl::GLContext and gl::GLSurface) needs this
-    // distinction when creating a context.
-    configs_[0] = std::make_unique<Config>(EGL_WINDOW_BIT);
-    configs_[1] = std::make_unique<Config>(EGL_PBUFFER_BIT);
-  }
-}
-
-const Config* Display::GetConfig(EGLConfig cfg) {
-  lock_.AssertAcquired();
-  for (const auto& config : configs_) {
-    if (config.get() == cfg)
-      return config.get();
-  }
-  return nullptr;
-}
-
-Surface* Display::GetSurface(EGLSurface surface) {
-  lock_.AssertAcquired();
-  auto it = base::ranges::find(surfaces_, surface);
-  if (it == surfaces_.end())
-    return nullptr;
-  return it->get();
-}
-
-Context* Display::GetContext(EGLContext context) {
-  lock_.AssertAcquired();
-  auto it = base::ranges::find(contexts_, context);
-  if (it == contexts_.end())
-    return nullptr;
-  return it->get();
-}
-
-}  // namespace egl
-}  // namespace gles2_conform_support
diff --git a/gpu/gles2_conform_support/egl/display.h b/gpu/gles2_conform_support/egl/display.h
deleted file mode 100644
index 7dbde41..0000000
--- a/gpu/gles2_conform_support/egl/display.h
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef GPU_GLES2_CONFORM_SUPPORT_EGL_DISPLAY_H_
-#define GPU_GLES2_CONFORM_SUPPORT_EGL_DISPLAY_H_
-
-#include <EGL/egl.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-#include <vector>
-
-#include "base/memory/ref_counted.h"
-#include "base/synchronization/lock.h"
-
-namespace gles2_conform_support::egl {
-
-class Config;
-class Context;
-class Surface;
-class ThreadState;
-
-class Display {
- public:
-  explicit Display();
-
-  Display(const Display&) = delete;
-  Display& operator=(const Display&) = delete;
-
-  ~Display();
-
-  bool is_initialized() const { return is_initialized_; }
-
-  void ReleaseCurrentForReleaseThread(ThreadState*);
-
-  // A function for windowless GTF tests.
-  void SetNextCreateWindowSurfaceCreatesPBuffer(EGLint width, EGLint height);
-
-  EGLBoolean Initialize(ThreadState* ts, EGLint* major, EGLint* minor);
-  EGLBoolean Terminate(ThreadState* ts);
-  const char* QueryString(ThreadState* ts, EGLint name);
-
-  // Config routines.
-  EGLBoolean GetConfigAttrib(ThreadState* ts,
-                             EGLConfig cfg,
-                             EGLint attribute,
-                             EGLint* value);
-  EGLBoolean ChooseConfig(ThreadState* ts,
-                          const EGLint* attrib_list,
-                          EGLConfig* configs,
-                          EGLint config_size,
-                          EGLint* num_config);
-  EGLBoolean GetConfigs(ThreadState*,
-                        EGLConfig*,
-                        EGLint config_size,
-                        EGLint* num_config);
-
-  // Surface routines.
-  static bool IsValidNativeWindow(EGLNativeWindowType);
-  EGLSurface CreatePbufferSurface(ThreadState*,
-                                  EGLConfig,
-                                  const EGLint* attrib_list);
-  EGLSurface CreateWindowSurface(ThreadState*,
-                                 EGLConfig,
-                                 EGLNativeWindowType win,
-                                 const EGLint* attrib_list);
-  EGLBoolean DestroySurface(ThreadState*, EGLSurface);
-  EGLBoolean SwapBuffers(ThreadState*, EGLSurface);
-
-  // Context routines.
-  EGLContext CreateContext(ThreadState*,
-                           EGLConfig,
-                           EGLSurface share_ctx,
-                           const EGLint* attrib_list);
-  EGLBoolean DestroyContext(ThreadState*, EGLContext);
-
-  EGLBoolean ReleaseCurrent(ThreadState*);
-  EGLBoolean MakeCurrent(ThreadState*, EGLSurface, EGLSurface, EGLContext);
-
-  uint64_t GenerateFenceSyncRelease();
-
- private:
-  void InitializeConfigsIfNeeded();
-  const Config* GetConfig(EGLConfig);
-  Surface* GetSurface(EGLSurface);
-  Context* GetContext(EGLContext);
-  EGLSurface DoCreatePbufferSurface(ThreadState* ts,
-                                    const Config* config,
-                                    EGLint width,
-                                    EGLint height);
-
-  base::Lock lock_;
-  bool is_initialized_;
-  uint64_t next_fence_sync_release_;
-  std::vector<scoped_refptr<Surface>> surfaces_;
-  std::vector<scoped_refptr<Context>> contexts_;
-  std::unique_ptr<Config> configs_[2];
-
-  // GTF windowless support.
-  bool next_create_window_surface_creates_pbuffer_;
-  EGLint window_surface_pbuffer_width_;
-  EGLint window_surface_pbuffer_height_;
-};
-
-}  // namespace gles2_conform_support::egl
-
-#endif  // GPU_GLES2_CONFORM_SUPPORT_EGL_DISPLAY_H_
diff --git a/gpu/gles2_conform_support/egl/egl.cc b/gpu/gles2_conform_support/egl/egl.cc
deleted file mode 100644
index f4130cf..0000000
--- a/gpu/gles2_conform_support/egl/egl.cc
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <EGL/egl.h>
-#include <stdint.h>
-
-#include "gpu/command_buffer/client/gles2_lib.h"
-#include "gpu/gles2_conform_support/egl/config.h"
-#include "gpu/gles2_conform_support/egl/context.h"
-#include "gpu/gles2_conform_support/egl/display.h"
-#include "gpu/gles2_conform_support/egl/surface.h"
-#include "gpu/gles2_conform_support/egl/thread_state.h"
-
-using gles2_conform_support::egl::Display;
-using gles2_conform_support::egl::ThreadState;
-
-extern "C" {
-EGLAPI EGLint EGLAPIENTRY eglGetError() {
-  return ThreadState::Get()->ConsumeErrorCode();
-}
-
-EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id) {
-  if (display_id != EGL_DEFAULT_DISPLAY)
-    return EGL_NO_DISPLAY;
-  return ThreadState::Get()->GetDefaultDisplay();
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy,
-                                            EGLint* major,
-                                            EGLint* minor) {
-  ThreadState* ts = ThreadState::Get();
-  Display* display = ts->GetDisplay(dpy);
-  if (!display)
-    return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
-  return display->Initialize(ts, major, minor);
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy) {
-  ThreadState* ts = ThreadState::Get();
-  Display* display = ts->GetDisplay(dpy);
-  if (!display)
-    return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
-  return display->Terminate(ts);
-}
-
-EGLAPI const char* EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name) {
-  ThreadState* ts = ThreadState::Get();
-  if (dpy == EGL_NO_DISPLAY) {
-    switch (name) {
-      case EGL_EXTENSIONS:
-        return ts->ReturnSuccess("");
-      case EGL_VERSION:
-        return ts->ReturnSuccess("1.4");
-      default:
-        break;
-    }
-  }
-  Display* display = ts->GetDisplay(dpy);
-  if (!display)
-    return ts->ReturnError<const char*>(EGL_BAD_DISPLAY, nullptr);
-  return display->QueryString(ts, name);
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy,
-                                              const EGLint* attrib_list,
-                                              EGLConfig* configs,
-                                              EGLint config_size,
-                                              EGLint* num_config) {
-  ThreadState* ts = ThreadState::Get();
-  Display* display = ts->GetDisplay(dpy);
-  if (!display)
-    return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
-  return display->ChooseConfig(ts, attrib_list, configs, config_size,
-                               num_config);
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy,
-                                            EGLConfig* configs,
-                                            EGLint config_size,
-                                            EGLint* num_config) {
-  ThreadState* ts = ThreadState::Get();
-  Display* display = ts->GetDisplay(dpy);
-  if (!display)
-    return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
-  return display->GetConfigs(ts, configs, config_size, num_config);
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy,
-                                                 EGLConfig cfg,
-                                                 EGLint attribute,
-                                                 EGLint* value) {
-  ThreadState* ts = ThreadState::Get();
-  Display* display = ts->GetDisplay(dpy);
-  if (!display)
-    return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
-  return display->GetConfigAttrib(ts, cfg, attribute, value);
-}
-
-EGLAPI EGLSurface EGLAPIENTRY
-eglCreateWindowSurface(EGLDisplay dpy,
-                       EGLConfig cfg,
-                       EGLNativeWindowType win,
-                       const EGLint* attrib_list) {
-  ThreadState* ts = ThreadState::Get();
-  Display* display = ts->GetDisplay(dpy);
-  if (!display)
-    return ts->ReturnError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
-  return display->CreateWindowSurface(ts, cfg, win, attrib_list);
-}
-
-EGLAPI EGLSurface EGLAPIENTRY
-eglCreatePbufferSurface(EGLDisplay dpy,
-                        EGLConfig cfg,
-                        const EGLint* attrib_list) {
-  ThreadState* ts = ThreadState::Get();
-  Display* display = ts->GetDisplay(dpy);
-  if (!display)
-    return ts->ReturnError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
-  return display->CreatePbufferSurface(ts, cfg, attrib_list);
-}
-
-EGLAPI EGLSurface EGLAPIENTRY
-eglCreatePixmapSurface(EGLDisplay dpy,
-                       EGLConfig config,
-                       EGLNativePixmapType pixmap,
-                       const EGLint* attrib_list) {
-  return EGL_NO_SURFACE;
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy,
-                                                EGLSurface sfe) {
-  ThreadState* ts = ThreadState::Get();
-  Display* display = ts->GetDisplay(dpy);
-  if (!display)
-    return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
-  return display->DestroySurface(ts, sfe);
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy,
-                                              EGLSurface surface,
-                                              EGLint attribute,
-                                              EGLint* value) {
-  return EGL_FALSE;
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api) {
-  return EGL_FALSE;
-}
-
-EGLAPI EGLenum EGLAPIENTRY eglQueryAPI() {
-  return EGL_OPENGL_ES_API;
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void) {
-  return EGL_FALSE;
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void) {
-  ThreadState::ReleaseThread();
-  return EGL_TRUE;
-}
-
-EGLAPI EGLSurface EGLAPIENTRY
-eglCreatePbufferFromClientBuffer(EGLDisplay dpy,
-                                 EGLenum buftype,
-                                 EGLClientBuffer buffer,
-                                 EGLConfig config,
-                                 const EGLint* attrib_list) {
-  return EGL_NO_SURFACE;
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy,
-                                               EGLSurface surface,
-                                               EGLint attribute,
-                                               EGLint value) {
-  return EGL_FALSE;
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy,
-                                              EGLSurface surface,
-                                              EGLint buffer) {
-  return EGL_FALSE;
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy,
-                                                 EGLSurface surface,
-                                                 EGLint buffer) {
-  return EGL_FALSE;
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval) {
-  return EGL_FALSE;
-}
-
-EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy,
-                                               EGLConfig cfg,
-                                               EGLContext share_ctx,
-                                               const EGLint* attrib_list) {
-  ThreadState* ts = ThreadState::Get();
-  Display* display = ts->GetDisplay(dpy);
-  if (!display)
-    return ts->ReturnError(EGL_BAD_DISPLAY, EGL_NO_CONTEXT);
-  return display->CreateContext(ts, cfg, share_ctx, attrib_list);
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy,
-                                                EGLContext ctx) {
-  ThreadState* ts = ThreadState::Get();
-  Display* display = ts->GetDisplay(dpy);
-  if (!display)
-    return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
-  return display->DestroyContext(ts, ctx);
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy,
-                                             EGLSurface draw,
-                                             EGLSurface read,
-                                             EGLContext ctx) {
-  ThreadState* ts = ThreadState::Get();
-  if (draw == EGL_NO_SURFACE && read == EGL_NO_SURFACE &&
-      ctx == EGL_NO_CONTEXT) {
-    Display* display =
-        dpy == EGL_NO_DISPLAY ? ts->GetDefaultDisplay() : ts->GetDisplay(dpy);
-    if (!display)
-      return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
-    return display->ReleaseCurrent(ts);
-  }
-  Display* display = ts->GetDisplay(dpy);
-  if (!display)
-    return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
-  return display->MakeCurrent(ts, draw, read, ctx);
-}
-
-EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext() {
-  return EGL_NO_CONTEXT;
-}
-
-EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw) {
-  return EGL_NO_SURFACE;
-}
-
-EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay() {
-  return EGL_NO_DISPLAY;
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy,
-                                              EGLContext ctx,
-                                              EGLint attribute,
-                                              EGLint* value) {
-  return EGL_FALSE;
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL() {
-  return EGL_FALSE;
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine) {
-  return EGL_FALSE;
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface sfe) {
-  ThreadState* ts = ThreadState::Get();
-  Display* display = ts->GetDisplay(dpy);
-  if (!display)
-    return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
-  return display->SwapBuffers(ts, sfe);
-}
-
-EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy,
-                                             EGLSurface surface,
-                                             EGLNativePixmapType target) {
-  return EGL_FALSE;
-}
-
-/* Now, define eglGetProcAddress using the generic function ptr. type */
-EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY
-eglGetProcAddress(const char* procname) {
-  return reinterpret_cast<__eglMustCastToProperFunctionPointerType>(
-      gles2::GetGLFunctionPointer(procname));
-}
-}  // extern "C"
diff --git a/gpu/gles2_conform_support/egl/surface.cc b/gpu/gles2_conform_support/egl/surface.cc
deleted file mode 100644
index c32e0a1..0000000
--- a/gpu/gles2_conform_support/egl/surface.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2011 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "gpu/gles2_conform_support/egl/surface.h"
-#include "ui/gl/gl_surface.h"
-
-namespace gles2_conform_support {
-namespace egl {
-
-Surface::Surface(gl::GLSurface* gl_surface, const Config* config)
-    : is_current_in_some_thread_(false),
-      gl_surface_(gl_surface),
-      config_(config) {}
-
-Surface::~Surface() = default;
-
-gl::GLSurface* Surface::gl_surface() const {
-  return gl_surface_.get();
-}
-
-const Config* Surface::config() const {
-  return config_;
-}
-
-bool Surface::ValidatePbufferAttributeList(const EGLint* attrib_list) {
-  if (attrib_list) {
-    for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
-      switch (attrib_list[i]) {
-        case EGL_WIDTH:
-        case EGL_HEIGHT:
-          break;
-        default:
-          return false;
-      }
-    }
-  }
-  return true;
-}
-
-bool Surface::ValidateWindowAttributeList(const EGLint* attrib_list) {
-  if (attrib_list) {
-    if (attrib_list[0] != EGL_NONE)
-      return false;
-  }
-  return true;
-}
-}  // namespace egl
-}  // namespace gles2_conform_support
diff --git a/gpu/gles2_conform_support/egl/surface.h b/gpu/gles2_conform_support/egl/surface.h
deleted file mode 100644
index 7e585de..0000000
--- a/gpu/gles2_conform_support/egl/surface.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2011 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef GPU_GLES2_CONFORM_SUPPORT_EGL_SURFACE_H_
-#define GPU_GLES2_CONFORM_SUPPORT_EGL_SURFACE_H_
-
-#include <EGL/egl.h>
-
-#include "base/memory/raw_ptr.h"
-#include "base/memory/ref_counted.h"
-namespace gl {
-class GLSurface;
-}
-
-namespace gles2_conform_support {
-namespace egl {
-class Config;
-
-class Surface : public base::RefCountedThreadSafe<Surface> {
- public:
-  explicit Surface(gl::GLSurface* gl_surface, const Config* config);
-
-  Surface(const Surface&) = delete;
-  Surface& operator=(const Surface&) = delete;
-
-  void set_is_current_in_some_thread(bool flag) {
-    is_current_in_some_thread_ = flag;
-  }
-  bool is_current_in_some_thread() const { return is_current_in_some_thread_; }
-  gl::GLSurface* gl_surface() const;
-  const Config* config() const;
-  static bool ValidatePbufferAttributeList(const EGLint* attrib_list);
-  static bool ValidateWindowAttributeList(const EGLint* attrib_list);
-
- private:
-  friend class base::RefCountedThreadSafe<Surface>;
-  ~Surface();
-  bool is_current_in_some_thread_;
-  scoped_refptr<gl::GLSurface> gl_surface_;
-  raw_ptr<const Config> config_;
-};
-
-}  // namespace egl
-}  // namespace gles2_conform_support
-
-#endif  // GPU_GLES2_CONFORM_SUPPORT_EGL_SURFACE_H_
diff --git a/gpu/gles2_conform_support/egl/test_support.cc b/gpu/gles2_conform_support/egl/test_support.cc
deleted file mode 100644
index 974f7d3..0000000
--- a/gpu/gles2_conform_support/egl/test_support.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2016 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "test_support.h"
-#include "gpu/gles2_conform_support/egl/display.h"
-#include "gpu/gles2_conform_support/egl/thread_state.h"
-
-#if defined(COMPONENT_BUILD) && defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY)
-bool g_command_buffer_gles_has_atexit_manager;
-#endif
-
-extern "C" {
-EGLAPI void EGLAPIENTRY
-CommandBufferGLESSetNextCreateWindowSurfaceCreatesPBuffer(EGLDisplay dpy,
-                                                          EGLint width,
-                                                          EGLint height) {
-  gles2_conform_support::egl::ThreadState* ts =
-      gles2_conform_support::egl::ThreadState::Get();
-  gles2_conform_support::egl::Display* display = ts->GetDisplay(dpy);
-  if (!display)
-    return;
-  display->SetNextCreateWindowSurfaceCreatesPBuffer(width, height);
-}
-}
diff --git a/gpu/gles2_conform_support/egl/test_support.h b/gpu/gles2_conform_support/egl/test_support.h
deleted file mode 100644
index e583a77..0000000
--- a/gpu/gles2_conform_support/egl/test_support.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2016 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef GPU_GLES2_CONFORM_SUPPORT_EGL_TEST_SUPPORT_H_
-#define GPU_GLES2_CONFORM_SUPPORT_EGL_TEST_SUPPORT_H_
-
-#include <EGL/egl.h>
-
-#if defined(COMPONENT_BUILD) && defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY)
-// A variable used for communicating whether the app has initialized the global
-// variables.
-// On component build, the dynamic library and the Chromium test
-// runner executable refer to the same global variables. Any non-Chromium client
-// of the dynamic library will not initialize the globabl variables.
-// On non-component (static) build, the library and the runner have distinct
-// global variables.
-EGLAPI extern EGLAPIENTRY bool g_command_buffer_gles_has_atexit_manager;
-#endif
-
-extern "C" {
-// A function to support GTF windowless tests. gles2_conform_test_windowless and
-// khronos_glcts_test_windowless create "windowless" native windows and render
-// to those. The test runners do not at the moment implement creating said
-// windowless native windows. This call sets the system so that it will create a
-// pbuffer when eglCreateWindow is called.
-EGLAPI EGLAPIENTRY void
-CommandBufferGLESSetNextCreateWindowSurfaceCreatesPBuffer(EGLDisplay eglDisplay,
-                                                          EGLint width,
-                                                          EGLint height);
-}
-#endif  // GPU_GLES2_CONFORM_SUPPORT_EGL_TEST_SUPPORT_H_
diff --git a/gpu/gles2_conform_support/egl/thread_state.cc b/gpu/gles2_conform_support/egl/thread_state.cc
deleted file mode 100644
index 55d9032..0000000
--- a/gpu/gles2_conform_support/egl/thread_state.cc
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2016 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "gpu/gles2_conform_support/egl/thread_state.h"
-
-#include "base/at_exit.h"
-#include "base/command_line.h"
-#include "base/environment.h"
-#include "base/lazy_instance.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "build/build_config.h"
-#include "gpu/command_buffer/client/gles2_lib.h"
-#include "gpu/command_buffer/common/thread_local.h"
-#include "gpu/config/gpu_info_collector.h"
-#include "gpu/config/gpu_preferences.h"
-#include "gpu/config/gpu_util.h"
-#include "gpu/gles2_conform_support/egl/context.h"
-#include "gpu/gles2_conform_support/egl/display.h"
-#include "gpu/gles2_conform_support/egl/surface.h"
-#include "gpu/gles2_conform_support/egl/test_support.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_display.h"
-#include "ui/gl/gl_surface.h"
-#include "ui/gl/gl_switches.h"
-#include "ui/gl/init/gl_factory.h"
-
-#if BUILDFLAG(IS_OZONE)
-#include "ui/ozone/public/ozone_platform.h"
-#endif
-
-namespace gles2_conform_support {
-// Thread local key for ThreadState instance. Accessed when holding g_egl_lock
-// only, since the initialization can not be Guaranteed otherwise.  Not in
-// anonymous namespace due to Mac OS X 10.6 linker. See gles2_lib.cc.
-static gpu::ThreadLocalKey g_egl_thread_state_key;
-
-namespace {
-base::LazyInstance<base::Lock>::Leaky g_egl_lock;
-int g_egl_active_thread_count;
-
-egl::Display* g_egl_default_display;
-
-#if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY)
-// egl::Display is used for comformance tests and command_buffer_gles.  We only
-// need the exit manager for the command_buffer_gles library.
-base::AtExitManager* g_exit_manager;
-#endif
-}  // namespace
-
-namespace egl {
-
-egl::ThreadState* ThreadState::Get() {
-  base::AutoLock lock(g_egl_lock.Get());
-  if (g_egl_active_thread_count == 0) {
-#if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY)
-#if defined(COMPONENT_BUILD)
-    if (!g_command_buffer_gles_has_atexit_manager)
-      g_exit_manager = new base::AtExitManager;
-#else
-    g_exit_manager = new base::AtExitManager;
-#endif
-#endif
-    gles2::Initialize();
-
-    if (gl::GetGLImplementation() == gl::kGLImplementationNone) {
-      base::CommandLine::StringVector argv;
-      std::unique_ptr<base::Environment> env(base::Environment::Create());
-      std::string env_string;
-      env->GetVar("CHROME_COMMAND_BUFFER_GLES2_ARGS", &env_string);
-#if BUILDFLAG(IS_WIN)
-      argv =
-          base::SplitString(base::UTF8ToWide(env_string), base::kWhitespaceWide,
-                            base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
-      argv.insert(argv.begin(), base::UTF8ToWide("dummy"));
-#else
-      argv =
-          base::SplitString(env_string, base::kWhitespaceASCII,
-                            base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
-      argv.insert(argv.begin(), "dummy");
-#endif
-      base::CommandLine::Init(0, nullptr);
-      base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-      // Need to call both Init and InitFromArgv, since Windows does not use
-      // argc, argv in CommandLine::Init(argc, argv).
-      command_line->InitFromArgv(argv);
-#if BUILDFLAG(IS_OZONE)
-      ui::OzonePlatform::InitializeForGPU(ui::OzonePlatform::InitParams());
-#endif
-      gl::GLDisplay* display = gl::init::InitializeGLNoExtensionsOneOff(
-          /*init_bindings=*/true,
-          /*gpu_preference=*/gl::GpuPreference::kDefault);
-      gpu::GpuFeatureInfo gpu_feature_info;
-      if (!command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds)) {
-        gpu::GPUInfo gpu_info;
-        gpu::CollectGraphicsInfoForTesting(&gpu_info);
-        gpu_feature_info = gpu::ComputeGpuFeatureInfo(
-            gpu_info, gpu::GpuPreferences(), command_line, nullptr);
-        Context::SetPlatformGpuFeatureInfo(gpu_feature_info);
-      }
-
-      gl::init::SetDisabledExtensionsPlatform(
-          gpu_feature_info.disabled_extensions);
-      gl::init::InitializeExtensionSettingsOneOffPlatform(display);
-    }
-
-    g_egl_default_display = new egl::Display();
-    g_egl_thread_state_key = gpu::ThreadLocalAlloc();
-  }
-  egl::ThreadState* thread_state = static_cast<egl::ThreadState*>(
-      gpu::ThreadLocalGetValue(g_egl_thread_state_key));
-  if (!thread_state) {
-    thread_state = new egl::ThreadState;
-    gpu::ThreadLocalSetValue(g_egl_thread_state_key, thread_state);
-    ++g_egl_active_thread_count;
-  }
-  return thread_state;
-}
-
-void ThreadState::ReleaseThread() {
-  base::AutoLock lock(g_egl_lock.Get());
-  if (g_egl_active_thread_count == 0)
-    return;
-
-  egl::ThreadState* thread_state = static_cast<egl::ThreadState*>(
-      gpu::ThreadLocalGetValue(g_egl_thread_state_key));
-  if (!thread_state)
-    return;
-
-  --g_egl_active_thread_count;
-  if (g_egl_active_thread_count > 0) {
-    g_egl_default_display->ReleaseCurrent(thread_state);
-    delete thread_state;
-  } else {
-    gpu::ThreadLocalFree(g_egl_thread_state_key);
-
-    // First delete the display object, so that it drops the possible refs to
-    // current context.
-    delete g_egl_default_display;
-    g_egl_default_display = nullptr;
-
-    // We can use Surface and Context without lock, since there's no threads
-    // left anymore. Destroy the current context explicitly, in an attempt to
-    // reduce the number of error messages abandoned context would produce.
-    if (thread_state->current_context()) {
-      Context::MakeCurrent(thread_state->current_context(),
-                           thread_state->current_surface(), nullptr, nullptr);
-    }
-    delete thread_state;
-
-    gles2::Terminate();
-#if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY)
-#if defined(COMPONENT_BUILD)
-    if (g_command_buffer_gles_has_atexit_manager)
-      delete g_exit_manager;
-#else
-    delete g_exit_manager;
-#endif
-    g_exit_manager = nullptr;
-#endif
-  }
-}
-
-ThreadState::ThreadState() : error_code_(EGL_SUCCESS) {}
-
-ThreadState::~ThreadState() = default;
-
-EGLint ThreadState::ConsumeErrorCode() {
-  EGLint current_error_code = error_code_;
-  error_code_ = EGL_SUCCESS;
-  return current_error_code;
-}
-
-Display* ThreadState::GetDisplay(EGLDisplay dpy) {
-  if (dpy == g_egl_default_display)
-    return g_egl_default_display;
-  return nullptr;
-}
-
-Display* ThreadState::GetDefaultDisplay() {
-  return g_egl_default_display;
-}
-
-void ThreadState::SetCurrent(Surface* surface, Context* context) {
-  DCHECK((surface == nullptr) == (context == nullptr));
-  if (current_context_) {
-    current_context_->set_is_current_in_some_thread(false);
-    current_surface_->set_is_current_in_some_thread(false);
-  }
-  current_surface_ = surface;
-  current_context_ = context;
-  if (current_context_) {
-    current_context_->set_is_current_in_some_thread(true);
-    current_surface_->set_is_current_in_some_thread(true);
-  }
-}
-
-ThreadState::AutoCurrentContextRestore::AutoCurrentContextRestore(
-    ThreadState* thread_state)
-    : thread_state_(thread_state) {}
-
-ThreadState::AutoCurrentContextRestore::~AutoCurrentContextRestore() {
-  if (Context* current_context = thread_state_->current_context()) {
-    current_context->ApplyCurrentContext(
-        thread_state_->current_surface()->gl_surface());
-  } else {
-    Context::ApplyContextReleased();
-  }
-}
-
-void ThreadState::AutoCurrentContextRestore::SetCurrent(Surface* surface,
-                                                        Context* context) {
-  thread_state_->SetCurrent(surface, context);
-}
-
-}  // namespace egl
-}  // namespace gles2_conform_support
diff --git a/gpu/gles2_conform_support/egl/thread_state.h b/gpu/gles2_conform_support/egl/thread_state.h
deleted file mode 100644
index 8a31891..0000000
--- a/gpu/gles2_conform_support/egl/thread_state.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2016 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef GPU_GLES2_CONFORM_SUPPORT_EGL_THREAD_STATE_H_
-#define GPU_GLES2_CONFORM_SUPPORT_EGL_THREAD_STATE_H_
-
-#include <EGL/egl.h>
-#include "base/memory/raw_ptr.h"
-#include "base/memory/ref_counted.h"
-
-namespace gles2_conform_support {
-namespace egl {
-
-class Context;
-class Display;
-class Surface;
-
-// Thread-local API state of EGL.
-class ThreadState {
- public:
-  // Factory getter for the class. Should only be called by the API layer, and
-  // then passed through Display in order to avoid lock issues.
-  static ThreadState* Get();
-
-  ThreadState(const ThreadState&) = delete;
-  ThreadState& operator=(const ThreadState&) = delete;
-
-  static void ReleaseThread();
-
-  Surface* current_surface() const { return current_surface_.get(); }
-  Context* current_context() const { return current_context_.get(); }
-
-  template <typename T>
-  T ReturnError(EGLint error, T return_value) {
-    error_code_ = error;
-    return return_value;
-  }
-  template <typename T>
-  T ReturnSuccess(T return_value) {
-    error_code_ = EGL_SUCCESS;
-    return return_value;
-  }
-  EGLint ConsumeErrorCode();
-
-  Display* GetDefaultDisplay();
-  Display* GetDisplay(EGLDisplay);
-
-  // RAII class for ensuring that ThreadState current context
-  // is reflected in the gfx:: and gles:: global variables.
-  class AutoCurrentContextRestore {
-   public:
-    AutoCurrentContextRestore(ThreadState*);
-
-    AutoCurrentContextRestore(const AutoCurrentContextRestore&) = delete;
-    AutoCurrentContextRestore& operator=(const AutoCurrentContextRestore&) =
-        delete;
-
-    ~AutoCurrentContextRestore();
-    void SetCurrent(Surface*, Context*);
-
-   private:
-    raw_ptr<ThreadState> thread_state_;
-  };
-
- private:
-  ThreadState();
-  ~ThreadState();
-  void SetCurrent(Surface*, Context*);
-
-  EGLint error_code_;
-  scoped_refptr<Surface> current_surface_;
-  scoped_refptr<Context> current_context_;
-};
-
-}  // namespace egl
-}  // namespace gles2_conform_support
-
-#endif  // GPU_GLES2_CONFORM_SUPPORT_EGL_THREAD_STATE_H_
diff --git a/gpu/gles2_conform_support/generate_gles2_conform_tests.py b/gpu/gles2_conform_support/generate_gles2_conform_tests.py
deleted file mode 100755
index 00c4d478..0000000
--- a/gpu/gles2_conform_support/generate_gles2_conform_tests.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env python3
-# Copyright 2013 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""code generator for OpenGL ES 2.0 conformance tests."""
-
-import os
-import re
-import sys
-import typing
-
-def ReadFileAsLines(filename: str) -> typing.List[str]:
-  """Reads a file, removing blank lines and lines that start with #"""
-  with open(filename, "r") as in_file:
-    raw_lines = in_file.readlines()
-  lines = []
-  for line in raw_lines:
-    line = line.strip()
-    if len(line) > 0 and not line.startswith("#"):
-      lines.append(line)
-  return lines
-
-
-def GenerateTests(out_file: typing.IO) -> None:
-  """Generates gles2_conform_test_autogen.cc"""
-
-  tests = ReadFileAsLines(
-      "../../third_party/gles2_conform/GTF_ES/glsl/GTF/mustpass_es20.run")
-
-  out_file.write("""
-#include "gpu/gles2_conform_support/gles2_conform_test.h"
-#include "testing/gtest/include/gtest/gtest.h"
-""".encode("utf8"))
-
-  for test in tests:
-    out_file.write(("""
-TEST(GLES2ConformTest, %(name)s) {
-  EXPECT_TRUE(RunGLES2ConformTest("%(path)s"));
-}
-""" % {
-        "name": re.sub(r'[^A-Za-z0-9]', '_', test),
-        "path": test,
-      }).encode("utf8"))
-
-
-def main(argv: typing.List[str]) -> int:
-  """This is the main function."""
-
-  if len(argv) >= 1:
-    out_dir = argv[0]
-  else:
-    out_dir = '.'
-
-  out_filename = os.path.join(out_dir, 'gles2_conform_test_autogen.cc')
-  with open(out_filename, 'wb') as out_file:
-    GenerateTests(out_file)
-
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(main(sys.argv[1:]))
diff --git a/gpu/gles2_conform_support/generate_gles2_embedded_data.py b/gpu/gles2_conform_support/generate_gles2_embedded_data.py
deleted file mode 100755
index a83161d..0000000
--- a/gpu/gles2_conform_support/generate_gles2_embedded_data.py
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/usr/bin/env python3
-# Copyright 2013 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""generates files to embed the gles2 conformance test data in executable."""
-
-from __future__ import print_function
-
-import os
-import sys
-import typing
-
-class GenerateEmbeddedFiles():
-  """generates files to embed the gles2 conform test data in executable"""
-
-  paths_to_ignore = set([
-    ".",
-    "..",
-    ".svn",
-    ".git",
-    ".hg",
-  ])
-
-  extensions_to_include = set([
-      ".vert",
-      ".frag",
-      ".test",
-      ".run",
-  ])
-
-  def __init__(self, scan_dir: str, base_dir: typing.Optional[str]):
-    self.scan_dir = scan_dir
-    self.base_dir = base_dir
-    self.count = 0;
-    if self.base_dir != None:
-      self.files_data_h = open(os.path.join(base_dir, "FilesDATA.h"), "wb")
-      self.files_data_c = open(os.path.join(base_dir, "FilesDATA.c"), "wb")
-      self.files_toc_c = open(os.path.join(base_dir, "FilesTOC.c"), "wb")
-
-      self.files_data_h.write(b"#ifndef FilesDATA_h\n\n")
-      self.files_data_h.write(b"#define FilesDATA_h\n\n");
-
-      self.files_data_c.write(b"#include \"FilesDATA.h\"\n\n")
-
-      self.files_toc_c.write(b"#include \"FilesTOC.h\"\n\n");
-      self.files_toc_c.write(b"struct GTFVectorFileEntry tempFiles;\n\n");
-      self.files_toc_c.write(b"struct FileEntry files[] = {\n");
-
-    self.AddFiles(scan_dir)
-
-    if self.base_dir != None:
-      self.files_toc_c.write(b"\n};\n\n");
-      self.files_toc_c.write(
-        b"int numFileEntrys = sizeof(files) / sizeof(struct FileEntry);\n");
-
-      self.files_data_h.write(b"\n\n#endif  // FilesDATA_h\n");
-
-      self.files_data_c.close()
-      self.files_data_h.close()
-      self.files_toc_c.close()
-
-  def AddFiles(self, scan_dir: str) -> None:
-    """Scan a folder and embed the contents of files."""
-    files_to_embed = os.listdir(scan_dir)
-    sub_dirs = []
-    for file_to_embed in files_to_embed:
-      full_path = os.path.join(scan_dir, file_to_embed)
-      ext = os.path.splitext(file_to_embed)[1]
-      base_path = full_path[len(self.scan_dir) + 1:]
-      if os.path.isdir(full_path):
-        if not file_to_embed in GenerateEmbeddedFiles.paths_to_ignore:
-          sub_dirs.append(full_path)
-      elif ext in GenerateEmbeddedFiles.extensions_to_include:
-        if self.base_dir == None:
-          print(full_path.replace("\\", "/"))
-        else:
-          self.count += 1
-          name = "_FILE_%s_%d" % (ext.upper(), self.count)
-          name = name.replace(".", "_")
-
-          self.files_data_h.write(
-              ("extern const char %s[];\n" % name).encode("utf8"))
-          self.files_data_c.write(
-              ("const char %s[] = \n" % name).encode("utf8"))
-
-          data = open(full_path, "r")
-          lines = data.readlines();
-          data.close()
-
-          for line in lines:
-            line = line.replace("\n", "")
-            line = line.replace("\r", "")
-            line = line.replace("\\", "\\\\")
-            line = line.replace("\"", "\\\"")
-
-            self.files_data_c.write(('"%s\\n"\n' % line).encode("utf8"))
-
-          self.files_data_c.write(b";\n")
-          self.files_toc_c.write(("\t{ \"%s\", %s, 0 },\n" % (
-              base_path.replace("\\", "/"), name)).encode("utf8"))
-
-    for sub_dir in sub_dirs:
-      self.AddFiles(sub_dir)
-
-
-def main(argv: typing.List[str]) -> int:
-  """This is the main function."""
-
-  if len(argv) >= 1:
-    scan_dir = argv[0]
-  else:
-    scan_dir = '.'
-
-  if len(argv) >= 2:
-    base_dir = argv[1]
-  else:
-    base_dir = None
-
-  GenerateEmbeddedFiles(scan_dir, base_dir)
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(main(sys.argv[1:]))
diff --git a/gpu/gles2_conform_support/gles2_conform_support.c b/gpu/gles2_conform_support/gles2_conform_support.c
deleted file mode 100644
index 83e370f..0000000
--- a/gpu/gles2_conform_support/gles2_conform_support.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2011 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A small sample just to make sure we can actually compile and link
-// our OpenGL ES 2.0 conformance test support code.
-
-#include <EGL/egl.h>
-#include "gpu/gles2_conform_support/gtf/gtf_stubs.h"
-
-// Note: This code is not intended to run, only compile and link.
-int GTFMain(int argc, char** argv) {
-  EGLint major, minor;
-  EGLDisplay eglDisplay;
-  EGLNativeDisplayType nativeDisplay = EGL_DEFAULT_DISPLAY;
-
-  eglDisplay = eglGetDisplay(nativeDisplay);
-  eglInitialize(eglDisplay, &major, &minor);
-
-  return 0;
-}
-
-
diff --git a/gpu/gles2_conform_support/gles2_conform_test.cc b/gpu/gles2_conform_support/gles2_conform_test.cc
deleted file mode 100644
index 6c5bffc3..0000000
--- a/gpu/gles2_conform_support/gles2_conform_test.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2013 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "gpu/gles2_conform_support/gles2_conform_test.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <string>
-
-#include "base/base_paths.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/functional/bind.h"
-#include "base/logging.h"
-#include "build/build_config.h"
-#if BUILDFLAG(IS_MAC)
-#include "base/apple/scoped_nsautorelease_pool.h"
-#endif
-#include "base/path_service.h"
-#include "base/process/launch.h"
-#include "base/strings/string_util.h"
-#include "base/test/launcher/unit_test_launcher.h"
-#include "base/test/test_suite.h"
-#include "gpu/config/gpu_test_config.h"
-#include "gpu/config/gpu_test_expectations_parser.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-int RunHelper(base::TestSuite* test_suite) {
-  return test_suite->Run();
-}
-
-}  // namespace
-
-bool RunGLES2ConformTest(const char* path) {
-  // Load test expectations, and return early if a test is marked as FAIL.
-  base::FilePath src_path;
-  base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &src_path);
-  base::FilePath test_expectations_path =
-      src_path.Append(FILE_PATH_LITERAL("gpu")).
-      Append(FILE_PATH_LITERAL("gles2_conform_support")).
-      Append(FILE_PATH_LITERAL("gles2_conform_test_expectations.txt"));
-  if (!base::PathExists(test_expectations_path)) {
-    LOG(ERROR) << "Fail to locate gles2_conform_test_expectations.txt";
-    return false;
-  }
-  gpu::GPUTestExpectationsParser test_expectations;
-  if (!test_expectations.LoadTestExpectations(test_expectations_path)) {
-    LOG(ERROR) << "Fail to load gles2_conform_test_expectations.txt";
-    return false;
-  }
-  gpu::GPUTestBotConfig bot_config;
-  if (!bot_config.LoadCurrentConfig(nullptr)) {
-    LOG(ERROR) << "Fail to load bot configuration";
-    return false;
-  }
-
-  // Set the bot config api based on the OS and command line
-  base::CommandLine* current_cmd_line = base::CommandLine::ForCurrentProcess();
-  int32_t config_os = bot_config.os();
-  if ((config_os & gpu::GPUTestConfig::kOsWin) != 0) {
-    std::string angle_renderer =
-        current_cmd_line->HasSwitch("use-angle")
-            ? current_cmd_line->GetSwitchValueASCII("use-angle")
-            : "d3d11";
-    if (angle_renderer == "d3d11") {
-      bot_config.set_api(gpu::GPUTestConfig::kAPID3D11);
-    } else if (angle_renderer == "d3d9") {
-      bot_config.set_api(gpu::GPUTestConfig::kAPID3D9);
-    } else if (angle_renderer == "gl") {
-      bot_config.set_api(gpu::GPUTestConfig::kAPIGLDesktop);
-    } else if (angle_renderer == "gles") {
-      bot_config.set_api(gpu::GPUTestConfig::kAPIGLES);
-    } else {
-      bot_config.set_api(gpu::GPUTestConfig::kAPIUnknown);
-    }
-  } else if ((config_os & gpu::GPUTestConfig::kOsMac) != 0 ||
-             config_os == gpu::GPUTestConfig::kOsLinux) {
-    bot_config.set_api(gpu::GPUTestConfig::kAPIGLDesktop);
-  } else if (config_os == gpu::GPUTestConfig::kOsChromeOS ||
-             config_os == gpu::GPUTestConfig::kOsAndroid) {
-    bot_config.set_api(gpu::GPUTestConfig::kAPIGLES);
-  } else {
-    bot_config.set_api(gpu::GPUTestConfig::kAPIUnknown);
-  }
-
-  if (!bot_config.IsValid()) {
-    LOG(ERROR) << "Invalid bot configuration";
-    return false;
-  }
-  std::string path_string(path);
-  std::string test_name;
-  base::ReplaceChars(path_string, "\\/.", "_", &test_name);
-  int32_t expectation =
-      test_expectations.GetTestExpectation(test_name, bot_config);
-  if (expectation != gpu::GPUTestExpectationsParser::kGpuTestPass) {
-    LOG(WARNING) << "Test " << test_name << " is bypassed";
-    return true;
-  }
-
-  base::FilePath test_path;
-  base::PathService::Get(base::DIR_EXE, &test_path);
-  base::FilePath program(test_path.Append(FILE_PATH_LITERAL(
-      "gles2_conform_test_windowless")));
-
-  base::CommandLine cmd_line(program);
-  cmd_line.AppendArguments(*current_cmd_line, false);
-  cmd_line.AppendSwitch(std::string("--"));
-  cmd_line.AppendArg(std::string("-run=") + path);
-
-  std::string output;
-  bool success = base::GetAppOutputAndError(cmd_line, &output);
-  if (success) {
-    size_t success_index = output.find("Conformance PASSED all");
-    size_t failed_index = output.find("FAILED");
-    success = (success_index != std::string::npos) &&
-              (failed_index == std::string::npos);
-  }
-  if (!success) {
-    LOG(ERROR) << output;
-  }
-  return success;
-}
-
-int main(int argc, char** argv) {
-  base::CommandLine::Init(argc, argv);
-#if BUILDFLAG(IS_MAC)
-  base::apple::ScopedNSAutoreleasePool pool;
-#endif
-  ::testing::InitGoogleTest(&argc, argv);
-  base::TestSuite test_suite(argc, argv);
-  int rt = base::LaunchUnitTestsSerially(
-      argc, argv, base::BindOnce(&RunHelper, base::Unretained(&test_suite)));
-  return rt;
-}
diff --git a/gpu/gles2_conform_support/gles2_conform_test.h b/gpu/gles2_conform_support/gles2_conform_test.h
deleted file mode 100644
index 95471a3..0000000
--- a/gpu/gles2_conform_support/gles2_conform_test.h
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2013 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef GPU_GLES2_CONFORM_SUPPORT_GLES2_CONFORM_TEST_H_
-#define GPU_GLES2_CONFORM_SUPPORT_GLES2_CONFORM_TEST_H_
-
-bool RunGLES2ConformTest(const char* path);
-
-#endif  // GPU_GLES2_CONFORM_SUPPORT_GLES2_CONFORM_TEST_H_
diff --git a/gpu/gles2_conform_support/gles2_conform_test_expectations.txt b/gpu/gles2_conform_support/gles2_conform_test_expectations.txt
deleted file mode 100644
index fc842eb4..0000000
--- a/gpu/gles2_conform_support/gles2_conform_test_expectations.txt
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2013 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file contains a list of defective GLES2 conformance tests. The expected
-// format is:
-//  {BUG#} {MODIFIERS} : {TEST_NAME} = {PASS,FAIL,FLAKY,TIMEOUT,SKIP}
-//
-// MODIFIERS can be a combination of the below list:
-//  WIN XP VISTA WIN7 MAC LEOPARD SNOWLEOPARD LION LINUX CHROMEOS MOUNTAINLION
-//  MAVERICKS
-//  NVIDIA AMD INTEL
-//  0xabcd - GPU PCI device ID. Specifying a PCI id requires a vendor.
-//  DEBUG RELEASE
-//
-// TEST_NAME can be a specific test name, or have a '*' in the end, which
-// indicates a prefix matching.
-//
-// Any tests whose expectations are not PASS will be skipped on the bots.
-//
-// Examples:
-//  91530 MAC WIN LINUX : context_lost_restored = TIMEOUT
-//  91533 WIN : gl_min_uniforms = FAIL
-//  91531 MAC WIN LINUX : conformance_more_* = SKIP
-//  91532 MAC NVIDIA 0x0640 : tex_image_and_sub_image_2d_with_video = PASS FAIL
-
-612551 WIN LINUX MAC CHROMEOS : GL2ExtensionTests_egl_image_input_run = SKIP
-
-517966 WIN OPENGL : GL2FixedTests_blend_input_run = FAIL
-517966 WIN OPENGL : GL2FixedTests_buffer_clear_input_run = FAIL
-517966 WIN OPENGL RELEASE : GL2FixedTests_buffer_color_input_run = FAIL
-517966 WIN OPENGL : GL2FixedTests_copy_texture_input_run = FAIL
-517966 WIN OPENGL : GL2FixedTests_depth_buffer_clear_input_run = FAIL
-517966 WIN OPENGL : GL2FixedTests_stencil_plane_clear_input_run = FAIL
-517966 WIN OPENGL : GL2FixedTests_user_clip_planes_input_run = FAIL
-517966 WIN OPENGL : GL2Tests_framebuffer_objects_input_run = FAIL
-
-490149 WIN OPENGL INTEL : GL2ExtensionTests_dFdy_input_run = FAIL
-490149 WIN OPENGL INTEL : GL2Tests_fixed_data_type_input_run = FAIL
-490149 WIN OPENGL INTEL : GL2Tests_glUniform_input_run = FAIL
-490149 WIN OPENGL INTEL : GL2Tests_three_uniforms_input_run = FAIL
-490149 WIN OPENGL INTEL : GL_build_input_run = FAIL
-
-540538 WIN D3D9 INTEL : GL_cos_input_run = FAIL
-
-253674 LION INTEL : GL2ExtensionTests_dFdy_input_run = FAIL
-253674 LION INTEL : GL2FixedTests_point_sprites_input_run = FAIL
-253674 LION INTEL : GL_control_flow_input_run = FAIL
-253674 LION INTEL : GL_dot_input_run = FAIL
-253674 LION INTEL : GL_faceforward_input_run = FAIL
-253674 LION INTEL : GL_length_input_run = FAIL
-253674 LION INTEL : GL_normalize_input_run = FAIL
-253674 LION INTEL : GL_reflect_input_run = FAIL
-253674 LION INTEL : GL_refract_input_run = FAIL
-253674 LION INTEL : GL_tan_input_run = FAIL
-
-253674 LION AMD : GL2FixedTests_point_sprites_input_run = FAIL
-253674 LION AMD : GL_dot_input_run = FAIL
-253674 LION AMD : GL_length_input_run = FAIL
-
-// See also crbug.com/306485 for non-Lion instances.
-253674 MAC AMD : GL_distance_input_run = FAIL
-
-253674 MOUNTAINLION AMD : GL2ExtensionTests_dFdy_input_run = FAIL
-253674 MOUNTAINLION AMD : GL2FixedTests_point_sprites_input_run = FAIL
-253674 MOUNTAINLION AMD : GL_control_flow_input_run = FAIL
-253674 MOUNTAINLION AMD : GL_operators_input_run = FAIL
-
-253674 MOUNTAINLION INTEL : GL2ExtensionTests_dFdy_input_run = FAIL
-253674 MOUNTAINLION INTEL : GL2FixedTests_point_sprites_input_run = FAIL
-253674 MOUNTAINLION INTEL : GL_control_flow_input_run = FAIL
-253674 MOUNTAINLION INTEL : GL_operators_input_run = FAIL
-
-339911 MOUNTAINLION INTEL : GL2FixedTests_blend_input_run = FAIL
-
-253674 MAC : GL2Tests_glUniform_input_run = FAIL
-253674 MAC : GL2Tests_three_uniforms_input_run = FAIL
-
-630452 MAC NVIDIA : GL2FixedTests_color_ramp_input_run = SKIP
-630452 MAC NVIDIA RELEASE : GL2FixedTests_buffer_color_input_run = SKIP
-
-393677 CHROMEOS INTEL 0xa011 : GL_acos_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL_asin_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL_atan_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL_control_flow_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL_cos_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL_discard_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL_functions_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL_gl_FrontFacing_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL_log_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL_log2_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL_normalize_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL_sin_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL2ExtensionTests_dFdx_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL2ExtensionTests_dFdy_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL2ExtensionTests_fwidth_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL2FixedTests_blend_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL2FixedTests_point_rasterization_input_run = FAIL
-393677 CHROMEOS INTEL 0xa011 : GL2FixedTests_scissor_input_run = FAIL
-
-598902 LINUX OPENGL INTEL : GL2Tests_fixed_data_type_input_run = FAIL
-598902 LINUX OPENGL INTEL : GLCoverage_input_run = FAIL
-598902 LINUX OPENGL INTEL : GL2FixedTests_copy_texture_input_run = FAIL
-
-// Test takes too long to run in debug configurations
-646442 DEBUG : GL2FixedTests_buffer_color_input_run = SKIP
-
-////////////////////////////////////////////////////////////////////////////////
-//
-//  Temprory entries: they should be removed once the bugs are fixed.
-//
-////////////////////////////////////////////////////////////////////////////////
-
diff --git a/gpu/gles2_conform_support/gtf/gtf_stubs.h b/gpu/gles2_conform_support/gtf/gtf_stubs.h
deleted file mode 100644
index d992c2e5..0000000
--- a/gpu/gles2_conform_support/gtf/gtf_stubs.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2011 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// A few stubs so we don't need the actual OpenGL ES 2.0 conformance tests
-// to compile the support for them.
-
-#ifndef GPU_GLES2_CONFORM_SUPPORT_GTF_GTF_STUBS_H_
-#define GPU_GLES2_CONFORM_SUPPORT_GTF_GTF_STUBS_H_
-
-#include <GLES2/gl2.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-typedef unsigned char GTFbool;
-#define GTFfalse 0
-#define GTFtrue  1
-
-int GTFMain(int argc, char** argv);
-
-#endif  // GPU_GLES2_CONFORM_SUPPORT_GTF_GTF_STUBS_H_
-
-
diff --git a/gpu/gles2_conform_support/native/BUILD.gn b/gpu/gles2_conform_support/native/BUILD.gn
deleted file mode 100644
index e2bf1e01..0000000
--- a/gpu/gles2_conform_support/native/BUILD.gn
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 2015 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-source_set("native") {
-  output_name = "egl_main_native"
-  sources = [
-    "egl_native.cc",
-    "main.cc",
-  ]
-  defines = [
-    "GLES2_CONFORM_SUPPORT_ONLY",
-    "GTF_GLES20",
-    "EGLAPI=",
-    "EGLAPIENTRY=",
-  ]
-  deps = [
-    ":windowless",
-    "//base",
-    "//gpu/gles2_conform_support/egl",
-    "//ui/gl",
-  ]
-  if (is_linux || is_chromeos) {
-    sources += [
-      "egl_native_aura.cc",
-      "egl_native_x11.cc",
-    ]
-  }
-  if (is_win) {
-    sources += [ "egl_native_win.cc" ]
-  }
-}
-
-source_set("windowless") {
-  output_name = "egl_main_windowless"
-  sources = [
-    "egl_native.cc",
-    "egl_native_windowless.cc",
-    "main.cc",
-  ]
-  defines = [
-    "GLES2_CONFORM_SUPPORT_ONLY",
-    "GTF_GLES20",
-    "EGLAPI=",
-    "EGLAPIENTRY=",
-  ]
-  deps = [
-    "//base",
-    "//gpu/gles2_conform_support/egl",
-    "//ui/gl",
-  ]
-}
diff --git a/gpu/gles2_conform_support/native/egl_native.cc b/gpu/gles2_conform_support/native/egl_native.cc
deleted file mode 100644
index dea2b2e..0000000
--- a/gpu/gles2_conform_support/native/egl_native.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-extern "C" {
-#if defined(GLES2_CONFORM_SUPPORT_ONLY)
-#include "gpu/gles2_conform_support/gtf/gtf_stubs.h"
-#else
-#include "third_party/gles2_conform/GTF_ES/glsl/GTF/Source/eglNative.h"  // nogncheck
-#endif
-
-GTFbool GTFNativeCreatePixmap(EGLNativeDisplayType nativeDisplay,
-                              EGLDisplay eglDisplay, EGLConfig eglConfig,
-                              const char *title, int width, int height,
-                              EGLNativePixmapType *pNativePixmap) {
-  return GTFtrue;
-}
-
-void GTFNativeDestroyPixmap(EGLNativeDisplayType nativeDisplay,
-                            EGLNativePixmapType nativePixmap) {
-}
-
-EGLImageKHR GTFCreateEGLImageExternal(
-    int width, int height, int format,
-    float r, float g, float b, float a, void** resource) {
-  return (EGLImageKHR)0;
-}
-
-void GTFDestroyEGLImageExternal(EGLImageKHR image, void* resource) {
-}
-
-const int* GTFQueryFormatsEGLImageExternal(void) {
-  return 0;
-}
-
-GTFbool GTFIsAlphaFormatEGLImageExternal(int format) {
-  return GTFfalse;
-}
-
-}  // extern "C"
-
-
diff --git a/gpu/gles2_conform_support/native/egl_native_aura.cc b/gpu/gles2_conform_support/native/egl_native_aura.cc
deleted file mode 100644
index 5a8681b7..0000000
--- a/gpu/gles2_conform_support/native/egl_native_aura.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2013 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This is just a compile fix. If this is really needed when using aura, the
-// methods below should be filled out.
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include "base/notreached.h"
-
-extern "C" {
-#if defined(GLES2_CONFORM_SUPPORT_ONLY)
-#include "gpu/gles2_conform_support/gtf/gtf_stubs.h"
-#else
-#include "third_party/gles2_conform/GTF_ES/glsl/GTF/Source/eglNative.h"  // nogncheck
-#endif
-
-GTFbool GTFNativeCreateDisplay(EGLNativeDisplayType *pNativeDisplay) {
-  NOTIMPLEMENTED();
-  return GTFfalse;
-}
-
-void GTFNativeDestroyDisplay(EGLNativeDisplayType nativeDisplay) {
-  NOTIMPLEMENTED();
-}
-
-void GTFNativeDestroyWindow(EGLNativeDisplayType nativeDisplay,
-                            EGLNativeWindowType nativeWindow) {
-  NOTIMPLEMENTED();
-}
-
-GTFbool GTFNativeCreateWindow(EGLNativeDisplayType nativeDisplay,
-                              EGLDisplay eglDisplay, EGLConfig eglConfig,
-                              const char* title, int width, int height,
-                              EGLNativeWindowType *pNativeWindow) {
-  NOTIMPLEMENTED();
-  return GTFfalse;
-}
-
-}  // extern "C"
diff --git a/gpu/gles2_conform_support/native/egl_native_win.cc b/gpu/gles2_conform_support/native/egl_native_win.cc
deleted file mode 100644
index 410185b..0000000
--- a/gpu/gles2_conform_support/native/egl_native_win.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-extern "C" {
-#if defined(GLES2_CONFORM_SUPPORT_ONLY)
-#include "gpu/gles2_conform_support/gtf/gtf_stubs.h"
-#else
-#include "third_party/gles2_conform/GTF_ES/glsl/GTF/Source/eglNative.h"  // nogncheck
-#endif
-}
-
-#include <string>
-
-namespace {
-LPCTSTR kWindowClassName = TEXT("ES2CONFORM");
-
-LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg,
-                            WPARAM w_param, LPARAM l_param) {
-  LRESULT result = 0;
-  switch (msg) {
-    case WM_CLOSE:
-      ::DestroyWindow(hwnd);
-      break;
-    case WM_DESTROY:
-      ::PostQuitMessage(0);
-      break;
-    case WM_ERASEBKGND:
-      // Return a non-zero value to indicate that the background has been
-      // erased.
-      result = 1;
-      break;
-    default:
-      result = ::DefWindowProc(hwnd, msg, w_param, l_param);
-      break;
-  }
-  return result;
-}
-}  // namespace.
-
-extern "C" {
-
-GTFbool GTFNativeCreateDisplay(EGLNativeDisplayType *pNativeDisplay) {
-  *pNativeDisplay = EGL_DEFAULT_DISPLAY;
-  return GTFtrue;
-}
-
-void GTFNativeDestroyDisplay(EGLNativeDisplayType nativeDisplay) {
-  // Nothing to destroy since we are using EGL_DEFAULT_DISPLAY
-}
-
-GTFbool GTFNativeCreateWindow(EGLNativeDisplayType nativeDisplay,
-                              EGLDisplay eglDisplay, EGLConfig eglConfig,
-                              const char* title, int width, int height,
-                              EGLNativeWindowType *pNativeWindow) {
-  WNDCLASS wnd_class = {0};
-  HINSTANCE instance = GetModuleHandle(nullptr);
-  wnd_class.style = CS_OWNDC;
-  wnd_class.lpfnWndProc = WindowProc;
-  wnd_class.hInstance = instance;
-  wnd_class.hbrBackground =
-      reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
-  wnd_class.lpszClassName = kWindowClassName;
-  if (!RegisterClass(&wnd_class))
-    return GTFfalse;
-
-  DWORD wnd_style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
-  RECT wnd_rect;
-  wnd_rect.left = 0;
-  wnd_rect.top = 0;
-  wnd_rect.right = width;
-  wnd_rect.bottom = height;
-  if (!AdjustWindowRect(&wnd_rect, wnd_style, FALSE))
-    return GTFfalse;
-
-#ifdef UNICODE
-  // Convert ascii string to wide string.
-  const std::wstring wnd_title(title, title + strlen(title));
-#else
-  const std::string wnd_title = title;
-#endif  // UNICODE
-
-  HWND hwnd = CreateWindow(wnd_class.lpszClassName, wnd_title.c_str(),
-                           wnd_style, 0, 0, wnd_rect.right - wnd_rect.left,
-                           wnd_rect.bottom - wnd_rect.top, nullptr, nullptr,
-                           instance, nullptr);
-  if (hwnd == nullptr)
-    return GTFfalse;
-
-  ShowWindow(hwnd, SW_SHOWNORMAL);
-  *pNativeWindow = hwnd;
-  return GTFtrue;
-}
-
-void GTFNativeDestroyWindow(EGLNativeDisplayType nativeDisplay,
-                            EGLNativeWindowType nativeWindow) {
-  DestroyWindow(nativeWindow);
-  UnregisterClass(kWindowClassName, GetModuleHandle(nullptr));
-}
-
-EGLImageKHR GTFCreateEGLImage(int width, int height,
-                              GLenum format, GLenum type) {
-  return (EGLImageKHR) nullptr;
-}
-
-void GTFDestroyEGLImage(EGLImageKHR image) {
-}
-
-}  // extern "C"
diff --git a/gpu/gles2_conform_support/native/egl_native_windowless.cc b/gpu/gles2_conform_support/native/egl_native_windowless.cc
deleted file mode 100644
index 1246becf..0000000
--- a/gpu/gles2_conform_support/native/egl_native_windowless.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "gpu/gles2_conform_support/egl/test_support.h"
-
-extern "C" {
-#if defined(GLES2_CONFORM_SUPPORT_ONLY)
-#include "gpu/gles2_conform_support/gtf/gtf_stubs.h"
-#else
-#include "third_party/gles2_conform/GTF_ES/glsl/GTF/Source/eglNative.h"  // nogncheck
-#endif
-
-GTFbool GTFNativeCreateDisplay(EGLNativeDisplayType *pNativeDisplay) {
-  *pNativeDisplay = EGL_DEFAULT_DISPLAY;
-  return GTFtrue;
-}
-
-void GTFNativeDestroyDisplay(EGLNativeDisplayType nativeDisplay) {
-  // Nothing to destroy since we are using EGL_DEFAULT_DISPLAY
-}
-
-GTFbool GTFNativeCreateWindow(EGLNativeDisplayType nativeDisplay,
-                              EGLDisplay eglDisplay, EGLConfig eglConfig,
-                              const char* title, int width, int height,
-                              EGLNativeWindowType *pNativeWindow) {
-  CommandBufferGLESSetNextCreateWindowSurfaceCreatesPBuffer(eglDisplay, width,
-                                                            height);
-  return GTFtrue;
-}
-
-void GTFNativeDestroyWindow(EGLNativeDisplayType nativeDisplay,
-                            EGLNativeWindowType nativeWindow) {
-}
-
-EGLImageKHR GTFCreateEGLImage(int width, int height,
-                              GLenum format, GLenum type) {
-  return (EGLImageKHR)0;
-}
-
-void GTFDestroyEGLImage(EGLImageKHR image) {
-}
-
-}  // extern "C"
-
diff --git a/gpu/gles2_conform_support/native/egl_native_x11.cc b/gpu/gles2_conform_support/native/egl_native_x11.cc
deleted file mode 100644
index f476711c..0000000
--- a/gpu/gles2_conform_support/native/egl_native_x11.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-extern "C" {
-#if defined(GLES2_CONFORM_SUPPORT_ONLY)
-#include "gpu/gles2_conform_support/gtf/gtf_stubs.h"
-#else
-#include "third_party/gles2_conform/GTF_ES/glsl/GTF/Source/eglNative.h"  // nogncheck
-#endif
-
-EGLImageKHR GTFCreateEGLImage(int width, int height,
-                              GLenum format, GLenum type) {
-  PFNEGLCREATEIMAGEKHRPROC egl_create_image_khr_;
-  egl_create_image_khr_ = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>
-                            (eglGetProcAddress("eglCreateImageKHR"));
-
-  static const EGLint attrib[] = {
-    EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
-    EGL_GL_TEXTURE_LEVEL_KHR, 0,
-    EGL_NONE
-  };
-
-  if (format != GL_RGBA && format != GL_RGB)
-    return static_cast<EGLImageKHR>(nullptr);
-
-  if (type != GL_UNSIGNED_BYTE)
-    return static_cast<EGLImageKHR>(nullptr);
-
-  GLuint texture;
-  glGenTextures(1, &texture);
-  glBindTexture(GL_TEXTURE_2D, texture);
-  glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, type,
-               nullptr);
-
-  // Disable mip-maps because we do not require it.
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
-  if(glGetError() != GL_NO_ERROR)
-    return static_cast<EGLImageKHR>(nullptr);
-
-  EGLImageKHR egl_image =
-      egl_create_image_khr_(eglGetCurrentDisplay(),
-                            eglGetCurrentContext(),
-                            EGL_GL_TEXTURE_2D_KHR,
-                            reinterpret_cast<EGLClientBuffer>(texture),
-                            attrib);
-
-  if (eglGetError() == EGL_SUCCESS)
-    return egl_image;
-  else
-    return static_cast<EGLImageKHR>(nullptr);
-}
-
-void GTFDestroyEGLImage(EGLImageKHR image) {
-  PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr_;
-  egl_destroy_image_khr_ = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>
-                             (eglGetProcAddress("eglDestroyImageKHR"));
-
-  egl_destroy_image_khr_(eglGetCurrentDisplay(), image);
-}
-
-}  // extern "C"
diff --git a/gpu/gles2_conform_support/native/main.cc b/gpu/gles2_conform_support/native/main.cc
deleted file mode 100644
index 97dd7bd..0000000
--- a/gpu/gles2_conform_support/native/main.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stddef.h>
-
-#include <memory>
-
-#include "base/at_exit.h"
-#include "base/command_line.h"
-#include "build/build_config.h"
-#if BUILDFLAG(IS_MAC)
-#include "base/apple/scoped_nsautorelease_pool.h"
-#endif
-#if BUILDFLAG(IS_WIN)
-#include "base/strings/utf_string_conversions.h"
-#endif
-#include "base/message_loop/message_pump_type.h"
-#include "base/task/single_thread_task_executor.h"
-#include "ui/gl/gl_surface.h"
-
-extern "C" {
-#if defined(GLES2_CONFORM_SUPPORT_ONLY)
-#include "gpu/gles2_conform_support/gtf/gtf_stubs.h"
-#else
-#include "third_party/gles2_conform/GTF_ES/glsl/GTF/Source/GTFMain.h"  // nogncheck
-#endif
-}
-
-int main(int argc, char *argv[]) {
-  base::AtExitManager at_exit;
-  base::CommandLine::Init(argc, argv);
-  base::SingleThreadTaskExecutor main_task_executor(base::MessagePumpType::UI);
-
-  base::CommandLine::StringVector args =
-      base::CommandLine::ForCurrentProcess()->GetArgs();
-
-#if BUILDFLAG(IS_MAC)
-  base::apple::ScopedNSAutoreleasePool pool;
-#endif
-
-  std::unique_ptr<const char* []> argsArray(new const char*[args.size() + 1]);
-  argsArray[0] = argv[0];
-
-#if BUILDFLAG(IS_WIN)
-  std::vector<std::string> argsNonWide(args.size());
-  for (size_t index = 0; index < args.size(); ++index) {
-    argsNonWide[index] = base::WideToASCII(args[index]);
-    argsArray[index+1] = argsNonWide[index].c_str();
-  }
-#else
-  for (size_t index = 0; index < args.size(); ++index) {
-    argsArray[index+1] = args[index].c_str();
-  }
-#endif
-
-  GTFMain(static_cast<int>(args.size()+1),
-    const_cast<char**>(argsArray.get()));
-
-  return 0;
-}
diff --git a/gpu/ipc/common/gpu_memory_buffer_impl_dxgi.h b/gpu/ipc/common/gpu_memory_buffer_impl_dxgi.h
index c1fd20c..db306cd 100644
--- a/gpu/ipc/common/gpu_memory_buffer_impl_dxgi.h
+++ b/gpu/ipc/common/gpu_memory_buffer_impl_dxgi.h
@@ -7,10 +7,12 @@
 
 #include <stddef.h>
 #include <stdint.h>
+
 #include <memory>
 
 #include "base/containers/span.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_span.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/unsafe_shared_memory_pool.h"
 #include "base/unguessable_token.h"
@@ -81,7 +83,7 @@
   std::unique_ptr<base::UnsafeSharedMemoryPool::Handle> shared_memory_handle_;
 
   // Used to store shared memory passed from the capturer.
-  base::span<uint8_t> premapped_memory_;
+  base::raw_span<uint8_t> premapped_memory_;
 };
 
 }  // namespace gpu
diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc
index 60b3888d..e04773f 100644
--- a/gpu/ipc/service/gpu_channel.cc
+++ b/gpu/ipc/service/gpu_channel.cc
@@ -409,8 +409,7 @@
   // Threading: GpuChannelManager outlives gpu_channel_, so even though it is a
   // main thread object, we don't have a lifetime issue. However we may be
   // reading something stale here, but we don't synchronize anything here.
-  if (base::FeatureList::IsEnabled(features::kGpuCleanupInBackground) &&
-      gpu_channel_->gpu_channel_manager()->application_backgrounded()) {
+  if (gpu_channel_->gpu_channel_manager()->application_backgrounded()) {
     // We expect to clean shared images, so put it on this sequence, to make
     // sure that ordering is conserved, and we execute after.
     auto it = route_sequences_.find(
diff --git a/gpu/ipc/service/gpu_channel_manager.cc b/gpu/ipc/service/gpu_channel_manager.cc
index 8baa7f5..6a8aa3d 100644
--- a/gpu/ipc/service/gpu_channel_manager.cc
+++ b/gpu/ipc/service/gpu_channel_manager.cc
@@ -825,11 +825,10 @@
 
   // Release all skia caching when the application is backgrounded.
   SkGraphics::PurgeAllCaches();
-  if (base::FeatureList::IsEnabled(features::kGpuCleanupInBackground)) {
-    // At that point, no frames are going to be produced. Make sure that
-    // e.g. pending SharedImage deletions happens promptly.
-    PerformImmediateCleanup();
-  }
+  // At that point, no frames are going to be produced. Make sure that
+  // e.g. pending SharedImage deletions happens promptly.
+  PerformImmediateCleanup();
+
   application_backgrounded_ = true;
 }
 
diff --git a/gpu/khronos_glcts_support/BUILD.gn b/gpu/khronos_glcts_support/BUILD.gn
deleted file mode 100644
index 83b477f..0000000
--- a/gpu/khronos_glcts_support/BUILD.gn
+++ /dev/null
@@ -1,949 +0,0 @@
-# Copyright 2015 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//testing/test.gni")
-
-declare_args() {
-  internal_khronos_glcts_tests = false
-}
-
-if (internal_khronos_glcts_tests) {
-  glcts_gtf_runfiles =
-      [ "//third_party/khronos_glcts/GTF_ES/glsl/GTF/mustpass_es20.run" ]
-
-  copy("glcts_resources") {
-    sources = [ "//third_party/khronos_glcts/cts/data" ]
-    outputs = [ "$root_out_dir/khronos_glcts_data/gl_cts/{{source_file_part}}" ]
-  }
-
-  copy("glcts_gtf_resources") {
-    sources = [
-                "//third_party/khronos_glcts/GTF_ES/glsl/GTF/GL",
-                "//third_party/khronos_glcts/GTF_ES/glsl/GTF/GL2ExtensionTests",
-                "//third_party/khronos_glcts/GTF_ES/glsl/GTF/GL2FixedTests",
-                "//third_party/khronos_glcts/GTF_ES/glsl/GTF/GL2Tests",
-                "//third_party/khronos_glcts/GTF_ES/glsl/GTF/GLCoverage",
-              ] + glcts_gtf_runfiles
-    outputs =
-        [ "$root_out_dir/khronos_glcts_data/gl_cts/GTF/{{source_file_part}}" ]
-  }
-
-  action("generate_khronos_glcts_tests") {
-    script = "generate_khronos_glcts_tests.py"
-    sources = [ "khronos_glcts_test.h" ] + glcts_gtf_runfiles
-    outputs = [ "$target_gen_dir/khronos_glcts_test_autogen.cc" ]
-    args = [ "--outdir=" + rebase_path("$target_gen_dir") ] + glcts_gtf_runfiles
-  }
-
-  config("defaults_config") {
-    defines = [
-      "DEQP_TARGET_NAME=\"chrome-gpu-command-buffer\"",
-      "DEQP_SUPPORT_GLES2=1",
-      "DEQP_SUPPORT_EGL=1",
-      "GTF_API=GTF_GLES20",
-    ]
-
-    if (is_linux || is_chromeos) {
-      defines += [ "_XOPEN_SOURCE=500" ]
-    }
-  }
-
-  config("debase_config") {
-    include_dirs = [ "//third_party/khronos_glcts/framework/delibs/debase" ]
-  }
-  source_set("debase") {
-    sources = [
-      "//third_party/khronos_glcts/framework/delibs/debase/deDefs.c",
-      "//third_party/khronos_glcts/framework/delibs/debase/deDefs.h",
-      "//third_party/khronos_glcts/framework/delibs/debase/deFloat16.c",
-      "//third_party/khronos_glcts/framework/delibs/debase/deFloat16.h",
-      "//third_party/khronos_glcts/framework/delibs/debase/deInt32.c",
-      "//third_party/khronos_glcts/framework/delibs/debase/deInt32.h",
-      "//third_party/khronos_glcts/framework/delibs/debase/deInt32Test.c",
-      "//third_party/khronos_glcts/framework/delibs/debase/deMath.c",
-      "//third_party/khronos_glcts/framework/delibs/debase/deMath.h",
-      "//third_party/khronos_glcts/framework/delibs/debase/deMemory.c",
-      "//third_party/khronos_glcts/framework/delibs/debase/deMemory.h",
-      "//third_party/khronos_glcts/framework/delibs/debase/deRandom.c",
-      "//third_party/khronos_glcts/framework/delibs/debase/deRandom.h",
-      "//third_party/khronos_glcts/framework/delibs/debase/deString.c",
-      "//third_party/khronos_glcts/framework/delibs/debase/deString.h",
-    ]
-
-    configs += [ ":defaults_config" ]
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs -= [ "//build/config/compiler:no_rtti" ]
-    configs += [ "//build/config/compiler:rtti" ]
-
-    public_configs = [ ":debase_config" ]
-
-    if (is_linux || is_chromeos) {
-      cflags_c = [ "-Wno-implicit-function-declaration" ]
-    }
-  }
-
-  config("depool_config") {
-    include_dirs = [ "//third_party/khronos_glcts/framework/delibs/depool" ]
-  }
-  source_set("depool") {
-    sources = [
-      "//third_party/khronos_glcts/framework/delibs/depool/deMemPool.c",
-      "//third_party/khronos_glcts/framework/delibs/depool/deMemPool.h",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolArray.c",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolArray.h",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolHash.c",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolHash.h",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolHashArray.c",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolHashArray.h",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolHashSet.c",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolHashSet.h",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolHeap.c",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolHeap.h",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolMultiSet.c",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolMultiSet.h",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolSet.c",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolSet.h",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolStringBuilder.c",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolStringBuilder.h",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolTest.c",
-      "//third_party/khronos_glcts/framework/delibs/depool/dePoolTest.h",
-    ]
-
-    deps = [ ":debase" ]
-
-    configs += [ ":defaults_config" ]
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs -= [ "//build/config/compiler:no_rtti" ]
-    configs += [ "//build/config/compiler:rtti" ]
-
-    public_configs = [ ":depool_config" ]
-  }
-
-  config("dethread_config") {
-    include_dirs = [ "//third_party/khronos_glcts/framework/delibs/dethread" ]
-  }
-  source_set("dethread") {
-    sources = [
-      "//third_party/khronos_glcts/framework/delibs/dethread/deAtomic.c",
-      "//third_party/khronos_glcts/framework/delibs/dethread/deAtomic.h",
-      "//third_party/khronos_glcts/framework/delibs/dethread/deMutex.h",
-      "//third_party/khronos_glcts/framework/delibs/dethread/deSemaphore.h",
-      "//third_party/khronos_glcts/framework/delibs/dethread/deThread.h",
-      "//third_party/khronos_glcts/framework/delibs/dethread/deThreadLocal.h",
-      "//third_party/khronos_glcts/framework/delibs/dethread/deThreadTest.c",
-      "//third_party/khronos_glcts/framework/delibs/dethread/deThreadTest.h",
-    ]
-
-    deps = [ ":debase" ]
-
-    configs += [ ":defaults_config" ]
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs -= [ "//build/config/compiler:no_rtti" ]
-    configs += [ "//build/config/compiler:rtti" ]
-
-    public_configs = [ ":dethread_config" ]
-
-    if (is_linux || is_chromeos) {
-      sources += [
-        "//third_party/khronos_glcts/framework/delibs/dethread/unix/deMutexUnix.c",
-        "//third_party/khronos_glcts/framework/delibs/dethread/unix/deSemaphoreUnix.c",
-        "//third_party/khronos_glcts/framework/delibs/dethread/unix/deThreadLocalUnix.c",
-        "//third_party/khronos_glcts/framework/delibs/dethread/unix/deThreadUnix.c",
-      ]
-    }
-  }
-
-  config("deutil_config") {
-    include_dirs = [ "//third_party/khronos_glcts/framework/delibs/deutil" ]
-  }
-  source_set("deutil") {
-    sources = [
-      "//third_party/khronos_glcts/framework/delibs/deutil/deClock.c",
-      "//third_party/khronos_glcts/framework/delibs/deutil/deClock.h",
-      "//third_party/khronos_glcts/framework/delibs/deutil/deCommandLine.c",
-      "//third_party/khronos_glcts/framework/delibs/deutil/deCommandLine.h",
-      "//third_party/khronos_glcts/framework/delibs/deutil/deDynamicLibrary.c",
-      "//third_party/khronos_glcts/framework/delibs/deutil/deDynamicLibrary.h",
-      "//third_party/khronos_glcts/framework/delibs/deutil/deFile.c",
-      "//third_party/khronos_glcts/framework/delibs/deutil/deFile.h",
-      "//third_party/khronos_glcts/framework/delibs/deutil/deProcess.c",
-      "//third_party/khronos_glcts/framework/delibs/deutil/deProcess.h",
-      "//third_party/khronos_glcts/framework/delibs/deutil/deSocket.c",
-      "//third_party/khronos_glcts/framework/delibs/deutil/deSocket.h",
-      "//third_party/khronos_glcts/framework/delibs/deutil/deTimer.c",
-      "//third_party/khronos_glcts/framework/delibs/deutil/deTimer.h",
-      "//third_party/khronos_glcts/framework/delibs/deutil/deTimerTest.c",
-      "//third_party/khronos_glcts/framework/delibs/deutil/deTimerTest.h",
-    ]
-
-    deps = [
-      ":debase",
-      ":depool",
-      ":dethread",
-    ]
-
-    configs += [ ":defaults_config" ]
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs -= [ "//build/config/compiler:no_rtti" ]
-    configs += [ "//build/config/compiler:rtti" ]
-
-    public_configs = [ ":deutil_config" ]
-
-    if (is_linux || is_chromeos) {
-      cflags_c = [ "-Wno-string-conversion" ]
-    }
-  }
-
-  config("decpp_config") {
-    include_dirs = [ "//third_party/khronos_glcts/framework/delibs/decpp" ]
-  }
-  source_set("decpp") {
-    sources = [
-      "//third_party/khronos_glcts/framework/delibs/decpp/deBlockBuffer.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deBlockBuffer.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deDefs.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deDefs.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deDirectoryIterator.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deDirectoryIterator.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deDynamicLibrary.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deDynamicLibrary.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deFilePath.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deFilePath.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deMemPool.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deMemPool.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deMutex.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deMutex.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/dePoolArray.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/dePoolArray.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/dePoolString.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/dePoolString.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deRandom.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deRandom.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deRingBuffer.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deRingBuffer.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deSemaphore.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deSemaphore.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deSharedPtr.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deSharedPtr.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deSocket.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deSocket.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deStringUtil.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deStringUtil.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deThread.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deThread.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deThreadSafeRingBuffer.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deThreadSafeRingBuffer.hpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deUniquePtr.cpp",
-      "//third_party/khronos_glcts/framework/delibs/decpp/deUniquePtr.hpp",
-    ]
-
-    deps = [
-      ":debase",
-      ":depool",
-      ":dethread",
-      ":deutil",
-    ]
-
-    configs += [ ":defaults_config" ]
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs -= [ "//build/config/compiler:no_rtti" ]
-    configs += [ "//build/config/compiler:rtti" ]
-    configs -= [ "//build/config/compiler:no_exceptions" ]
-    configs += [ "//build/config/compiler:exceptions" ]
-
-    public_configs = [ ":decpp_config" ]
-  }
-
-  group("delibs") {
-    public_deps = [
-      ":debase",
-      ":decpp",
-      ":depool",
-      ":dethread",
-      ":deutil",
-    ]
-  }
-
-  config("qphelper_config") {
-    include_dirs = [ "//third_party/khronos_glcts/framework/qphelper" ]
-  }
-  source_set("qphelper") {
-    sources = [
-      "//third_party/khronos_glcts/framework/qphelper/qpCommandLine.c",
-      "//third_party/khronos_glcts/framework/qphelper/qpCommandLine.h",
-      "//third_party/khronos_glcts/framework/qphelper/qpCrashHandler.c",
-      "//third_party/khronos_glcts/framework/qphelper/qpCrashHandler.h",
-      "//third_party/khronos_glcts/framework/qphelper/qpDebugOut.c",
-      "//third_party/khronos_glcts/framework/qphelper/qpDebugOut.h",
-      "//third_party/khronos_glcts/framework/qphelper/qpInfo.c",
-      "//third_party/khronos_glcts/framework/qphelper/qpInfo.h",
-      "//third_party/khronos_glcts/framework/qphelper/qpTestLog.c",
-      "//third_party/khronos_glcts/framework/qphelper/qpTestLog.h",
-      "//third_party/khronos_glcts/framework/qphelper/qpWatchDog.c",
-      "//third_party/khronos_glcts/framework/qphelper/qpWatchDog.h",
-      "//third_party/khronos_glcts/framework/qphelper/qpXmlWriter.c",
-      "//third_party/khronos_glcts/framework/qphelper/qpXmlWriter.h",
-    ]
-
-    defines = [ "QP_SUPPORT_PNG" ]
-
-    deps = [
-      ":delibs",
-      "//third_party/libpng:libpng",
-    ]
-
-    configs += [ ":defaults_config" ]
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs -= [ "//build/config/compiler:no_rtti" ]
-    configs += [ "//build/config/compiler:rtti" ]
-
-    public_configs = [ ":qphelper_config" ]
-
-    if (is_linux || is_chromeos) {
-      cflags_c = [ "-Wno-string-conversion" ]
-    }
-  }
-
-  config("tcutil_config") {
-    include_dirs = [ "//third_party/khronos_glcts/framework/common" ]
-  }
-  source_set("tcutil") {
-    sources = [
-      "//third_party/khronos_glcts/framework/common/tcuApp.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuApp.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuCommandLine.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuCommandLine.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuCompressedTexture.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuCompressedTexture.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuDefs.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuDefs.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuFloat.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuFormatUtil.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuFuzzyImageCompare.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuFuzzyImageCompare.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuImageCompare.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuImageCompare.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuImageIO.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuImageIO.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuMatrix.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuMatrixUtil.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuPixelFormat.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuPlatform.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuPlatform.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuRGBA.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuRGBA.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuRandomValueIterator.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuRandomValueIterator.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuRenderTarget.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuRenderTarget.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuResource.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuResource.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuStringTemplate.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuStringTemplate.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuSurface.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuSurface.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuTestCase.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuTestCase.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuTestCaseWrapper.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuTestCaseWrapper.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuTestContext.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuTestContext.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuTestExecutor.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuTestExecutor.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuTestLog.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuTestLog.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuTestPackage.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuTestPackage.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuTexture.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuTexture.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuTextureUtil.cpp",
-      "//third_party/khronos_glcts/framework/common/tcuTextureUtil.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuVector.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuVectorType.hpp",
-      "//third_party/khronos_glcts/framework/common/tcuVectorUtil.hpp",
-
-      # Not used by anything...
-      #"//third_party/khronos_glcts/framework/common/tcuZipResource.cpp",
-      #"//third_party/khronos_glcts/framework/common/tcuZipResource.hpp",
-    ]
-
-    deps = [
-      ":delibs",
-      "//third_party/libpng:libpng",
-    ]
-
-    public_deps = [ ":qphelper" ]
-
-    include_dirs =
-        [ "//third_party/khronos_glcts/framework/delibs/libpng" ]  # png.hpp
-
-    configs += [ ":defaults_config" ]
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs -= [ "//build/config/compiler:no_rtti" ]
-    configs += [ "//build/config/compiler:rtti" ]
-    configs -= [ "//build/config/compiler:no_exceptions" ]
-    configs += [ "//build/config/compiler:exceptions" ]
-
-    public_configs = [ ":tcutil_config" ]
-
-    if (is_linux || is_chromeos) {
-      cflags_cc = [ "-Wno-int-to-pointer-cast" ]
-    }
-  }
-
-  config("glwrapper_config") {
-    include_dirs = [ "//third_party/khronos_glcts/framework/opengl/wrapper" ]
-  }
-  source_set("glwrapper") {
-    sources = [
-      "//third_party/khronos_glcts/framework/opengl/wrapper/glw.h",
-      "//third_party/khronos_glcts/framework/opengl/wrapper/glwDefs.cpp",
-      "//third_party/khronos_glcts/framework/opengl/wrapper/glwDefs.hpp",
-      "//third_party/khronos_glcts/framework/opengl/wrapper/glwEnums.hpp",
-      "//third_party/khronos_glcts/framework/opengl/wrapper/glwFunctionLoader.hpp",
-      "//third_party/khronos_glcts/framework/opengl/wrapper/glwFunctions.cpp",
-      "//third_party/khronos_glcts/framework/opengl/wrapper/glwFunctions.hpp",
-      "//third_party/khronos_glcts/framework/opengl/wrapper/glwInitES20Direct.cpp",
-      "//third_party/khronos_glcts/framework/opengl/wrapper/glwInitES20Direct.hpp",
-      "//third_party/khronos_glcts/framework/opengl/wrapper/glwInitFunctions.cpp",
-      "//third_party/khronos_glcts/framework/opengl/wrapper/glwInitFunctions.hpp",
-      "//third_party/khronos_glcts/framework/opengl/wrapper/glwWrapper.cpp",
-      "//third_party/khronos_glcts/framework/opengl/wrapper/glwWrapper.hpp",
-    ]
-
-    deps = [
-      ":delibs",
-      "//gpu/command_buffer/client:gles2_c_lib_nocheck",
-    ]
-
-    configs += [ ":defaults_config" ]
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs -= [ "//build/config/compiler:no_rtti" ]
-    configs += [ "//build/config/compiler:rtti" ]
-    configs -= [ "//build/config/compiler:no_exceptions" ]
-    configs += [ "//build/config/compiler:exceptions" ]
-
-    public_configs = [ ":glwrapper_config" ]
-  }
-
-  config("glutil_config") {
-    include_dirs = [ "//third_party/khronos_glcts/framework/opengl" ]
-  }
-  source_set("glutil") {
-    sources = [
-      "//third_party/khronos_glcts/framework/opengl/gluCallLogWrapper.cpp",
-      "//third_party/khronos_glcts/framework/opengl/gluCallLogWrapper.hpp",
-      "//third_party/khronos_glcts/framework/opengl/gluContextInfo.cpp",
-      "//third_party/khronos_glcts/framework/opengl/gluContextInfo.hpp",
-      "//third_party/khronos_glcts/framework/opengl/gluDefs.cpp",
-      "//third_party/khronos_glcts/framework/opengl/gluDefs.hpp",
-      "//third_party/khronos_glcts/framework/opengl/gluDrawUtil.cpp",
-      "//third_party/khronos_glcts/framework/opengl/gluDrawUtil.hpp",
-      "//third_party/khronos_glcts/framework/opengl/gluFboRenderContext.cpp",
-      "//third_party/khronos_glcts/framework/opengl/gluFboRenderContext.hpp",
-      "//third_party/khronos_glcts/framework/opengl/gluPixelTransfer.cpp",
-      "//third_party/khronos_glcts/framework/opengl/gluPixelTransfer.hpp",
-      "//third_party/khronos_glcts/framework/opengl/gluPlatform.hpp",
-      "//third_party/khronos_glcts/framework/opengl/gluProgram.cpp",
-      "//third_party/khronos_glcts/framework/opengl/gluProgram.hpp",
-      "//third_party/khronos_glcts/framework/opengl/gluRenderContext.cpp",
-      "//third_party/khronos_glcts/framework/opengl/gluRenderContext.hpp",
-      "//third_party/khronos_glcts/framework/opengl/gluShaderUtil.cpp",
-      "//third_party/khronos_glcts/framework/opengl/gluShaderUtil.hpp",
-      "//third_party/khronos_glcts/framework/opengl/gluStateReset.cpp",
-      "//third_party/khronos_glcts/framework/opengl/gluStateReset.hpp",
-      "//third_party/khronos_glcts/framework/opengl/gluStrUtil.cpp",
-      "//third_party/khronos_glcts/framework/opengl/gluStrUtil.hpp",
-      "//third_party/khronos_glcts/framework/opengl/gluTexture.cpp",
-      "//third_party/khronos_glcts/framework/opengl/gluTexture.hpp",
-      "//third_party/khronos_glcts/framework/opengl/gluTextureUtil.cpp",
-      "//third_party/khronos_glcts/framework/opengl/gluTextureUtil.hpp",
-      "//third_party/khronos_glcts/framework/opengl/gluVarType.cpp",
-      "//third_party/khronos_glcts/framework/opengl/gluVarType.hpp",
-      "//third_party/khronos_glcts/framework/opengl/gluVarTypeUtil.cpp",
-      "//third_party/khronos_glcts/framework/opengl/gluVarTypeUtil.hpp",
-    ]
-
-    public_deps = [ ":glwrapper" ]
-
-    deps = [
-      ":delibs",
-      ":tcutil",
-    ]
-
-    configs += [ ":defaults_config" ]
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs -= [ "//build/config/compiler:no_rtti" ]
-    configs += [ "//build/config/compiler:rtti" ]
-    configs -= [ "//build/config/compiler:no_exceptions" ]
-    configs += [ "//build/config/compiler:exceptions" ]
-
-    public_configs = [ ":glutil_config" ]
-  }
-
-  config("tcutil_egl_config") {
-    include_dirs = [ "//third_party/khronos_glcts/framework/egl" ]
-  }
-  source_set("tcutil_egl") {
-    sources = [
-      "//third_party/khronos_glcts/framework/egl/tcuEgl.cpp",
-      "//third_party/khronos_glcts/framework/egl/tcuEgl.hpp",
-      "//third_party/khronos_glcts/framework/egl/tcuEglCallLogWrapper.cpp",
-      "//third_party/khronos_glcts/framework/egl/tcuEglCallLogWrapper.hpp",
-      "//third_party/khronos_glcts/framework/egl/tcuEglConfigFilter.cpp",
-      "//third_party/khronos_glcts/framework/egl/tcuEglConfigFilter.hpp",
-      "//third_party/khronos_glcts/framework/egl/tcuEglConfigInfo.cpp",
-      "//third_party/khronos_glcts/framework/egl/tcuEglConfigInfo.hpp",
-      "//third_party/khronos_glcts/framework/egl/tcuEglPlatform.cpp",
-      "//third_party/khronos_glcts/framework/egl/tcuEglPlatform.hpp",
-      "//third_party/khronos_glcts/framework/egl/tcuEglStrUtil.cpp",
-      "//third_party/khronos_glcts/framework/egl/tcuEglStrUtil.hpp",
-    ]
-
-    deps = [
-      ":delibs",
-      ":glwrapper",
-      ":tcutil",
-      "//gpu/gles2_conform_support/egl",
-    ]
-
-    include_dirs = [ "//third_party/khronos_glcts/framework/opengl" ]
-
-    configs += [ ":defaults_config" ]
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs -= [ "//build/config/compiler:no_rtti" ]
-    configs += [ "//build/config/compiler:rtti" ]
-    configs -= [ "//build/config/compiler:no_exceptions" ]
-    configs += [ "//build/config/compiler:exceptions" ]
-
-    public_configs = [
-      ":tcutil_egl_config",
-      "//third_party/khronos:khronos_headers",
-    ]
-
-    if (is_linux || is_chromeos) {
-      cflags_cc = [ "-Wno-int-to-void-pointer-cast" ]
-    }
-  }
-
-  group("khronos_glcts_framework") {
-    public_deps = [
-      ":delibs",
-      ":glutil",
-      ":qphelper",
-      ":tcutil",
-      ":tcutil_egl",
-    ]
-  }
-
-  config("glcts_common_config") {
-    include_dirs = [ "//third_party/khronos_glcts/cts/common" ]
-  }
-  source_set("glcts_common") {
-    sources = [
-      "//third_party/khronos_glcts/cts/common/glcConfigList.cpp",
-      "//third_party/khronos_glcts/cts/common/glcConfigList.hpp",
-      "//third_party/khronos_glcts/cts/common/glcConfigListCase.cpp",
-      "//third_party/khronos_glcts/cts/common/glcConfigListCase.hpp",
-      "//third_party/khronos_glcts/cts/common/glcConfigPackage.cpp",
-      "//third_party/khronos_glcts/cts/common/glcConfigPackage.hpp",
-      "//third_party/khronos_glcts/cts/common/glcContext.cpp",
-      "//third_party/khronos_glcts/cts/common/glcContext.hpp",
-      "//third_party/khronos_glcts/cts/common/glcFragDepthTests.cpp",
-      "//third_party/khronos_glcts/cts/common/glcFragDepthTests.hpp",
-      "//third_party/khronos_glcts/cts/common/glcInfoTests.cpp",
-      "//third_party/khronos_glcts/cts/common/glcInfoTests.hpp",
-      "//third_party/khronos_glcts/cts/common/glcShaderIndexingTests.cpp",
-      "//third_party/khronos_glcts/cts/common/glcShaderIndexingTests.hpp",
-      "//third_party/khronos_glcts/cts/common/glcShaderIntegerMixTests.cpp",
-      "//third_party/khronos_glcts/cts/common/glcShaderIntegerMixTests.hpp",
-      "//third_party/khronos_glcts/cts/common/glcShaderLibrary.cpp",
-      "//third_party/khronos_glcts/cts/common/glcShaderLibrary.hpp",
-      "//third_party/khronos_glcts/cts/common/glcShaderLibraryCase.cpp",
-      "//third_party/khronos_glcts/cts/common/glcShaderLibraryCase.hpp",
-      "//third_party/khronos_glcts/cts/common/glcShaderLoopTests.cpp",
-      "//third_party/khronos_glcts/cts/common/glcShaderLoopTests.hpp",
-      "//third_party/khronos_glcts/cts/common/glcShaderRenderCase.cpp",
-      "//third_party/khronos_glcts/cts/common/glcShaderRenderCase.hpp",
-      "//third_party/khronos_glcts/cts/common/glcShaderStructTests.cpp",
-      "//third_party/khronos_glcts/cts/common/glcShaderStructTests.hpp",
-      "//third_party/khronos_glcts/cts/common/glcShaderSwitchTests.cpp",
-      "//third_party/khronos_glcts/cts/common/glcShaderSwitchTests.hpp",
-      "//third_party/khronos_glcts/cts/common/glcTestCase.cpp",
-      "//third_party/khronos_glcts/cts/common/glcTestCase.hpp",
-      "//third_party/khronos_glcts/cts/common/glcTestCaseWrapper.cpp",
-      "//third_party/khronos_glcts/cts/common/glcTestCaseWrapper.hpp",
-      "//third_party/khronos_glcts/cts/common/glcTestPackage.cpp",
-      "//third_party/khronos_glcts/cts/common/glcTestPackage.hpp",
-      "//third_party/khronos_glcts/cts/common/glcTestSubcase.cpp",
-      "//third_party/khronos_glcts/cts/common/glcTestSubcase.hpp",
-      "//third_party/khronos_glcts/cts/common/glcUniformBlockCase.cpp",
-      "//third_party/khronos_glcts/cts/common/glcUniformBlockCase.hpp",
-      "//third_party/khronos_glcts/cts/common/glcUniformBlockTests.cpp",
-      "//third_party/khronos_glcts/cts/common/glcUniformBlockTests.hpp",
-    ]
-
-    deps = [
-      ":delibs",
-      ":glutil",
-      ":tcutil",
-      ":tcutil_egl",
-    ]
-
-    configs += [ ":defaults_config" ]
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs -= [ "//build/config/compiler:no_rtti" ]
-    configs += [ "//build/config/compiler:rtti" ]
-    configs -= [ "//build/config/compiler:no_exceptions" ]
-    configs += [ "//build/config/compiler:exceptions" ]
-
-    public_configs = [ ":glcts_common_config" ]
-
-    if (is_linux || is_chromeos) {
-      cflags_cc = [ "-Wno-string-conversion" ]
-    }
-  }
-
-  config("glcts_gtf_wrapper_config") {
-    include_dirs = [ "//third_party/khronos_glcts/cts/gtf" ]
-  }
-  source_set("glcts_gtf_wrapper") {
-    sources = [
-      "//third_party/khronos_glcts/cts/gtf/gtfTestContext.cpp",
-      "//third_party/khronos_glcts/cts/gtf/gtfTestContext.hpp",
-      "//third_party/khronos_glcts/cts/gtf/gtfWrapper.cpp",
-      "//third_party/khronos_glcts/cts/gtf/gtfWrapper.h",
-    ]
-
-    deps = [
-      ":delibs",
-      ":glcts_common",
-      ":glutil",
-      ":tcutil",
-      ":tcutil_egl",
-    ]
-
-    include_dirs = [ "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source" ]
-
-    configs += [ ":defaults_config" ]
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs -= [ "//build/config/compiler:no_rtti" ]
-    configs += [ "//build/config/compiler:rtti" ]
-    configs -= [ "//build/config/compiler:no_exceptions" ]
-    configs += [ "//build/config/compiler:exceptions" ]
-
-    public_configs = [ ":glcts_gtf_wrapper_config" ]
-  }
-
-  config("gtf_es_config") {
-    include_dirs = [ "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source" ]
-  }
-  source_set("gtf_es") {
-    sources = [
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL/GTFAttDataGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL/GTFDepthRangeParamGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL/GTFModelDataGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL/GTFPointParamGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL/GTFReadPixelsGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL/GTFShaderDataGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL/GTFShaderTextGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL/GTFStateDataGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL/GTFTestTextureFloatBase.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL/GTFTexDataGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL/GTFTexParamGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL/GTFUniDataGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFArguments.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFFileReader.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFLog.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFMemFile.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFModelData.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFPort.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFStringUtils.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFTest.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFTestCompareGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFTestDriver.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFTestElement.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFTestUtil.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFgl.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/MIMG.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/XmlUtils.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/eglu.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/eglut.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/gl2Native.c",
-
-      # Base
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestAttributeGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestBindAllAttributes.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestCreateObjectGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestDetachGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestFixedDataType.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestFramebufferObjects.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestGetAttachedObjects.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestGetAttributeLocation.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestGetBIFD.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestGetExtensions.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestGetProgramInfoLog.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestGetProgramiv.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestGetShaderInfoLog.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestGetShaderiv.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestGetUniform.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestGetVertexAttrib.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestMaxVertexAttrib.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestMultipleShaders.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestRelinkProgram.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestUniform.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestUniformQueryGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestVertexAttribPointer.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestVertexAttributes.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2Tests/GTFGL2TestVertexProgramPointSize.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFTestGL2Test.c",
-
-      # Build
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFTestBuildGL.c",
-
-      # Shader load
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFTestShaderLoadGL.c",
-
-      # Rasterization
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFTestRasterizationGL.c",
-
-      # Complexity
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFTestComplexityGL.c",
-
-      # Coverage
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFCoverageDict.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFCoverageGL.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFTestCoverageGL.c",
-
-      # Fixed-function
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestBlend.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestBufferClear.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestBufferColor.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestBufferCorners.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestBufferObjects.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestClip.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestColorRamp.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestCopyTexture.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestDepthBufferClear.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestDepthBufferFunctions.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestDither.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestDivideByZero.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestGets.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestMipmapsInterpolation.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestMipmapsSelection.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestPointRasterization.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestPointSprites.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestPolygonCull.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestScissor.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestStencilPlaneClear.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestStencilPlaneCorners.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestStencilPlaneFunction.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestStencilPlaneOperation.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestTextureEdgeClamp.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestTransformViewport.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestTriangleRasterization.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestTriangleTiling.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestUserClipPlanes.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestVertexOrder.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedTestViewportClamp.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedUtilg.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2FixedTests/GTFFixedUtilr.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFTestFixedGL.c",
-
-      # Extensions
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestConditionalQuery.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestDataType1010102.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestDebug.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestDepth24.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestDepth32.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestDepthTexture.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestDepthTextureCubeMap.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestElementIndexUINT.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestFBORenderMipmap.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestFragmentPrecisionHigh.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestFramebufferObject.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestMapBuffer.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestOcclusionQuery.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestPackedDepthStencil.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestPointSizeArray.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestPointSprite.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestReadFormat.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestStencil1.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestStencil4.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestStencil8.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestTexture3D.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestTextureCompressionASTCLDR.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestTextureFloat.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestTextureFloatLinear.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestTextureNPOT.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestUtilp.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestVertexArrayObject.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestVertexHalfFloat.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GTFTestExtension.c",
-
-      # ES only.
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestCompressedETC1RGB8Texture.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestCompressedPalettedTexture.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestEGLCreateContext.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestEGLImage.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestEGLImageExternal.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestRGB8RGBA8.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestRequiredInternalformat.c",
-      "//third_party/khronos_glcts/GTF_ES/glsl/GTF/Source/GL2ExtensionTests/GTFExtensionTestSurfacelessContext.c",
-    ]
-
-    deps = [
-      ":debase",
-      ":glcts_gtf_wrapper",
-      "//third_party/expat",
-    ]
-
-    configs += [ ":defaults_config" ]
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs -= [ "//build/config/compiler:no_rtti" ]
-    configs += [ "//build/config/compiler:rtti" ]
-
-    public_configs = [ ":gtf_es_config" ]
-
-    if (is_linux || is_chromeos) {
-      cflags_c = [
-        "-Wno-pointer-sign",
-        "-Wno-incompatible-pointer-types",
-        "-Wno-return-type",
-        "-Wno-parentheses-equality",
-        "-Wno-tautological-compare",
-      ]
-    }
-  }
-
-  config("glcts_gtf_config") {
-    include_dirs = [ "//third_party/khronos_glcts/cts/gtf" ]
-  }
-  source_set("glcts_gtf") {
-    sources = [
-      "//third_party/khronos_glcts/cts/gtf/gtfTestCase.cpp",
-      "//third_party/khronos_glcts/cts/gtf/gtfTestCase.hpp",
-      "//third_party/khronos_glcts/cts/gtf/gtfTestGroup.cpp",
-      "//third_party/khronos_glcts/cts/gtf/gtfTestGroup.hpp",
-    ]
-
-    deps = [
-      ":delibs",
-      ":glcts_common",
-      ":glcts_gtf_wrapper",
-      ":glutil",
-      ":gtf_es",
-      ":tcutil",
-    ]
-
-    configs += [ ":defaults_config" ]
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs -= [ "//build/config/compiler:no_rtti" ]
-    configs += [ "//build/config/compiler:rtti" ]
-    configs -= [ "//build/config/compiler:no_exceptions" ]
-    configs += [ "//build/config/compiler:exceptions" ]
-
-    public_configs = [ ":glcts_gtf_config" ]
-  }
-
-  config("glcts_es2_config") {
-    include_dirs = [ "//third_party/khronos_glcts/cts/gles2" ]
-  }
-  source_set("glcts_es2") {
-    sources = [
-      "//third_party/khronos_glcts/cts/gles2/es2cTestPackage.cpp",
-      "//third_party/khronos_glcts/cts/gles2/es2cTestPackage.hpp",
-    ]
-
-    public_deps = [ ":glcts_common" ]
-
-    deps = [
-      ":delibs",
-      ":glcts_gtf",
-      ":glutil",
-      ":tcutil",
-    ]
-
-    configs += [ ":defaults_config" ]
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs -= [ "//build/config/compiler:no_rtti" ]
-    configs += [ "//build/config/compiler:rtti" ]
-    configs -= [ "//build/config/compiler:no_exceptions" ]
-    configs += [ "//build/config/compiler:exceptions" ]
-
-    public_configs = [ ":glcts_es2_config" ]
-  }
-
-  source_set("tcutil_platform_windowless") {
-    sources = [ "native/egl_native_windowless.cc" ]
-
-    deps = [ ":khronos_glcts_framework" ]
-
-    configs -= [ "//build/config/compiler:no_rtti" ]
-    configs += [ "//build/config/compiler:rtti" ]
-  }
-
-  executable("khronos_glcts_test_windowless") {
-    sources = [
-      "//third_party/khronos_glcts/cts/glcTestPackageEntry.cpp",
-      "//third_party/khronos_glcts/cts/glcTestPackageRegistry.cpp",
-      "//third_party/khronos_glcts/cts/glcTestPackageRegistry.hpp",
-      "native/main.cc",
-    ]
-
-    deps = [
-      ":glcts_es2",
-      ":glcts_gtf_resources",
-      ":glcts_resources",
-      ":khronos_glcts_framework",
-      ":tcutil_platform_windowless",
-    ]
-
-    configs += [ ":defaults_config" ]
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs -= [ "//build/config/compiler:no_exceptions" ]
-    configs += [ "//build/config/compiler:exceptions" ]
-  }
-}
-
-if (!is_android) {
-  test("khronos_glcts_test") {
-    sources = [
-      "khronos_glcts_test.cc",
-      "khronos_glcts_test.h",
-    ]
-
-    deps = [
-      "//base",
-      "//gpu",
-      "//testing/gtest",
-    ]
-
-    data = [ "khronos_glcts_test_expectations.txt" ]
-
-    if (internal_khronos_glcts_tests) {
-      sources += [ "$target_gen_dir/khronos_glcts_test_autogen.cc" ]
-      deps += [
-        ":generate_khronos_glcts_tests",
-        ":khronos_glcts_test_windowless",
-      ]
-    }
-  }
-}
diff --git a/gpu/khronos_glcts_support/DEPS b/gpu/khronos_glcts_support/DEPS
deleted file mode 100644
index 9d9bc74..0000000
--- a/gpu/khronos_glcts_support/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
-  "+third_party/khronos_glcts",
-]
diff --git a/gpu/khronos_glcts_support/generate_khronos_glcts_tests.py b/gpu/khronos_glcts_support/generate_khronos_glcts_tests.py
deleted file mode 100755
index f6dd1cf..0000000
--- a/gpu/khronos_glcts_support/generate_khronos_glcts_tests.py
+++ /dev/null
@@ -1,117 +0,0 @@
-#!/usr/bin/env python3
-# Copyright 2014 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Code generator for khronos_glcts tests."""
-
-import argparse
-import os
-import re
-import sys
-import typing
-
-TEST_DEF_TEMPLATE = """
-TEST(KhronosGLCTSTest, %(gname)s) {
-  EXPECT_TRUE(RunKhronosGLCTSTest("%(cname)s"));
-}
-"""
-
-RUN_FILE_SUITE_PREFIX = {
-  "mustpass_es20.run" : "ES2-CTS.gtf",
-}
-
-BUILT_IN_TESTS = {
-  "mustpass_es20.run" : [
-    "CTS-Configs.es2",
-    "ES2-CTS.info.vendor",
-    "ES2-CTS.info.renderer",
-    "ES2-CTS.info.version",
-    "ES2-CTS.info.shading_language_version",
-    "ES2-CTS.info.extensions",
-    "ES2-CTS.info.render_target",
-  ],
-}
-
-def ReadFileAsLines(filename: str) -> typing.Generator[str, None, None]:
-  """
-    Reads a file, yielding each non-blank line
-    and lines that don't begin with #
-  """
-  with open(filename, "r") as in_file:
-    lines = in_file.readlines()
-  for line in lines:
-    line = line.strip()
-    if len(line) > 0 and not line.startswith("#"):
-      yield line
-
-def ReadRunFile(run_file: str) -> typing.List[str]:
-  """
-    Find all .test tests in a .run file and return their paths.
-    If the .run file contains another .run file, then that is inspected
-    too.
-  """
-  tests = []
-  base_dir = os.path.dirname(run_file)
-  for line in ReadFileAsLines(run_file):
-    _, ext = os.path.splitext(line)
-    if ext == ".test":
-      tests.append(os.path.join(base_dir, line))
-    elif ext == ".run":
-      tests += ReadRunFile(os.path.join(base_dir, line))
-    else:
-      raise ValueError("Unexpected line '%s' in '%s'" % (line, run_file))
-  return tests
-
-def GenerateTests(run_files: typing.List[str], output: typing.IO) -> None:
-  """
-    Generates code for khronos_glcts_test test-cases that are
-    listed in the run_files.
-  """
-  output.write('#include "gpu/khronos_glcts_support/khronos_glcts_test.h"\n')
-  output.write('#include "testing/gtest/include/gtest/gtest.h"\n\n')
-
-  for run_file in run_files:
-    run_file_name = os.path.basename(run_file)
-    run_file_dir = os.path.dirname(run_file)
-    suite_prefix = RUN_FILE_SUITE_PREFIX[run_file_name]
-    output.write("// " + run_file_name + "\n")
-    builtin_tests = BUILT_IN_TESTS[run_file_name]
-    for test in builtin_tests:
-      output.write(TEST_DEF_TEMPLATE
-        % {
-          "gname": re.sub(r'[^A-Za-z0-9]', '_', test),
-          "cname": test,
-        })
-    for test in ReadRunFile(run_file):
-      rel_path = os.path.relpath(test, run_file_dir)
-      root, _ = os.path.splitext(rel_path)
-      name = root.replace('.', '_')
-      name = "%s.%s" % (suite_prefix, name.replace(os.path.sep, '.'))
-      output.write(TEST_DEF_TEMPLATE
-        % {
-          "gname": re.sub(r'[^A-Za-z0-9]', '_', name),
-          "cname": name,
-        })
-    output.write("\n");
-
-def main() -> int:
-  """This is the main function."""
-  parser = argparse.ArgumentParser()
-  parser.add_argument("--outdir", default = ".")
-  parser.add_argument("run_files", nargs = "+")
-
-  args = parser.parse_args()
-
-  output = open(
-    os.path.join(args.outdir, "khronos_glcts_test_autogen.cc"), "w")
-
-  try:
-    GenerateTests(args.run_files, output)
-  finally:
-    output.close()
-
-  return 0
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/gpu/khronos_glcts_support/khronos_glcts_test.cc b/gpu/khronos_glcts_support/khronos_glcts_test.cc
deleted file mode 100644
index 93f54cf8..0000000
--- a/gpu/khronos_glcts_support/khronos_glcts_test.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2014 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "gpu/khronos_glcts_support/khronos_glcts_test.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <string>
-
-#include "base/at_exit.h"
-#include "base/base_paths.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/logging.h"
-#include "base/path_service.h"
-#include "base/process/launch.h"
-#include "base/strings/string_util.h"
-#include "gpu/config/gpu_test_config.h"
-#include "gpu/config/gpu_test_expectations_parser.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-base::FilePath g_deqp_log_dir;
-
-bool RunKhronosGLCTSTest(const char* test_name) {
-  // Load test expectations, and return early if a test is marked as FAIL.
-  base::FilePath src_path;
-  base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &src_path);
-  base::FilePath test_expectations_path =
-      src_path.Append(FILE_PATH_LITERAL("gpu")).
-      Append(FILE_PATH_LITERAL("khronos_glcts_support")).
-      Append(FILE_PATH_LITERAL("khronos_glcts_test_expectations.txt"));
-  if (!base::PathExists(test_expectations_path)) {
-    LOG(ERROR) << "Fail to locate khronos_glcts_test_expectations.txt";
-    return false;
-  }
-  gpu::GPUTestExpectationsParser test_expectations;
-  if (!test_expectations.LoadTestExpectations(test_expectations_path)) {
-    LOG(ERROR) << "Fail to load khronos_glcts_test_expectations.txt";
-    return false;
-  }
-  gpu::GPUTestBotConfig bot_config;
-  if (!bot_config.LoadCurrentConfig(nullptr)) {
-    LOG(ERROR) << "Fail to load bot configuration";
-    return false;
-  }
-  if (!bot_config.IsValid()) {
-    LOG(ERROR) << "Invalid bot configuration";
-    return false;
-  }
-
-  const ::testing::TestInfo* const test_info =
-      ::testing::UnitTest::GetInstance()->current_test_info();
-  int32_t expectation =
-      test_expectations.GetTestExpectation(test_info->name(), bot_config);
-  if (expectation != gpu::GPUTestExpectationsParser::kGpuTestPass) {
-    LOG(WARNING) << "Test " << test_info->name() << " is bypassed";
-    return true;
-  }
-
-  base::FilePath test_path;
-  base::PathService::Get(base::DIR_EXE, &test_path);
-  base::FilePath archive(test_path.Append(FILE_PATH_LITERAL(
-      "khronos_glcts_data")));
-  base::FilePath program(test_path.Append(FILE_PATH_LITERAL(
-      "khronos_glcts_test_windowless")));
-  base::FilePath log =
-      g_deqp_log_dir.AppendASCII(test_info->name()).
-      AddExtension(FILE_PATH_LITERAL(".log"));
-
-  base::CommandLine cmdline(program);
-  cmdline.AppendSwitchPath("--deqp-log-filename", log);
-  cmdline.AppendSwitchPath("--deqp-archive-dir", archive);
-  cmdline.AppendArg("--deqp-gl-config-id=-1");
-  cmdline.AppendArg(std::string("--deqp-case=") + test_name);
-
-  std::string output;
-  bool success = base::GetAppOutput(cmdline, &output);
-  if (success) {
-    size_t success_index = output.find("Pass (Pass)");
-    size_t failed_index = output.find("Fail (Fail)");
-    success = (success_index != std::string::npos) &&
-              (failed_index == std::string::npos);
-  }
-  if (!success) {
-    LOG(ERROR) << output;
-  }
-  return success;
-}
-
-int main(int argc, char *argv[]) {
-  base::AtExitManager at_exit;
-
-  ::testing::InitGoogleTest(&argc, argv);
-
-  if (argc == 2) {
-    g_deqp_log_dir = base::FilePath::FromUTF8Unsafe(argv[1]);
-  }
-  else {
-    base::GetTempDir(&g_deqp_log_dir);
-  }
-
-  return RUN_ALL_TESTS();
-}
-
diff --git a/gpu/khronos_glcts_support/khronos_glcts_test.h b/gpu/khronos_glcts_support/khronos_glcts_test.h
deleted file mode 100644
index 54c4d837..0000000
--- a/gpu/khronos_glcts_support/khronos_glcts_test.h
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2014 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef GPU_KHRONOS_GLCTS_SUPPORT_KHRONOS_GLCTS_TEST_H_
-#define GPU_KHRONOS_GLCTS_SUPPORT_KHRONOS_GLCTS_TEST_H_
-
-bool RunKhronosGLCTSTest(const char* test_name);
-
-#endif  // GPU_KHRONOS_GLCTS_SUPPORT_KHRONOS_GLCTS_TEST_H_
diff --git a/gpu/khronos_glcts_support/khronos_glcts_test_expectations.txt b/gpu/khronos_glcts_support/khronos_glcts_test_expectations.txt
deleted file mode 100644
index 4a65ba3..0000000
--- a/gpu/khronos_glcts_support/khronos_glcts_test_expectations.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2014 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file contains a list of defective khronos_glcts conformance tests. The
-// expected format is:
-//  {BUG#} {MODIFIERS} : {TEST_NAME} = {PASS,FAIL,FLAKY,TIMEOUT,SKIP}
-//
-// MODIFIERS can be a combination of the below list:
-//  WIN XP VISTA WIN7 MAC LEOPARD SNOWLEOPARD LION LINUX CHROMEOS MOUNTAINLION
-//  MAVERICKS
-//  NVIDIA AMD INTEL
-//  0xabcd - GPU PCI device ID. Specifying a PCI id requires a vendor.
-//  DEBUG RELEASE
-//
-// TEST_NAME can be a specific test name, or have a '*' in the end, which
-// indicates a prefix matching.
-//
-// Any tests whose expectations are not PASS will be skipped on the bots.
-//
-// Examples:
-//  91530 MAC WIN LINUX : context_lost_restored = TIMEOUT
-//  91533 WIN : gl_min_uniforms = FAIL
-//  91531 MAC WIN LINUX : conformance_more_* = SKIP
-//  91532 MAC NVIDIA 0x0640 : tex_image_and_sub_image_2d_with_video = PASS FAIL
-
-// Chromium implements GL_ARB_texture_rectangle which makes this test fail
-139729 DEBUG RELEASE : ES2_CTS_gtf_GL_build_Texture_Rectangle_Samplers_frag = FAIL
-
-// eglGetCurrentDisplay() returns EGL_NO_DISPLAY which causes this test to fail.
-421568 DEBUG RELEASE : ES2_CTS_gtf_GL2ExtensionTests_egl_create_context_egl_create_context = FAIL
-
-////////////////////////////////////////////////////////////////////////////////
-//
-//  Temporary entries: they should be removed once the bugs are fixed.
-//
-////////////////////////////////////////////////////////////////////////////////
diff --git a/gpu/khronos_glcts_support/native/egl_native_windowless.cc b/gpu/khronos_glcts_support/native/egl_native_windowless.cc
deleted file mode 100644
index a9fd2201..0000000
--- a/gpu/khronos_glcts_support/native/egl_native_windowless.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2014 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Using egl_native from gles2_conform_support
-// TODO: We may want to phase out the old gles2_conform support in preference
-// of this implementation.  So eventually we'll need to move the egl_native
-// stuff here or to a shareable location/path.
-#include "gpu/gles2_conform_support/egl/test_support.h"
-
-#include "third_party/khronos_glcts/framework/egl/tcuEglPlatform.hpp"
-
-namespace egl {
-namespace native {
-namespace windowless {
-
-class Surface : public tcu::egl::WindowSurface {
- public:
-  Surface(tcu::egl::Display& display,
-          EGLConfig config,
-          const EGLint* attribList,
-          int width,
-          int height)
-      : tcu::egl::WindowSurface(display,
-                                config,
-                                (EGLNativeWindowType) nullptr,
-                                attribList),
-        width_(width),
-        height_(height) {}
-
-  int getWidth() const override { return width_; }
-
-  int getHeight() const override { return height_; }
-
- private:
-  const int width_;
-  const int height_;
-};
-
-class Window : public tcu::NativeWindow {
- public:
-  Window(tcu::egl::Display& display,
-         EGLConfig config,
-         const EGLint* attribList,
-         int width,
-         int height)
-      : tcu::NativeWindow::NativeWindow(),
-        eglDisplay_(display),
-        surface_(display, config, attribList, width, height) {}
-
-  ~Window() override {}
-
-  tcu::egl::Display& getEglDisplay() override { return eglDisplay_; }
-
-  tcu::egl::WindowSurface& getEglSurface() override { return surface_; }
-
-  void processEvents() override { return; }
-
- private:
-  tcu::egl::Display& eglDisplay_;
-  Surface surface_;
-};
-
-class Platform : public tcu::EglPlatform {
- public:
-  Platform() : tcu::EglPlatform::EglPlatform() {}
-
-  ~Platform() override {}
-
-  tcu::NativeWindow* createWindow(tcu::NativeDisplay& dpy,
-                                  EGLConfig config,
-                                  const EGLint* attribList,
-                                  int width,
-                                  int height,
-                                  qpVisibility visibility) override {
-    tcu::egl::Display& eglDisplay = dpy.getEglDisplay();
-    EGLDisplay display = eglDisplay.getEGLDisplay();
-    CommandBufferGLESSetNextCreateWindowSurfaceCreatesPBuffer(display, width,
-                                                              height);
-    return new Window(eglDisplay, config, attribList, width, height);
-  }
-};
-
-}  // namespace windowless
-}  // namespace native
-}  // namespace egl
-
-tcu::Platform* createPlatform(void) {
-  return new egl::native::windowless::Platform();
-}
diff --git a/gpu/khronos_glcts_support/native/main.cc b/gpu/khronos_glcts_support/native/main.cc
deleted file mode 100644
index 184575e..0000000
--- a/gpu/khronos_glcts_support/native/main.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2014 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <cstdio>
-
-#include "base/at_exit.h"
-#include "base/command_line.h"
-#include "base/message_loop/message_pump_type.h"
-#include "base/task/single_thread_task_executor.h"
-
-#include "third_party/khronos_glcts/framework/common/tcuApp.hpp"
-#include "third_party/khronos_glcts/framework/common/tcuCommandLine.hpp"
-#include "third_party/khronos_glcts/framework/common/tcuDefs.hpp"
-#include "third_party/khronos_glcts/framework/common/tcuPlatform.hpp"
-#include "third_party/khronos_glcts/framework/common/tcuResource.hpp"
-#include "third_party/khronos_glcts/framework/common/tcuTestLog.hpp"
-#include "third_party/khronos_glcts/framework/delibs/decpp/deUniquePtr.hpp"
-
-// implemented in the native platform
-tcu::Platform* createPlatform ();
-
-void GTFMain(int argc, char* argv[]) {
-  setvbuf(stdout, DE_nullptr, _IOLBF, 4 * 1024);
-
-  try {
-    tcu::CommandLine cmdLine(argc, argv);
-    tcu::DirArchive archive(cmdLine.getArchiveDir());
-    tcu::TestLog log(cmdLine.getLogFileName(), cmdLine.getLogFlags());
-    de::UniquePtr<tcu::Platform> platform(createPlatform());
-    de::UniquePtr<tcu::App> app(
-      new tcu::App(*platform, archive, log, cmdLine));
-
-    // Main loop.
-    for (;;) {
-      if (!app->iterate())
-        break;
-    }
-  }
-  catch (const std::exception& e) {
-    tcu::die("%s", e.what());
-  }
-}
-
-int main(int argc, char *argv[]) {
-  base::AtExitManager at_exit;
-  base::CommandLine::Init(argc, argv);
-  base::SingleThreadTaskExecutor main_task_executor(base::MessagePumpType::UI);
-
-  GTFMain(argc, argv);
-
-  return 0;
-}
diff --git a/headless/lib/browser/command_line_handler.cc b/headless/lib/browser/command_line_handler.cc
index 567bfd95..a073e54 100644
--- a/headless/lib/browser/command_line_handler.cc
+++ b/headless/lib/browser/command_line_handler.cc
@@ -215,6 +215,10 @@
     builder.SetEnableLazyLoading(false);
   }
 
+  if (command_line.HasSwitch(switches::kForceNewBrowsingInstance)) {
+    builder.SetForceNewBrowsingInstance(true);
+  }
+
   return true;
 }
 
diff --git a/headless/lib/browser/headless_browser_impl.cc b/headless/lib/browser/headless_browser_impl.cc
index 5809a499..5f77dc7 100644
--- a/headless/lib/browser/headless_browser_impl.cc
+++ b/headless/lib/browser/headless_browser_impl.cc
@@ -155,6 +155,11 @@
   return *this;
 }
 
+Builder& Builder::SetForceNewBrowsingInstance(bool force) {
+  options_.force_new_browsing_instance = force;
+  return *this;
+}
+
 Options Builder::Build() {
   return std::move(options_);
 }
diff --git a/headless/lib/browser/headless_web_contents_impl.cc b/headless/lib/browser/headless_web_contents_impl.cc
index 838b3b23..c5955452 100644
--- a/headless/lib/browser/headless_web_contents_impl.cc
+++ b/headless/lib/browser/headless_web_contents_impl.cc
@@ -177,9 +177,14 @@
         return nullptr;
     }
 
+    content::NavigationController::LoadURLParams load_url_params(params);
+    load_url_params.force_new_browsing_instance =
+        headless_web_contents_->browser()
+            ->options()
+            ->force_new_browsing_instance;
+
     base::WeakPtr<content::NavigationHandle> navigation =
-        target->GetController().LoadURLWithParams(
-            content::NavigationController::LoadURLParams(params));
+        target->GetController().LoadURLWithParams(load_url_params);
     if (navigation_handle_callback && navigation) {
       std::move(navigation_handle_callback).Run(*navigation);
     }
@@ -445,6 +450,9 @@
   content::NavigationController::LoadURLParams params(url);
   params.transition_type = ui::PageTransitionFromInt(
       ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR);
+  params.force_new_browsing_instance =
+      browser()->options()->force_new_browsing_instance;
+
   web_contents_->GetController().LoadURLWithParams(params);
   web_contents_delegate_->ActivateContents(web_contents_.get());
   web_contents_->Focus();
diff --git a/headless/lib/switches.cc b/headless/lib/switches.cc
index 5890ba8..d72d382 100644
--- a/headless/lib/switches.cc
+++ b/headless/lib/switches.cc
@@ -102,6 +102,9 @@
 // affects HTTP and HTTPS requests.
 const char kProxyServer[] = "proxy-server";
 
+// Forces each navigation to use a new BrowsingInstance.
+const char kForceNewBrowsingInstance[] = "force-new-browsing-instance";
+
 // A string used to override the default user agent with a custom one.
 const char kUserAgent[] = "user-agent";
 
diff --git a/headless/public/headless_browser.h b/headless/public/headless_browser.h
index 27ef4c3c..7cdfe49 100644
--- a/headless/public/headless_browser.h
+++ b/headless/public/headless_browser.h
@@ -141,6 +141,9 @@
   // Whether lazy loading of images and frames is enabled.
   bool lazy_load_enabled = true;
 
+  // Forces each navigation to use a new BrowsingInstance.
+  bool force_new_browsing_instance = false;
+
   // Reminder: when adding a new field here, do not forget to add it to
   // HeadlessBrowserContextOptions (where appropriate).
  private:
@@ -179,6 +182,7 @@
   Builder& SetCrashReporterEnabled(bool enabled);
   Builder& SetCrashDumpsDir(const base::FilePath& dir);
   Builder& SetFontRenderHinting(gfx::FontRenderParams::Hinting hinting);
+  Builder& SetForceNewBrowsingInstance(bool force);
   Options Build();
 
  private:
diff --git a/headless/public/switches.h b/headless/public/switches.h
index 4fb7b98..344fa6e9 100644
--- a/headless/public/switches.h
+++ b/headless/public/switches.h
@@ -34,6 +34,7 @@
 HEADLESS_EXPORT extern const char kPasswordStore[];
 HEADLESS_EXPORT extern const char kProxyBypassList[];
 HEADLESS_EXPORT extern const char kProxyServer[];
+HEADLESS_EXPORT extern const char kForceNewBrowsingInstance[];
 HEADLESS_EXPORT extern const char kUserAgent[];
 HEADLESS_EXPORT extern const char kUserDataDir[];
 HEADLESS_EXPORT extern const char kWindowSize[];
diff --git a/infra/config/generated/builders/ci/android-archive-rel/gn-args.json b/infra/config/generated/builders/ci/android-archive-rel/gn-args.json
index fa5eedf4..94a9bf9 100644
--- a/infra/config/generated/builders/ci/android-archive-rel/gn-args.json
+++ b/infra/config/generated/builders/ci/android-archive-rel/gn-args.json
@@ -6,6 +6,7 @@
     "is_debug": false,
     "strip_debug_info": true,
     "symbol_level": 1,
+    "target_cpu": "arm",
     "target_os": "android",
     "use_remoteexec": true,
     "use_siso": true
diff --git a/infra/config/generated/builders/ci/android-official/gn-args.json b/infra/config/generated/builders/ci/android-official/gn-args.json
index d462900..0a21a57 100644
--- a/infra/config/generated/builders/ci/android-official/gn-args.json
+++ b/infra/config/generated/builders/ci/android-official/gn-args.json
@@ -3,6 +3,7 @@
     "debuggable_apks": false,
     "is_official_build": true,
     "symbol_level": 2,
+    "target_cpu": "arm",
     "target_os": "android",
     "use_remoteexec": true,
     "use_siso": true
diff --git a/infra/config/generated/builders/ci/lacros-arm-archive-rel/gn-args.json b/infra/config/generated/builders/ci/lacros-arm-archive-rel/gn-args.json
index 88c7dd7..8ac908b9 100644
--- a/infra/config/generated/builders/ci/lacros-arm-archive-rel/gn-args.json
+++ b/infra/config/generated/builders/ci/lacros-arm-archive-rel/gn-args.json
@@ -6,6 +6,7 @@
     "is_chromeos_device": true,
     "is_debug": false,
     "ozone_platform_headless": true,
+    "target_cpu": "arm",
     "target_os": "chromeos",
     "use_remoteexec": true,
     "use_siso": true
diff --git a/infra/config/generated/builders/ci/lacros-arm64-archive-rel/gn-args.json b/infra/config/generated/builders/ci/lacros-arm64-archive-rel/gn-args.json
index d5a6155..0e42a26 100644
--- a/infra/config/generated/builders/ci/lacros-arm64-archive-rel/gn-args.json
+++ b/infra/config/generated/builders/ci/lacros-arm64-archive-rel/gn-args.json
@@ -6,6 +6,7 @@
     "is_chromeos_device": true,
     "is_debug": false,
     "ozone_platform_headless": true,
+    "target_cpu": "arm64",
     "target_os": "chromeos",
     "use_remoteexec": true,
     "use_siso": true
diff --git a/infra/config/generated/builders/ci/lacros64-archive-rel/gn-args.json b/infra/config/generated/builders/ci/lacros64-archive-rel/gn-args.json
index 0704187..bbcff5d 100644
--- a/infra/config/generated/builders/ci/lacros64-archive-rel/gn-args.json
+++ b/infra/config/generated/builders/ci/lacros64-archive-rel/gn-args.json
@@ -6,6 +6,7 @@
     "is_chromeos_device": true,
     "is_debug": false,
     "ozone_platform_headless": true,
+    "target_cpu": "x64",
     "target_os": "chromeos",
     "use_remoteexec": true,
     "use_siso": true
diff --git a/infra/config/generated/builders/ci/linux-archive-rel/gn-args.json b/infra/config/generated/builders/ci/linux-archive-rel/gn-args.json
index 495f8d3..8e184aa 100644
--- a/infra/config/generated/builders/ci/linux-archive-rel/gn-args.json
+++ b/infra/config/generated/builders/ci/linux-archive-rel/gn-args.json
@@ -4,6 +4,8 @@
     "enable_updater": true,
     "is_component_build": false,
     "is_debug": false,
+    "target_cpu": "x64",
+    "target_os": "linux",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/ci/linux-chromeos-archive-rel/gn-args.json b/infra/config/generated/builders/ci/linux-chromeos-archive-rel/gn-args.json
index 532ce28..f8fe23a 100644
--- a/infra/config/generated/builders/ci/linux-chromeos-archive-rel/gn-args.json
+++ b/infra/config/generated/builders/ci/linux-chromeos-archive-rel/gn-args.json
@@ -3,6 +3,7 @@
     "dcheck_always_on": false,
     "is_component_build": false,
     "is_debug": false,
+    "target_cpu": "x64",
     "target_os": "chromeos",
     "use_cups": true,
     "use_remoteexec": true,
diff --git a/infra/config/generated/builders/ci/linux-lacros-archive-rel/gn-args.json b/infra/config/generated/builders/ci/linux-lacros-archive-rel/gn-args.json
index 2e6ae4a0..e5a71d3 100644
--- a/infra/config/generated/builders/ci/linux-lacros-archive-rel/gn-args.json
+++ b/infra/config/generated/builders/ci/linux-lacros-archive-rel/gn-args.json
@@ -5,6 +5,7 @@
     "dcheck_always_on": false,
     "is_component_build": false,
     "is_debug": false,
+    "target_cpu": "x64",
     "target_os": "chromeos",
     "use_remoteexec": true,
     "use_siso": true
diff --git a/infra/config/generated/builders/ci/linux-official/gn-args.json b/infra/config/generated/builders/ci/linux-official/gn-args.json
index e6c57c0..5f488f8 100644
--- a/infra/config/generated/builders/ci/linux-official/gn-args.json
+++ b/infra/config/generated/builders/ci/linux-official/gn-args.json
@@ -1,6 +1,8 @@
 {
   "gn_args": {
     "is_official_build": true,
+    "target_cpu": "x64",
+    "target_os": "linux",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/ci/mac-archive-rel/gn-args.json b/infra/config/generated/builders/ci/mac-archive-rel/gn-args.json
index f58d737..c25e0f7 100644
--- a/infra/config/generated/builders/ci/mac-archive-rel/gn-args.json
+++ b/infra/config/generated/builders/ci/mac-archive-rel/gn-args.json
@@ -5,6 +5,8 @@
     "is_component_build": false,
     "is_debug": false,
     "symbol_level": 1,
+    "target_cpu": "x64",
+    "target_os": "mac",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/ci/mac-arm64-archive-rel/gn-args.json b/infra/config/generated/builders/ci/mac-arm64-archive-rel/gn-args.json
index b68dab8..f8669cd 100644
--- a/infra/config/generated/builders/ci/mac-arm64-archive-rel/gn-args.json
+++ b/infra/config/generated/builders/ci/mac-arm64-archive-rel/gn-args.json
@@ -6,6 +6,7 @@
     "is_debug": false,
     "symbol_level": 1,
     "target_cpu": "arm64",
+    "target_os": "mac",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/ci/mac-official/gn-args.json b/infra/config/generated/builders/ci/mac-official/gn-args.json
index e6c57c0..6f38c92 100644
--- a/infra/config/generated/builders/ci/mac-official/gn-args.json
+++ b/infra/config/generated/builders/ci/mac-official/gn-args.json
@@ -1,6 +1,8 @@
 {
   "gn_args": {
     "is_official_build": true,
+    "target_cpu": "arm64",
+    "target_os": "mac",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/ci/win-archive-rel/gn-args.json b/infra/config/generated/builders/ci/win-archive-rel/gn-args.json
index 026f4e5..be9de26 100644
--- a/infra/config/generated/builders/ci/win-archive-rel/gn-args.json
+++ b/infra/config/generated/builders/ci/win-archive-rel/gn-args.json
@@ -4,6 +4,8 @@
     "is_component_build": false,
     "is_debug": false,
     "symbol_level": 1,
+    "target_cpu": "x64",
+    "target_os": "win",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/ci/win-arm64-archive-rel/gn-args.json b/infra/config/generated/builders/ci/win-arm64-archive-rel/gn-args.json
index 2c76b8a..0748c87 100644
--- a/infra/config/generated/builders/ci/win-arm64-archive-rel/gn-args.json
+++ b/infra/config/generated/builders/ci/win-arm64-archive-rel/gn-args.json
@@ -5,6 +5,7 @@
     "is_debug": false,
     "symbol_level": 1,
     "target_cpu": "arm64",
+    "target_os": "win",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/ci/win-official/gn-args.json b/infra/config/generated/builders/ci/win-official/gn-args.json
index e9b7238f..c2e0758b 100644
--- a/infra/config/generated/builders/ci/win-official/gn-args.json
+++ b/infra/config/generated/builders/ci/win-official/gn-args.json
@@ -2,6 +2,8 @@
   "gn_args": {
     "is_official_build": true,
     "symbol_level": 1,
+    "target_cpu": "x64",
+    "target_os": "win",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/ci/win32-archive-rel/gn-args.json b/infra/config/generated/builders/ci/win32-archive-rel/gn-args.json
index ec52a98..34e48a2 100644
--- a/infra/config/generated/builders/ci/win32-archive-rel/gn-args.json
+++ b/infra/config/generated/builders/ci/win32-archive-rel/gn-args.json
@@ -5,6 +5,7 @@
     "is_debug": false,
     "symbol_level": 1,
     "target_cpu": "x86",
+    "target_os": "win",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/ci/win32-official/gn-args.json b/infra/config/generated/builders/ci/win32-official/gn-args.json
index 4ac6dc0..ba40a2d 100644
--- a/infra/config/generated/builders/ci/win32-official/gn-args.json
+++ b/infra/config/generated/builders/ci/win32-official/gn-args.json
@@ -2,6 +2,7 @@
   "gn_args": {
     "is_official_build": true,
     "target_cpu": "x86",
+    "target_os": "win",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/try/android-clobber-rel/gn-args.json b/infra/config/generated/builders/try/android-clobber-rel/gn-args.json
index da57487..6d57cc4 100644
--- a/infra/config/generated/builders/try/android-clobber-rel/gn-args.json
+++ b/infra/config/generated/builders/try/android-clobber-rel/gn-args.json
@@ -8,6 +8,7 @@
     "proprietary_codecs": true,
     "strip_debug_info": true,
     "symbol_level": 0,
+    "target_cpu": "arm",
     "target_os": "android",
     "use_remoteexec": true,
     "use_siso": true
diff --git a/infra/config/generated/builders/try/android-official/gn-args.json b/infra/config/generated/builders/try/android-official/gn-args.json
index d462900..0a21a57 100644
--- a/infra/config/generated/builders/try/android-official/gn-args.json
+++ b/infra/config/generated/builders/try/android-official/gn-args.json
@@ -3,6 +3,7 @@
     "debuggable_apks": false,
     "is_official_build": true,
     "symbol_level": 2,
+    "target_cpu": "arm",
     "target_os": "android",
     "use_remoteexec": true,
     "use_siso": true
diff --git a/infra/config/generated/builders/try/branch-config-verifier/properties.json b/infra/config/generated/builders/try/branch-config-verifier/properties.json
index e82ca5d..ecad843 100644
--- a/infra/config/generated/builders/try/branch-config-verifier/properties.json
+++ b/infra/config/generated/builders/try/branch-config-verifier/properties.json
@@ -8,7 +8,6 @@
   },
   "branch_configs": [
     {
-      "gardener_rotation": "chrome_browser_release",
       "initialize": {},
       "name": "standard branch"
     },
diff --git a/infra/config/generated/builders/try/linux-official/gn-args.json b/infra/config/generated/builders/try/linux-official/gn-args.json
index ab9083c..9904d75 100644
--- a/infra/config/generated/builders/try/linux-official/gn-args.json
+++ b/infra/config/generated/builders/try/linux-official/gn-args.json
@@ -3,6 +3,8 @@
     "dcheck_always_on": true,
     "is_official_build": true,
     "symbol_level": 1,
+    "target_cpu": "x64",
+    "target_os": "linux",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/try/mac-arm64-clobber-rel/gn-args.json b/infra/config/generated/builders/try/mac-arm64-clobber-rel/gn-args.json
index b68dab8..f8669cd 100644
--- a/infra/config/generated/builders/try/mac-arm64-clobber-rel/gn-args.json
+++ b/infra/config/generated/builders/try/mac-arm64-clobber-rel/gn-args.json
@@ -6,6 +6,7 @@
     "is_debug": false,
     "symbol_level": 1,
     "target_cpu": "arm64",
+    "target_os": "mac",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/try/mac-clobber-rel/gn-args.json b/infra/config/generated/builders/try/mac-clobber-rel/gn-args.json
index f58d737..c25e0f7 100644
--- a/infra/config/generated/builders/try/mac-clobber-rel/gn-args.json
+++ b/infra/config/generated/builders/try/mac-clobber-rel/gn-args.json
@@ -5,6 +5,8 @@
     "is_component_build": false,
     "is_debug": false,
     "symbol_level": 1,
+    "target_cpu": "x64",
+    "target_os": "mac",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/try/mac-official/gn-args.json b/infra/config/generated/builders/try/mac-official/gn-args.json
index ab9083c..bab93dc 100644
--- a/infra/config/generated/builders/try/mac-official/gn-args.json
+++ b/infra/config/generated/builders/try/mac-official/gn-args.json
@@ -3,6 +3,8 @@
     "dcheck_always_on": true,
     "is_official_build": true,
     "symbol_level": 1,
+    "target_cpu": "arm64",
+    "target_os": "mac",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/try/win-arm64-clobber-rel/gn-args.json b/infra/config/generated/builders/try/win-arm64-clobber-rel/gn-args.json
index 31f2ab14..dcf80b4 100644
--- a/infra/config/generated/builders/try/win-arm64-clobber-rel/gn-args.json
+++ b/infra/config/generated/builders/try/win-arm64-clobber-rel/gn-args.json
@@ -5,6 +5,7 @@
     "is_debug": false,
     "symbol_level": 0,
     "target_cpu": "arm64",
+    "target_os": "win",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/try/win-clobber-rel/gn-args.json b/infra/config/generated/builders/try/win-clobber-rel/gn-args.json
index ea5fe78..7913950 100644
--- a/infra/config/generated/builders/try/win-clobber-rel/gn-args.json
+++ b/infra/config/generated/builders/try/win-clobber-rel/gn-args.json
@@ -4,6 +4,8 @@
     "is_component_build": false,
     "is_debug": false,
     "symbol_level": 0,
+    "target_cpu": "x64",
+    "target_os": "win",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/try/win-official/gn-args.json b/infra/config/generated/builders/try/win-official/gn-args.json
index ab9083c..e8d6714 100644
--- a/infra/config/generated/builders/try/win-official/gn-args.json
+++ b/infra/config/generated/builders/try/win-official/gn-args.json
@@ -3,6 +3,8 @@
     "dcheck_always_on": true,
     "is_official_build": true,
     "symbol_level": 1,
+    "target_cpu": "x64",
+    "target_os": "win",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/try/win32-clobber-rel/gn-args.json b/infra/config/generated/builders/try/win32-clobber-rel/gn-args.json
index 3333edd..115977c 100644
--- a/infra/config/generated/builders/try/win32-clobber-rel/gn-args.json
+++ b/infra/config/generated/builders/try/win32-clobber-rel/gn-args.json
@@ -5,6 +5,7 @@
     "is_debug": false,
     "symbol_level": 0,
     "target_cpu": "x86",
+    "target_os": "win",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/builders/try/win32-official/gn-args.json b/infra/config/generated/builders/try/win32-official/gn-args.json
index 96a5c58..6c11535 100644
--- a/infra/config/generated/builders/try/win32-official/gn-args.json
+++ b/infra/config/generated/builders/try/win32-official/gn-args.json
@@ -4,6 +4,7 @@
     "is_official_build": true,
     "symbol_level": 1,
     "target_cpu": "x86",
+    "target_os": "win",
     "use_remoteexec": true,
     "use_siso": true
   }
diff --git a/infra/config/generated/testing/variants.pyl b/infra/config/generated/testing/variants.pyl
index 58cb665..4aa14c1 100644
--- a/infra/config/generated/testing/variants.pyl
+++ b/infra/config/generated/testing/variants.pyl
@@ -267,16 +267,16 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'identifier': 'Lacros version skew testing ash canary',
-    'description': 'Run with ash-chrome version 128.0.6541.0',
+    'description': 'Run with ash-chrome version 128.0.6542.0',
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6541.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6542.0/test_ash_chrome',
     ],
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v128.0.6541.0',
-          'revision': 'version:128.0.6541.0',
+          'location': 'lacros_version_skew_tests_v128.0.6542.0',
+          'revision': 'version:128.0.6542.0',
         },
       ],
     },
diff --git a/infra/config/subprojects/chromium/ci/chromium.star b/infra/config/subprojects/chromium/ci/chromium.star
index 2a77d58..0df6cb5 100644
--- a/infra/config/subprojects/chromium/ci/chromium.star
+++ b/infra/config/subprojects/chromium/ci/chromium.star
@@ -83,6 +83,7 @@
             "remoteexec",
             "minimal_symbols",
             "strip_debug_info",
+            "arm",
         ],
     ),
     targets = targets.bundle(
@@ -192,6 +193,7 @@
             "remoteexec",
             "android_builder_without_codecs",
             "full_symbols",
+            "arm",
         ],
     ),
     targets = targets.bundle(
@@ -236,6 +238,7 @@
             "release_builder",
             "remoteexec",
             "use_cups",
+            "x64",
         ],
     ),
     targets = targets.bundle(
@@ -315,6 +318,7 @@
             "release_builder",
             "remoteexec",
             "also_build_ash_chrome",
+            "x64",
         ],
     ),
     targets = targets.bundle(
@@ -375,6 +379,7 @@
             "ozone_headless",
             "lacros",
             "release",
+            "x64",
         ],
     ),
     # If tests get added to this builder, it will need to specify os_type chromeos
@@ -434,6 +439,7 @@
             "ozone_headless",
             "lacros",
             "release",
+            "arm",
         ],
     ),
     # If tests get added to this builder, it will need to specify os_type chromeos
@@ -493,6 +499,7 @@
             "ozone_headless",
             "lacros",
             "release",
+            "arm64",
         ],
     ),
     # If tests get added to this builder, it will need to specify os_type chromeos
@@ -545,6 +552,8 @@
             "release_builder",
             "remoteexec",
             "updater",
+            "linux",
+            "x64",
         ],
     ),
     targets = targets.bundle(
@@ -590,7 +599,7 @@
         ),
     ),
     gn_args = gn_args.config(
-        configs = ["official_optimize", "remoteexec"],
+        configs = ["official_optimize", "remoteexec", "linux", "x64"],
     ),
     targets = targets.bundle(
         additional_compile_targets = "all",
@@ -635,6 +644,8 @@
             "remoteexec",
             "mac_strip",
             "minimal_symbols",
+            "mac",
+            "x64",
         ],
     ),
     targets = targets.bundle(
@@ -683,6 +694,7 @@
             "remoteexec",
             "mac_strip",
             "minimal_symbols",
+            "mac",
             "arm64",
         ],
     ),
@@ -734,6 +746,8 @@
         configs = [
             "official_optimize",
             "remoteexec",
+            "mac",
+            "arm64",
         ],
     ),
     targets = targets.bundle(
@@ -774,6 +788,8 @@
             "release_builder",
             "remoteexec",
             "minimal_symbols",
+            "win",
+            "x64",
         ],
     ),
     targets = targets.bundle(
@@ -825,6 +841,7 @@
             "release_builder",
             "remoteexec",
             "minimal_symbols",
+            "win",
             "arm64",
         ],
     ),
@@ -881,6 +898,8 @@
             "official_optimize",
             "remoteexec",
             "minimal_symbols",
+            "win",
+            "x64",
         ],
     ),
     targets = targets.bundle(
@@ -925,6 +944,7 @@
             "remoteexec",
             "x86",
             "minimal_symbols",
+            "win",
         ],
     ),
     targets = targets.bundle(
@@ -975,6 +995,7 @@
         configs = [
             "official_optimize",
             "remoteexec",
+            "win",
             "x86",
         ],
     ),
diff --git a/infra/config/subprojects/chromium/try/presubmit.star b/infra/config/subprojects/chromium/try/presubmit.star
index e06e784..d96880f 100644
--- a/infra/config/subprojects/chromium/try/presubmit.star
+++ b/infra/config/subprojects/chromium/try/presubmit.star
@@ -71,7 +71,6 @@
     return [{
         "name": "standard branch",
         "initialize": {},
-        "gardener_rotation": "chrome_browser_release",
     }, {
         "name": "desktop extended stable branch",
         "platform_set": {
diff --git a/infra/config/targets/autoshard_exceptions.json b/infra/config/targets/autoshard_exceptions.json
index 6f25415..222462a 100644
--- a/infra/config/targets/autoshard_exceptions.json
+++ b/infra/config/targets/autoshard_exceptions.json
@@ -78,18 +78,18 @@
             },
             "webview_instrumentation_test_apk": {
                 "debug": {
-                    "avg_num_builds_per_peak_hour": 99,
-                    "estimated_bot_hour_delta": 18.04,
-                    "prev_avg_pending_time_sec": 41.6,
-                    "prev_p50_pending_time_sec": 4.0,
-                    "prev_p90_pending_time_sec": 158.0,
-                    "prev_percentile_duration_minutes": 16.39,
-                    "prev_shard_count": 29,
-                    "simulated_max_shard_duration": 14.73,
-                    "test_overhead_min": 2.7333333333333334,
+                    "avg_num_builds_per_peak_hour": 107,
+                    "estimated_bot_hour_delta": -18.67,
+                    "prev_avg_pending_time_sec": 36.2,
+                    "prev_p50_pending_time_sec": 2.0,
+                    "prev_p90_pending_time_sec": 140.0,
+                    "prev_percentile_duration_minutes": 13.46,
+                    "prev_shard_count": 33,
+                    "simulated_max_shard_duration": 14.96,
+                    "test_overhead_min": 2.6166666666666667,
                     "try_builder": "android-x86-rel"
                 },
-                "shards": 33
+                "shards": 29
             }
         }
     },
@@ -174,18 +174,18 @@
             },
             "browser_tests_require_lacros": {
                 "debug": {
-                    "avg_num_builds_per_peak_hour": 92,
-                    "estimated_bot_hour_delta": -1.51,
-                    "prev_avg_pending_time_sec": 21.4,
-                    "prev_p50_pending_time_sec": 2.0,
-                    "prev_p90_pending_time_sec": 74.0,
-                    "prev_percentile_duration_minutes": 13.61,
-                    "prev_shard_count": 11,
-                    "simulated_max_shard_duration": 14.87,
-                    "test_overhead_min": 0.9833333333333333,
+                    "avg_num_builds_per_peak_hour": 101,
+                    "estimated_bot_hour_delta": 1.07,
+                    "prev_avg_pending_time_sec": 40.6,
+                    "prev_p50_pending_time_sec": 1.0,
+                    "prev_p90_pending_time_sec": 116.0,
+                    "prev_percentile_duration_minutes": 16.1,
+                    "prev_shard_count": 10,
+                    "simulated_max_shard_duration": 14.69,
+                    "test_overhead_min": 0.6333333333333333,
                     "try_builder": "linux-chromeos-rel"
                 },
-                "shards": 10
+                "shards": 11
             },
             "content_browsertests": {
                 "debug": {
diff --git a/infra/config/targets/lacros-version-skew-variants.json b/infra/config/targets/lacros-version-skew-variants.json
index c89e61a..4b419c2 100644
--- a/infra/config/targets/lacros-version-skew-variants.json
+++ b/infra/config/targets/lacros-version-skew-variants.json
@@ -1,16 +1,16 @@
 {
   "LACROS_VERSION_SKEW_CANARY": {
     "args": [
-      "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6541.0/test_ash_chrome"
+      "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6542.0/test_ash_chrome"
     ],
-    "description": "Run with ash-chrome version 128.0.6541.0",
+    "description": "Run with ash-chrome version 128.0.6542.0",
     "identifier": "Lacros version skew testing ash canary",
     "swarming": {
       "cipd_packages": [
         {
           "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-          "location": "lacros_version_skew_tests_v128.0.6541.0",
-          "revision": "version:128.0.6541.0"
+          "location": "lacros_version_skew_tests_v128.0.6542.0",
+          "revision": "version:128.0.6542.0"
         }
       ]
     }
diff --git a/internal b/internal
index 50e70879..7065ba4 160000
--- a/internal
+++ b/internal
@@ -1 +1 @@
-Subproject commit 50e70879b09d050c0010faf7e0faa9c3546a746f
+Subproject commit 7065ba45b9e097c55423362bda374e691ae55839
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn
index df29fc1..768148e 100644
--- a/ios/chrome/app/BUILD.gn
+++ b/ios/chrome/app/BUILD.gn
@@ -353,6 +353,7 @@
     "//ios/chrome/app/application_delegate:app_state_header",
     "//ios/chrome/app/application_delegate:application_delegate_internal",
     "//ios/chrome/browser/blocking_overlay/ui_bundled",
+    "//ios/chrome/browser/browser_view/ui_bundled",
     "//ios/chrome/browser/browsing_data/model",
     "//ios/chrome/browser/geolocation/model",
     "//ios/chrome/browser/shared/coordinator/scene:observing_scene_agent",
@@ -361,7 +362,6 @@
     "//ios/chrome/browser/shared/public/commands:commands",
     "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/signin/model",
-    "//ios/chrome/browser/ui/browser_view",
     "//ios/chrome/browser/ui/first_run",
     "//ios/chrome/browser/ui/first_run:field_trial",
     "//ios/chrome/browser/ui/first_run:first_run_provider",
diff --git a/ios/chrome/app/application_delegate/app_state_unittest.mm b/ios/chrome/app/application_delegate/app_state_unittest.mm
index 7abbf4b..d5a2742 100644
--- a/ios/chrome/app/application_delegate/app_state_unittest.mm
+++ b/ios/chrome/app/application_delegate/app_state_unittest.mm
@@ -213,7 +213,7 @@
     TestChromeBrowserState::Builder test_cbs_builder;
     test_cbs_builder.AddTestingFactory(
         AuthenticationServiceFactory::GetInstance(),
-        base::BindRepeating(AuthenticationServiceFactory::GetDefaultFactory()));
+        AuthenticationServiceFactory::GetDefaultFactory());
 
     browser_state_manager_ = std::make_unique<TestChromeBrowserStateManager>(
         test_cbs_builder.Build());
diff --git a/ios/chrome/app/first_run_app_state_agent.mm b/ios/chrome/app/first_run_app_state_agent.mm
index 2c6062f..fc6d322 100644
--- a/ios/chrome/app/first_run_app_state_agent.mm
+++ b/ios/chrome/app/first_run_app_state_agent.mm
@@ -10,6 +10,7 @@
 #import "ios/chrome/app/application_delegate/app_state.h"
 #import "ios/chrome/app/application_delegate/app_state_observer.h"
 #import "ios/chrome/app/application_delegate/startup_information.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.h"
 #import "ios/chrome/browser/shared/coordinator/scene/scene_controller.h"
 #import "ios/chrome/browser/shared/coordinator/scene/scene_state.h"
 #import "ios/chrome/browser/shared/coordinator/scene/scene_state_observer.h"
@@ -23,7 +24,6 @@
 #import "ios/chrome/browser/signin/model/account_capabilities_fetcher_ios.h"
 #import "ios/chrome/browser/signin/model/chrome_account_manager_service.h"
 #import "ios/chrome/browser/signin/model/chrome_account_manager_service_factory.h"
-#import "ios/chrome/browser/ui/browser_view/browser_view_controller.h"
 #import "ios/chrome/browser/ui/first_run/first_run_coordinator.h"
 #import "ios/chrome/browser/ui/first_run/first_run_screen_provider.h"
 #import "ios/chrome/browser/ui/first_run/orientation_limiting_navigation_controller.h"
diff --git a/ios/chrome/app/post_restore_app_agent_unittest.mm b/ios/chrome/app/post_restore_app_agent_unittest.mm
index 5d76244..64a8fc0 100644
--- a/ios/chrome/app/post_restore_app_agent_unittest.mm
+++ b/ios/chrome/app/post_restore_app_agent_unittest.mm
@@ -63,7 +63,7 @@
     TestChromeBrowserState::Builder builder;
     builder.AddTestingFactory(
         AuthenticationServiceFactory::GetInstance(),
-        base::BindRepeating(AuthenticationServiceFactory::GetDefaultFactory()));
+        AuthenticationServiceFactory::GetDefaultFactory());
     browser_state_ = builder.Build();
     AuthenticationServiceFactory::CreateAndInitializeForBrowserState(
         browser_state_.get(),
diff --git a/ios/chrome/app/strings/ios_chromium_strings.grd b/ios/chrome/app/strings/ios_chromium_strings.grd
index 5906dff..0d58522b1 100644
--- a/ios/chrome/app/strings/ios_chromium_strings.grd
+++ b/ios/chrome/app/strings/ios_chromium_strings.grd
@@ -889,6 +889,9 @@
       <message name="IDS_IOS_SET_UP_LIST_DEFAULT_BROWSER_TITLE" desc="Title for the Set Up List item that encourages the user to set Chromium as their default browser.">
         Use Chromium by Default
       </message>
+      <message name="IDS_IOS_SET_UP_LIST_DEFAULT_BROWSER_TITLE_IPAD" desc="Title for the Set Up List item that encourages the user to set Chrome as their default browser.">
+        Use Chromium on iPad by Default
+      </message>
       <message name="IDS_IOS_SET_UP_LIST_DESCRIPTION" desc="Description for the Set Up List - a list of tasks the user might want to complete when first using Chromium.">
           Complete these suggested actions below to get the most out of Chromium.
       </message>
diff --git a/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_SET_UP_LIST_DEFAULT_BROWSER_TITLE_IPAD.png.sha1 b/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_SET_UP_LIST_DEFAULT_BROWSER_TITLE_IPAD.png.sha1
new file mode 100644
index 0000000..70893211
--- /dev/null
+++ b/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_SET_UP_LIST_DEFAULT_BROWSER_TITLE_IPAD.png.sha1
@@ -0,0 +1 @@
+2853728247b63af6da565dbba4cd18ae5dcf3f56
\ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_google_chrome_strings.grd b/ios/chrome/app/strings/ios_google_chrome_strings.grd
index cca277e..cd86d8a 100644
--- a/ios/chrome/app/strings/ios_google_chrome_strings.grd
+++ b/ios/chrome/app/strings/ios_google_chrome_strings.grd
@@ -895,6 +895,9 @@
       <message name="IDS_IOS_SET_UP_LIST_DEFAULT_BROWSER_TITLE" desc="Title for the Set Up List item that encourages the user to set Chrome as their default browser.">
         Use Chrome by Default
       </message>
+      <message name="IDS_IOS_SET_UP_LIST_DEFAULT_BROWSER_TITLE_IPAD" desc="Title for the Set Up List item that encourages the user to set Chrome as their default browser.">
+        Use Chrome on iPad by Default
+      </message>
       <message name="IDS_IOS_SET_UP_LIST_DESCRIPTION" desc="Description for the Set Up List - a list of tasks the user might want to complete when first using Chrome.">
           Complete these suggested actions below to get the most out of Chrome.
       </message>
diff --git a/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_SET_UP_LIST_DEFAULT_BROWSER_TITLE_IPAD.png.sha1 b/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_SET_UP_LIST_DEFAULT_BROWSER_TITLE_IPAD.png.sha1
new file mode 100644
index 0000000..68f2b1d5
--- /dev/null
+++ b/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_SET_UP_LIST_DEFAULT_BROWSER_TITLE_IPAD.png.sha1
@@ -0,0 +1 @@
+e1f03530d29cd3983e336e83cb6e08a0d95542fc
\ No newline at end of file
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_bs.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_bs.xtb
index 9db2b1f..7e4e8ef 100644
--- a/ios/chrome/app/strings/resources/ios_chromium_strings_bs.xtb
+++ b/ios/chrome/app/strings/resources/ios_chromium_strings_bs.xtb
@@ -122,6 +122,7 @@
 
 Da promijenite ovu postavku, <ph name="BEGIN_LINK" />izbrišite podatke Chromiuma na računu<ph name="END_LINK" />.</translation>
 <translation id="4576283463017113841">Otvara stranicu s postavkama načina plaćanja u Chromiumu.</translation>
+<translation id="458786853569524949">Sad možete koristiti Chromium svaki put kad dodirnete veze u e-porukama, dokumentima i drugim aplikacijama.</translation>
 <translation id="459080529287102949">Pretraživanje vizuelnih elemenata u Chromiumu</translation>
 <translation id="4633738821577273991">Preuzmite i poboljšano Sigurno pregledanje za ovaj Chromium profil</translation>
 <translation id="4638625642619341392">Ovdje možete preuzeti Chromium.</translation>
@@ -288,6 +289,7 @@
 Vaši podaci su šifrirani pristupnim izrazom <ph name="TIME" /> Unesite ga da koristite i sačuvate podatke Chromiuma na Google računu.</translation>
 <translation id="9022552996538154597">Prijavite se u Chromium</translation>
 <translation id="9050790730841755540">Koristite Chromium svaki put kada dodirnete linkove u drugim aplikacijama.</translation>
+<translation id="9057082013386654559">Koristi Chromium za iPad prema zadanim postavkama</translation>
 <translation id="9059693977935746710">Nećete morati zapamtiti ovu lozinku. Sačuvat će se u Upravitelju lozinki za račun <ph name="EMAIL" /></translation>
 <translation id="9089354809943900324">Chromium nije ažuriran</translation>
 <translation id="9110075932708282655">Koristite Chromium kao zadanu opciju</translation>
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_hr.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_hr.xtb
index 265c23f..92df873d 100644
--- a/ios/chrome/app/strings/resources/ios_chromium_strings_hr.xtb
+++ b/ios/chrome/app/strings/resources/ios_chromium_strings_hr.xtb
@@ -122,6 +122,7 @@
 
 Kako biste promijenili tu postavku, <ph name="BEGIN_LINK" />izbrišite podatke Chromiuma na svom računu<ph name="END_LINK" />.</translation>
 <translation id="4576283463017113841">Otvara stranicu postavki načina plaćanja u Chromiumu.</translation>
+<translation id="458786853569524949">Sad možete koristiti Chromium svaki put kad dodirnete veze u e-porukama, dokumentima i drugim aplikacijama.</translation>
 <translation id="459080529287102949">Pretraživanje slika u Chromiumu</translation>
 <translation id="4633738821577273991">Nabavite poboljšano sigurno pregledavanje i za ovaj profil u Chromiumu</translation>
 <translation id="4638625642619341392">Preuzmite Chromium ovdje.</translation>
@@ -288,6 +289,7 @@
 Vaši su podaci šifrirani vašom šifrom <ph name="TIME" /> Unesite je da biste upotrebljavali i spremali podatke Chromiuma na svojem Google računu.</translation>
 <translation id="9022552996538154597">Prijava na Chromium</translation>
 <translation id="9050790730841755540">Upotrebljavajte Chromium svaki put kad dodirnete veze u drugim aplikacijama.</translation>
+<translation id="9057082013386654559">Koristi Chromium za iPad prema zadanim postavkama</translation>
 <translation id="9059693977935746710">Nećete morati pamtiti tu zaporku. Spremit će se u Upravitelj zaporki za <ph name="EMAIL" /></translation>
 <translation id="9089354809943900324">Chromium je zastario</translation>
 <translation id="9110075932708282655">Koristi Chromium prema zadanim postavkama</translation>
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_hy.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_hy.xtb
index 9fbb7a3..9a1438d 100644
--- a/ios/chrome/app/strings/resources/ios_chromium_strings_hy.xtb
+++ b/ios/chrome/app/strings/resources/ios_chromium_strings_hy.xtb
@@ -264,6 +264,7 @@
 <translation id="8386869251364507178">Գործողություններ Chromium-ում</translation>
 <translation id="8409374867500149834">Chromium-ի ամենահուսալի անվտանգության համակարգը պաշտպանում է ձեզ վնասաբեր կայքերից</translation>
 <translation id="8458950033462118672">Դուք կարող եք Chromium-ը դարձնել ձեր կանխադրված դիտարկիչը և կայքերը բացել այնտեղ ավտոմատ կերպով։</translation>
+<translation id="8543509361021925846">{THRESHOLD,plural, =1{Սա տեղի է ունենում, երբ Chromium-ը {THRESHOLD} րոպե չի օգտագործվում։ Տվյալները, որոնք պահվել են այս սարքում ձեր մուտք գործած ժամանակ, կջնջվեն։ Դա կարող է ներառել պատմությունը և գաղտնաբառերը։}one{Սա տեղի է ունենում, երբ Chromium-ը {THRESHOLD} րոպե չի օգտագործվում։ Տվյալները, որոնք պահվել են այս սարքում ձեր մուտք գործած ժամանակ, կջնջվեն։ Դա կարող է ներառել պատմությունը և գաղտնաբառերը։}other{Սա տեղի է ունենում, երբ Chromium-ը {THRESHOLD} րոպե չի օգտագործվում։ Տվյալները, որոնք պահվել են այս սարքում ձեր մուտք գործած ժամանակ, կջնջվեն։ Դա կարող է ներառել պատմությունը և գաղտնաբառերը։}}</translation>
 <translation id="858114650497379505">Դուք կարող եք Գաղտնաբառերի կառավարիչում պահված գաղտնաբառերն օգտագործել ձեր iPhone-ի այլ հավելվածներում։</translation>
 <translation id="8586442755830160949">© <ph name="YEAR" /> The Chromium Authors: Բոլոր իրավունքները պահպանված են:</translation>
 <translation id="865600487977764604">Ապահովում է ձեր անվտանգությունը Chromium-ում և Google հավելվածներում, երբ դուք գտնվում եք ձեր հաշվում։</translation>
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_mr.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_mr.xtb
index 0060e7c7..ab9fe7a 100644
--- a/ios/chrome/app/strings/resources/ios_chromium_strings_mr.xtb
+++ b/ios/chrome/app/strings/resources/ios_chromium_strings_mr.xtb
@@ -264,6 +264,7 @@
 <translation id="8386869251364507178">Chromium कृती</translation>
 <translation id="8409374867500149834">तुमच्याकडे हानीकारक वेबसाइटच्या विरोधात Chromium ची सर्वात मजबूत सुरक्षा आहे</translation>
 <translation id="8458950033462118672">तुम्ही Chromium ला तुमचे डीफॉल्ट ब्राउझर अ‍ॅप सेट करून त्यामध्ये आपोआप लिंक उघडू शकता.</translation>
+<translation id="8543509361021925846">{THRESHOLD,plural, =1{Chromium {THRESHOLD} मिनिटासाठी वापरले जात नाही, तेव्हा हे होते. तुम्ही साइन इन केले असताना फक्त या डिव्हाइसवर सेव्ह केलेला डेटा हटवला जाईल. यामध्ये इतिहास आणि पासवर्ड यांचा समावेश असू शकतो.}other{Chromium {THRESHOLD} मिनिटांसाठी वापरले जात नाही, तेव्हा हे होते. तुम्ही साइन इन केले असताना फक्त या डिव्हाइसवर सेव्ह केलेला डेटा हटवला जाईल. यामध्ये इतिहास आणि पासवर्ड यांचा समावेश असू शकतो.}}</translation>
 <translation id="858114650497379505">तुम्ही पासवर्ड व्यवस्थापक यामध्ये सेव्ह केलेले पासवर्ड तुमच्या iPhone वरील इतर अ‍ॅप्समध्ये वापरू शकता.</translation>
 <translation id="8586442755830160949">Copyright <ph name="YEAR" /> The Chromium लेखक. सर्व हक्क राखीव.</translation>
 <translation id="865600487977764604">तुम्ही साइन इन केलेले असते, तेव्हा तुम्हाला Chromium वर सुरक्षित ठेवतो आणि इतर Google अ‍ॅप्सवरील तुमच्या सुरक्षेमध्ये सुधारणा करण्यासाठी वापरला जाऊ शकतो.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_ms.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_ms.xtb
index 5fe5876..e0600ac 100644
--- a/ios/chrome/app/strings/resources/ios_chromium_strings_ms.xtb
+++ b/ios/chrome/app/strings/resources/ios_chromium_strings_ms.xtb
@@ -264,6 +264,7 @@
 <translation id="8386869251364507178">Tindakan Chromium</translation>
 <translation id="8409374867500149834">Anda mempunyai keselamatan terkuat Chromium terhadap laman web berbahaya</translation>
 <translation id="8458950033462118672">Anda boleh membuka pautan dalam Chromium secara automatik dengan menjadikan Chromium sebagai Apl Penyemak Imbas Lalai anda.</translation>
+<translation id="8543509361021925846">{THRESHOLD,plural, =1{Perkara ini berlaku apabila Chromium tidak digunakan selama {THRESHOLD} minit. Data yang disimpan hanya pada peranti ini semasa anda log masuk akan dipadamkan. Data ini boleh termasuk sejarah dan kata laluan.}other{Perkara ini berlaku apabila Chromium tidak digunakan selama {THRESHOLD} minit. Data yang disimpan hanya pada peranti ini semasa anda log masuk akan dipadamkan. Data ini boleh termasuk sejarah dan kata laluan.}}</translation>
 <translation id="858114650497379505">Anda boleh menggunakan kata laluan yang anda simpan pada Pengurus Kata Laluan dalam apl lain pada iPhone anda.</translation>
 <translation id="8586442755830160949">Hak Cipta <ph name="YEAR" /> Pengarang Chromium. Hak cipta terpelihara.</translation>
 <translation id="865600487977764604">Memastikan anda selamat pada Chromium dan mungkin digunakan untuk meningkatkan keselamatan anda dalam apl Google yang lain apabila anda log masuk.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_nl.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_nl.xtb
index 22bbe5c5..bc6bcf0 100644
--- a/ios/chrome/app/strings/resources/ios_chromium_strings_nl.xtb
+++ b/ios/chrome/app/strings/resources/ios_chromium_strings_nl.xtb
@@ -264,6 +264,7 @@
 <translation id="8386869251364507178">Chromium-acties</translation>
 <translation id="8409374867500149834">Je hebt de krachtigste beveiliging van Chromium tegen schadelijke websites</translation>
 <translation id="8458950033462118672">Je kunt links automatisch openen in Chromium door Chromium in te stellen als je standaard browser-app.</translation>
+<translation id="8543509361021925846">{THRESHOLD,plural, =1{Dit gebeurt als Chromium {THRESHOLD} minuut niet wordt gebruikt. Gegevens die alleen op dit apparaat zijn opgeslagen terwijl je was ingelogd, worden verwijderd. Dit kunnen onder andere geschiedenis en wachtwoorden zijn.}other{Dit gebeurt als Chromium {THRESHOLD} minuten niet wordt gebruikt. Gegevens die alleen op dit apparaat zijn opgeslagen terwijl je was ingelogd, worden verwijderd. Dit kunnen onder andere geschiedenis en wachtwoorden zijn.}}</translation>
 <translation id="858114650497379505">Je kunt de wachtwoorden die je in Wachtwoordmanager hebt opgeslagen, gebruiken in andere apps op je iPhone.</translation>
 <translation id="8586442755830160949">Copyright <ph name="YEAR" /> De auteurs van Chromium. Alle rechten voorbehouden.</translation>
 <translation id="865600487977764604">Beschermt je op Chromium en kan worden gebruikt om de beveiliging in andere Google-apps te verbeteren als je bent ingelogd.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_si.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_si.xtb
index 8cfc42f4..1b64e38 100644
--- a/ios/chrome/app/strings/resources/ios_chromium_strings_si.xtb
+++ b/ios/chrome/app/strings/resources/ios_chromium_strings_si.xtb
@@ -122,6 +122,7 @@
 
 මෙම සැකසීම වෙනස් කිරීමට <ph name="BEGIN_LINK" />ඔබේ ගිණුම තුළ ඇති Chromium දත්ත මකන්න<ph name="END_LINK" />.</translation>
 <translation id="4576283463017113841">Chromium තුළ ගෙවීම් ක්‍රම සැකසීම් පිටුව විවෘත කරයි.</translation>
+<translation id="458786853569524949">ඔබට දැන් ඉ-තැපැල්, ලේඛන සහ වෙනත් යෙදුම් තුළ ඇති සබැඳි තට්ටු කරන ඕනෑම වේලාවක Chromium භාවිත කළ හැක.</translation>
 <translation id="459080529287102949">Chromium තුළ දෘශ්‍ය සොයන්න</translation>
 <translation id="4633738821577273991">මෙම Chromium පැතිකඩ සඳහා ද ඉහළ නැංවූ සුරක්ෂිත පිරික්සුම ලබා ගන්න</translation>
 <translation id="4638625642619341392">Chromium මෙතැනින් බාගන්න.</translation>
@@ -289,6 +290,7 @@
 <ph name="TIME" /> හි ඔබේ මුර-වැකිකඩ සමග ඔබේ දත්ත සංකේතනය කර ඇත. ඔබේ Google ගිණුමේ Chromium දත්ත භාවිතා කිරීමට සහ සුරැකීමට එය ඇතුළු කරන්න.</translation>
 <translation id="9022552996538154597">Chromium වෙත පිවිසෙන්න</translation>
 <translation id="9050790730841755540">ඔබ වෙනත් යෙදුම්වල සබැඳි තට්ටු කරන ඕනෑම වේලාවක Chromium භාවිතා කරන්න.</translation>
+<translation id="9057082013386654559">පෙරනිමියෙන් iPad සඳහා Chromium භාවිත කරන්න</translation>
 <translation id="9059693977935746710">ඔබට මෙම මුරපදය මතක තබා ගැනීමට අවශ්‍ය නොවනු ඇත. එය <ph name="EMAIL" /> සඳහා මුරපද කළමනාකරු වෙත සුරකිනු ඇත</translation>
 <translation id="9089354809943900324">Chromium යල්පැනගොස් ඇත</translation>
 <translation id="9110075932708282655">පෙරනිමියෙන් Chromium භාවිත කරන්න</translation>
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_sr-Latn.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_sr-Latn.xtb
index 55b1a47..3c2efcb0 100644
--- a/ios/chrome/app/strings/resources/ios_chromium_strings_sr-Latn.xtb
+++ b/ios/chrome/app/strings/resources/ios_chromium_strings_sr-Latn.xtb
@@ -122,6 +122,7 @@
 
 Da biste promenili ovo podešavanje, <ph name="BEGIN_LINK" />izbrišite Chromium podatke na nalogu<ph name="END_LINK" />.</translation>
 <translation id="4576283463017113841">Otvara stranicu Podešavanje načina plaćanja u Chromium-u.</translation>
+<translation id="458786853569524949">Sada možete da koristite Chromium svaki put kada dodirnete linkove u imejlovima, dokumentima i drugim aplikacijama.</translation>
 <translation id="459080529287102949">Pretražite vizuelni materijal u Chromium-u</translation>
 <translation id="4633738821577273991">Nabavite poboljšano bezbedno pregledanje i za ovaj Chromium profil</translation>
 <translation id="4638625642619341392">Preuzmite Chromium ovde.</translation>
@@ -288,6 +289,7 @@
 Podaci su šifrovani pomoću pristupne fraze <ph name="TIME" />. Unesite je da biste koristili i sačuvali Chromium podatke na Google nalogu.</translation>
 <translation id="9022552996538154597">Prijavljivanje na Chromium</translation>
 <translation id="9050790730841755540">Koristite Chromium svaki put kada dodirujete linkove u drugim aplikacijama.</translation>
+<translation id="9057082013386654559">Podrazumevano koristite Chromium za iPad</translation>
 <translation id="9059693977935746710">Ne morate da zapamtite ovu lozinku. Čuva se u Menadžeru lozinki za <ph name="EMAIL" /></translation>
 <translation id="9089354809943900324">Chromium je zastareo</translation>
 <translation id="9110075932708282655">Podrazumevano koristite Chromium</translation>
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_sr.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_sr.xtb
index dd7507e4..77d560b 100644
--- a/ios/chrome/app/strings/resources/ios_chromium_strings_sr.xtb
+++ b/ios/chrome/app/strings/resources/ios_chromium_strings_sr.xtb
@@ -122,6 +122,7 @@
 
 Да бисте променили ово подешавање, <ph name="BEGIN_LINK" />избришите Chromium податке на налогу<ph name="END_LINK" />.</translation>
 <translation id="4576283463017113841">Отвара страницу Подешавање начина плаћања у Chromium-у.</translation>
+<translation id="458786853569524949">Сада можете да користите Chromium сваки пут када додирнете линкове у имејловима, документима и другим апликацијама.</translation>
 <translation id="459080529287102949">Претражите визуелни материјал у Chromium-у</translation>
 <translation id="4633738821577273991">Набавите побољшано безбедно прегледање и за овај Chromium профил</translation>
 <translation id="4638625642619341392">Преузмите Chromium овде.</translation>
@@ -288,6 +289,7 @@
 Подаци су шифровани помоћу приступне фразе <ph name="TIME" />. Унесите је да бисте користили и сачували Chromium податке на Google налогу.</translation>
 <translation id="9022552996538154597">Пријављивање на Chromium</translation>
 <translation id="9050790730841755540">Користите Chromium сваки пут када додирујете линкове у другим апликацијама.</translation>
+<translation id="9057082013386654559">Подразумевано користите Chromium за iPad</translation>
 <translation id="9059693977935746710">Не морате да запамтите ову лозинку. Чува се у Менаџеру лозинки за <ph name="EMAIL" /></translation>
 <translation id="9089354809943900324">Chromium је застарео</translation>
 <translation id="9110075932708282655">Подразумевано користите Chromium</translation>
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_uz.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_uz.xtb
index ad9d440..3f489e1 100644
--- a/ios/chrome/app/strings/resources/ios_chromium_strings_uz.xtb
+++ b/ios/chrome/app/strings/resources/ios_chromium_strings_uz.xtb
@@ -262,6 +262,7 @@
 <translation id="8386869251364507178">Chromium amallari</translation>
 <translation id="8409374867500149834">Sizdagi Chromium zararli saytlarga qarshi eng kuchli himoya tizimiga ega</translation>
 <translation id="8458950033462118672">Saytlar Chromium brauzerida avtomatik ochilishi uchun uni birlamchi brauzer etib tayinlash kifoya.</translation>
+<translation id="8543509361021925846">{THRESHOLD,plural, =1{Chromium {THRESHOLD} daqiqa ishlatilmasa, mazkur amal bajariladi. Hisobga kirilganda faqat shu qurilmada saqlangan maʼlumotlar oʻchirib tashlanadi. Bunga tarix va parollar kirishi mumkin.}other{Chromium {THRESHOLD} daqiqa ishlatilmasa, mazkur amal bajariladi. Hisobga kirilganda faqat shu qurilmada saqlangan maʼlumotlar oʻchirib tashlanadi. Bunga tarix va parollar kirishi mumkin.}}</translation>
 <translation id="858114650497379505">Parollar menejeriga saqlangan parollarni iPhonedagi boshqa ilovalarda ishlatish mumkin.</translation>
 <translation id="8586442755830160949">© The Chromium Authors, <ph name="YEAR" />. Barcha huquqlar himoyalangan.</translation>
 <translation id="865600487977764604">Hisobingizga kirganingizda Chromium va boshqa Google ilovalaridan xavfsiz foydalanishingizni taʼminlaydi.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_bs.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_bs.xtb
index cf506a1..3f56841 100644
--- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_bs.xtb
+++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_bs.xtb
@@ -14,6 +14,7 @@
 <translation id="1320619893013575407">Isključili ste prijavu u Chrome.</translation>
 <translation id="1333745675627230582">Igrajte igru Dinosaur na Chromeu</translation>
 <translation id="1352919863522755794">Google upravitelj lozinki nije uspio provjeriti vaše lozinke. Predlažemo da provjerite internetsku vezu.</translation>
+<translation id="139623527619433858">Koristi Chrome za iPad prema zadanim postavkama</translation>
 <translation id="1407843355326180937">Prijavite se na ovu web lokaciju i u Chrome da dobijete svoje oznake i još mnogo toga na svim svojim uređajima.</translation>
 <translation id="1436059927646026729">Otvori moju posljednju karticu u Chromeu</translation>
 <translation id="1449241544691504574">Dodavanje oznaka u Chrome</translation>
@@ -220,6 +221,7 @@
 <translation id="7272930098487145294">Da sačuvate slike, dodirnite Postavke da omogućite Chromeu dodavanje u vaše fotografije</translation>
 <translation id="7275945473750112644">Računom upravlja <ph name="HOSTED_DOMAIN" />, stoga će se vaši podaci Chromea obrisati s ovog uređaja</translation>
 <translation id="7284245284340063465">Ako ste zaboravili pristupni izraz ili želite promijeniti ovu postavku, <ph name="BEGIN_LINK" />izbrišite podatke Chromea na računu<ph name="END_LINK" />.</translation>
+<translation id="7299681342915173313">Sad možete koristiti Chrome svaki put kad dodirnete veze u e-porukama, dokumentima i drugim aplikacijama.</translation>
 <translation id="7304491752269485262">Prošireni prikaz automatskog popunjavanja u Chromeu</translation>
 <translation id="7344094882820374540">Dobijte Chromeovu najjaču zaštitu od opasnih web lokacija</translation>
 <translation id="7349129508108954623">Dozvolite Chromeu da koristi Google Mape da vam dâ upute i lokalne informacije o otkrivenim adresama.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_hr.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_hr.xtb
index e1046d8a..cfbf244c 100644
--- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_hr.xtb
+++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_hr.xtb
@@ -14,6 +14,7 @@
 <translation id="1320619893013575407">Isključili ste prijavu u Chrome.</translation>
 <translation id="1333745675627230582">Igraj igru Dinosaur na Chromeu</translation>
 <translation id="1352919863522755794">Google upravitelj zaporki nije uspio provjeriti vaše zaporke. Provjerite internetsku vezu.</translation>
+<translation id="139623527619433858">Koristi Chrome za iPad prema zadanim postavkama</translation>
 <translation id="1407843355326180937">Prijavite se na ovu web-lokaciju i Chrome kako biste imali pristup svojim oznakama i još toga na svim svojim uređajima.</translation>
 <translation id="1436059927646026729">Otvaranje moje najnovije kartice u Chromeu</translation>
 <translation id="1449241544691504574">Dodavanje oznaka u Chrome</translation>
@@ -220,6 +221,7 @@
 <translation id="7272930098487145294">Da bi se slike spremale, dodirnite Postavke kako biste dopustili Chromeu da dodaje vašim fotografijama</translation>
 <translation id="7275945473750112644">Vašim računom upravlja <ph name="HOSTED_DOMAIN" />, pa će se vaši podaci iz Chromea izbrisati s ovog uređaja</translation>
 <translation id="7284245284340063465">Ako ste zaboravili šifru ili želite promijeniti tu postavku, <ph name="BEGIN_LINK" />izbrišite Chromeove podatke na računu<ph name="END_LINK" />.</translation>
+<translation id="7299681342915173313">Sad možete koristiti Chrome svaki put kad dodirnete veze u e-porukama, dokumentima i drugim aplikacijama.</translation>
 <translation id="7304491752269485262">Prošireni prikaz automatskog popunjavanja u Chromeu</translation>
 <translation id="7344094882820374540">Odaberite najsnažniju Chromeovu zaštitu od opasnih web-lokacija</translation>
 <translation id="7349129508108954623">Dopustite Chromeu da upotrebljava Google karte kako bi vam pružao upute i lokalne informacije o otkrivenim adresama.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_hy.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_hy.xtb
index 620aaa1..9858379d 100644
--- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_hy.xtb
+++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_hy.xtb
@@ -192,6 +192,7 @@
 <translation id="6646696210740573446">Ուղարկում է URL-ի քողարկված մասը Google-ին գաղտնիության սերվերի միջոցով, որը թաքցնում է ձեր IP հասցեն։ Եթե կայքը փորձում է գողանալ ձեր գաղտնաբառը, կամ երբ վնասակար ֆայլ եք ներբեռնում, Chrome-ը կարող է նաև ուղարկել URL-ն ու էջի բովանդակությունը Google-ին։</translation>
 <translation id="6648150602980899529">Դուք մուտք եք գործում <ph name="DOMAIN" /> տիրույթի կողմից կառավարվող հաշիվ` դրա ադմինիստրատորին թույլ տալով վերահսկել ձեր Chrome-ի տվյալները: Ձեր տվյալները մշտապես կկապվեն այս հաշվի հետ: Եթե դուրս գաք Chrome-ից, այս սարքում պահված տվյալները կջնջվեն, սակայն կպահպանվեն ձեր Google հաշվում:</translation>
 <translation id="6683891932310469419">Բացում է Chrome-ի պատմության էջը։</translation>
+<translation id="6695698548122852044">{THRESHOLD,plural, =1{Սա տեղի է ունենում, երբ Chrome-ը {THRESHOLD} րոպե չի օգտագործվում։ Տվյալները, որոնք պահվել են այս սարքում ձեր մուտք գործած ժամանակ, կջնջվեն։ Դա կարող է ներառել պատմությունը և գաղտնաբառերը։}one{Սա տեղի է ունենում, երբ Chrome-ը {THRESHOLD} րոպե չի օգտագործվում։ Տվյալները, որոնք պահվել են այս սարքում ձեր մուտք գործած ժամանակ, կջնջվեն։ Դա կարող է ներառել պատմությունը և գաղտնաբառերը։}other{Սա տեղի է ունենում, երբ Chrome-ը {THRESHOLD} րոպե չի օգտագործվում։ Տվյալները, որոնք պահվել են այս սարքում ձեր մուտք գործած ժամանակ, կջնջվեն։ Դա կարող է ներառել պատմությունը և գաղտնաբառերը։}}</translation>
 <translation id="6709398533399187136">Տվյալների արտահոսքի արդյունքում ձեր գաղտնաբառը հայտնի է դարձել կողմնակի անձանց։ Google Գաղտնաբառերի կառավարիչը խորհուրդ է տալիս անհապաղ փոխել այն։</translation>
 <translation id="6820553595690137150">Անցաբառով գաղտնագրումը չի կիրառվում վճարման եղանակների և հասցեների համար։
 
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_mr.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_mr.xtb
index b7511e52..729d677 100644
--- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_mr.xtb
+++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_mr.xtb
@@ -192,6 +192,7 @@
 <translation id="6646696210740573446">तुमचा आयपी अ‍ॅड्रेस लपवणार्‍या गोपनीयता सर्व्हरद्वारे URL चा क्लिष्ट भाग Google ला पाठवते. साइटने तुमचा पासवर्ड चोरण्याचा प्रयत्न केल्यास किंवा तुम्ही हानिकारक फाइल डाउनलोड केल्यास, Chrome कदाचित पेज आशयाच्या भागांसह URLs देखील Google ला पाठवेल.</translation>
 <translation id="6648150602980899529"><ph name="DOMAIN" /> द्वारे व्यवस्थापित केलेल्या खात्यासह तुम्ही साइन इन करत आहात आणि त्याच्या ॲडमिनिस्ट्रेटरला तुमच्या Chrome डेटाचे नियंत्रण देत आहात. तुमचा डेटा कायमचा या खात्यामध्ये असेल. Chrome मधून साइन आउट केल्याने तुमचा डेटा या डिव्हाइस वरून हटवला जाईल परंतु तो तुमच्या Google खात्यामध्ये स्टोअर केलेला असेल.</translation>
 <translation id="6683891932310469419">तुमचे Chrome इतिहास पेज उघडते.</translation>
+<translation id="6695698548122852044">{THRESHOLD,plural, =1{Chrome {THRESHOLD} मिनिटासाठी वापरले जात नाही, तेव्हा हे होते. तुम्ही साइन इन केले असताना फक्त या डिव्हाइसवर सेव्ह केलेला डेटा हटवला जाईल. यामध्ये इतिहास आणि पासवर्ड यांचा समावेश असू शकतो.}other{Chrome {THRESHOLD} मिनिटांसाठी वापरले जात नाही, तेव्हा हे होते. तुम्ही साइन इन केले असताना फक्त या डिव्हाइसवर सेव्ह केलेला डेटा हटवला जाईल. यामध्ये इतिहास आणि पासवर्ड यांचा समावेश असू शकतो.}}</translation>
 <translation id="6709398533399187136">तुमचा पासवर्ड डेटा भंगामध्ये उघड झाला होता. Google पासवर्ड व्यवस्थापक तो आता बदलण्याची शिफारस करतो.</translation>
 <translation id="6820553595690137150">पासफ्रेझ एन्क्रिप्शनमध्ये पेमेंट पद्धती आणि पत्ते समाविष्ट नसतात.
 
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_ms.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_ms.xtb
index 2200e74..58ddfca 100644
--- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_ms.xtb
+++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_ms.xtb
@@ -192,6 +192,7 @@
 <translation id="6646696210740573446">Menghantar bahagian pengeliruan URL kepada Google melalui pelayan privasi yang menyembunyikan alamat IP anda. Jika laman cuba mencuri kata laluan anda atau apabila anda memuat turun fail yang berbahaya, Chrome juga mungkin menghantar URL, termasuk sedikit kandungan halaman, kepada Google.</translation>
 <translation id="6648150602980899529">Anda log masuk dengan akaun yang diurus oleh <ph name="DOMAIN" /> dan memberi kawalan terhadap data Chrome anda kepada  pentadbirnya. Data anda akan terikat secara kekal kepada akaun ini. Tindakan log keluar daripada Chrome akan memadamkan data anda daripada peranti ini, tetapi data itu akan kekal disimpan dalam Google Account anda.</translation>
 <translation id="6683891932310469419">Buka Halaman Sejarah Chrome anda.</translation>
+<translation id="6695698548122852044">{THRESHOLD,plural, =1{Perkara ini berlaku apabila Chrome tidak digunakan selama {THRESHOLD} minit. Data yang disimpan hanya pada peranti ini semasa anda log masuk akan dipadamkan. Data ini boleh termasuk sejarah dan kata laluan.}other{Perkara ini berlaku apabila Chrome tidak digunakan selama {THRESHOLD} minit. Data yang disimpan hanya pada peranti ini semasa anda log masuk akan dipadamkan. Data ini boleh termasuk sejarah dan kata laluan.}}</translation>
 <translation id="6709398533399187136">Kata laluan anda terdedah dalam suatu pelanggaran data. Pengurus Kata Laluan Google mengesyorkan agar anda menukarnya sekarang.</translation>
 <translation id="6820553595690137150">Penyulitan ungkapan laluan tidak termasuk kaedah pembayaran dan alamat.
 
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_nl.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_nl.xtb
index 4ea0b38..3f5e978 100644
--- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_nl.xtb
+++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_nl.xtb
@@ -192,6 +192,7 @@
 <translation id="6646696210740573446">Stuurt een geobfusceerd gedeelte van de URL naar Google via een privacyserver die je IP-adres verbergt. Als een site je wachtwoord probeert te stelen of als je een schadelijk bestand downloadt, kan Chrome ook URL's, inclusief delen van de paginacontent, naar Google sturen.</translation>
 <translation id="6648150602980899529">Je logt in met een account dat wordt beheerd door <ph name="DOMAIN" />, waarmee je de eigenaar beheer geeft over je Chrome-gegevens. Je gegevens worden permanent gekoppeld aan dit account. Als je uitlogt van Chrome, worden je gegevens van dit apparaat verwijderd. Ze blijven echter opgeslagen in je Google-account.</translation>
 <translation id="6683891932310469419">Opent de pagina met je Chrome-geschiedenis.</translation>
+<translation id="6695698548122852044">{THRESHOLD,plural, =1{Dit gebeurt als Chrome {THRESHOLD} minuut niet wordt gebruikt. Gegevens die alleen op dit apparaat zijn opgeslagen terwijl je was ingelogd, worden verwijderd. Dit kunnen onder andere geschiedenis en wachtwoorden zijn.}other{Dit gebeurt als Chrome {THRESHOLD} minuten niet wordt gebruikt. Gegevens die alleen op dit apparaat zijn opgeslagen terwijl je was ingelogd, worden verwijderd. Dit kunnen onder andere geschiedenis en wachtwoorden zijn.}}</translation>
 <translation id="6709398533399187136">Je wachtwoord is gelekt bij een gegevenslek. Google Wachtwoordmanager raadt je aan dit wachtwoord nu te wijzigen.</translation>
 <translation id="6820553595690137150">Versleuteling van wachtwoordzinnen omvat geen betaalmethoden en adressen.
 
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_si.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_si.xtb
index f1176aa..eac1dd69 100644
--- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_si.xtb
+++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_si.xtb
@@ -14,6 +14,7 @@
 <translation id="1320619893013575407">ඔබ Chrome පුරනය වීම ක්‍රියාවිරහිත කළා.</translation>
 <translation id="1333745675627230582">Chrome Dino ක්‍රීඩාව කරන්න</translation>
 <translation id="1352919863522755794">Google මුරපද කළමනාකරු හට ඔබේ මුරපද පරීක්ෂා කිරීමට නොහැකි විය. ඔබේ අන්තර්ජාල සම්බන්ධතාව පරීක්ෂා කිරීමට උත්සාහ කරන්න.</translation>
+<translation id="139623527619433858">පෙරනිමියෙන් iPad සඳහා Chrome භාවිත කරන්න</translation>
 <translation id="1407843355326180937">ඔබේ සියලුම උපාංග මත ඔබේ පිටුසන් සහ තවත් ඒවා ලබා ගැනීමට මෙම අඩවියට සහ Chrome වෙත පුරන්න.</translation>
 <translation id="1436059927646026729">Chrome තුළ මගේ නවතම පටිත්ත විවෘත කරන්න</translation>
 <translation id="1449241544691504574">Chrome වෙත පිටුසන් එක් කරන්න</translation>
@@ -221,6 +222,7 @@
 <translation id="7272930098487145294">රූප සුරැකීමට, Chrome හට ඔබේ ඡායාරූප එක් කිරීමට ඉඩ දීමට සැකසීම් මත තට්ටු කරන්න</translation>
 <translation id="7275945473750112644">ඔබගේ ගිණුම <ph name="HOSTED_DOMAIN" /> මගින් කළමනාකරණය කරන නිසා, ඔබගේ Chrome දත්ත මෙම උපාංගයෙන් හිස් කරනු ඇත</translation>
 <translation id="7284245284340063465">ඔබට ඔබේ මුර වැකිකඩ අමතක වුවහොත් හෝ මෙම සැකසීම වෙනස් කිරීමට අවශ්‍ය නම්, <ph name="BEGIN_LINK" />ඔබේ ගිණුමේ ඇති Chrome දත්ත මකන්න<ph name="END_LINK" />.</translation>
+<translation id="7299681342915173313">ඔබට දැන් ඉ-තැපැල්, ලේඛන සහ වෙනත් යෙදුම් තුළ ඇති සබැඳි තට්ටු කරන ඕනෑම වේලාවක Chrome භාවිත කළ හැක.</translation>
 <translation id="7304491752269485262">Chrome ස්වයං පිරවුම් පුළුල් කළ දසුන</translation>
 <translation id="7344094882820374540">භයානක අඩවි වලින් Chrome හි ශක්තිමත්ම ආරක්ෂාව ලබා ගන්න</translation>
 <translation id="7349129508108954623">හඳුනාගත් ලිපින මත ඔබට උපදෙස් සහ දේශීය තතු ලබා දීමට Google සිතියම් භාවිත කිරීමට Chrome හට ඉඩ දෙන්න.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_sr-Latn.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_sr-Latn.xtb
index 16cdd5a3..b4de4fe 100644
--- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_sr-Latn.xtb
+++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_sr-Latn.xtb
@@ -14,6 +14,7 @@
 <translation id="1320619893013575407">Isključili ste prijavljivanje u Chrome.</translation>
 <translation id="1333745675627230582">Igrajte igru Chrome dinosaurus</translation>
 <translation id="1352919863522755794">Google menadžer lozinki nije uspeo da vam proveri lozinke. Proverite internet vezu.</translation>
+<translation id="139623527619433858">Podrazumevano koristite Chrome za iPad</translation>
 <translation id="1407843355326180937">Prijavite se na ovaj sajt i u Chrome da bi vam obeleživači i drugi sadržaj bili dostupni na svim uređajima.</translation>
 <translation id="1436059927646026729">Otvori moju najnoviju karticu u Chrome-u</translation>
 <translation id="1449241544691504574">Dodaj obeleživače u Chrome</translation>
@@ -220,6 +221,7 @@
 <translation id="7272930098487145294">Da biste sačuvali slike, dodirnite Podešavanja da biste omogućili Chrome-u da dodaje slike</translation>
 <translation id="7275945473750112644">Nalogom upravlja <ph name="HOSTED_DOMAIN" />, pa će se Chrome podaci obrisati sa ovog uređaja</translation>
 <translation id="7284245284340063465">Ako ste zaboravili pristupnu frazu ili želite da promenite ovo podešavanje, <ph name="BEGIN_LINK" />izbrišite Chrome podatke na nalogu<ph name="END_LINK" />.</translation>
+<translation id="7299681342915173313">Sada možete da koristite Chrome svaki put kada dodirnete linkove u imejlovima, dokumentima i drugim aplikacijama.</translation>
 <translation id="7304491752269485262">Prošireni prikaz Chrome automatskog popunjavanja</translation>
 <translation id="7344094882820374540">Nabavite najjaču Chrome zaštitu od opasnih sajtova</translation>
 <translation id="7349129508108954623">Dozvolite Chrome-u da koristi Google mape da bi vam pružao uputstva i lokalne informacije o otkrivenim adresama.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_sr.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_sr.xtb
index 5eae8175..f271c46 100644
--- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_sr.xtb
+++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_sr.xtb
@@ -14,6 +14,7 @@
 <translation id="1320619893013575407">Искључили сте пријављивање у Chrome.</translation>
 <translation id="1333745675627230582">Играјте игру Chrome диносаурус</translation>
 <translation id="1352919863522755794">Google менаџер лозинки није успео да вам провери лозинке. Проверите интернет везу.</translation>
+<translation id="139623527619433858">Подразумевано користите Chrome за iPad</translation>
 <translation id="1407843355326180937">Пријавите се на овај сајт и у Chrome да би вам обележивачи и други садржај били доступни на свим уређајима.</translation>
 <translation id="1436059927646026729">Отвори моју најновију картицу у Chrome-у</translation>
 <translation id="1449241544691504574">Додај обележиваче у Chrome</translation>
@@ -220,6 +221,7 @@
 <translation id="7272930098487145294">Да бисте сачували слике, додирните Подешавања да бисте омогућили Chrome-у да додаје слике</translation>
 <translation id="7275945473750112644">Налогом управља <ph name="HOSTED_DOMAIN" />, па ће се Chrome подаци обрисати са овог уређаја</translation>
 <translation id="7284245284340063465">Ако сте заборавили приступну фразу или желите да промените ово подешавање, <ph name="BEGIN_LINK" />избришите Chrome податке на налогу<ph name="END_LINK" />.</translation>
+<translation id="7299681342915173313">Сада можете да користите Chrome сваки пут када додирнете линкове у имејловима, документима и другим апликацијама.</translation>
 <translation id="7304491752269485262">Проширени приказ Chrome аутоматског попуњавања</translation>
 <translation id="7344094882820374540">Набавите најјачу Chrome заштиту од опасних сајтова</translation>
 <translation id="7349129508108954623">Дозволите Chrome-у да користи Google мапе да би вам пружао упутства и локалне информације о откривеним адресама.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_uz.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_uz.xtb
index ea6164e..424cc85 100644
--- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_uz.xtb
+++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_uz.xtb
@@ -192,6 +192,7 @@
 <translation id="6646696210740573446">Himoyalangan URL parchasini IP manzilni yashiruvchi maxfiy server orqali Googlega yuboradi. Agar sayt parolingizni oʻgʻirlashga urinsa yoki zararli fayl yuklab olsangiz, Chrome URL manzillar va sahifa elementlarini ham Googlega yuborishi mumkin.</translation>
 <translation id="6648150602980899529"><ph name="DOMAIN" /> domenida boshqariladigan hisobga kirish bilan siz administratorga Chrome ma’lumotlaringizni boshqarishiga rozilik bildirasiz. Barcha Chrome ma’lumotlaringiz bu hisobga butunlay bog‘langan. Agar hisobdan chiqadigan bo‘lsangiz, bu qurilmadagi barcha ma’lumotlaringiz o‘chib ketadi, lekin Google hisobingizda saqlanib qoladi.</translation>
 <translation id="6683891932310469419">Chrome tarixi sahifasini ochadi</translation>
+<translation id="6695698548122852044">{THRESHOLD,plural, =1{Chrome {THRESHOLD} daqiqa ishlatilmasa, mazkur amal bajariladi. Hisobga kirilganda faqat shu qurilmada saqlangan maʼlumotlar oʻchirib tashlanadi. Bunga tarix va parollar kirishi mumkin.}other{Chrome {THRESHOLD} daqiqa ishlatilmasa, mazkur amal bajariladi. Hisobga kirilganda faqat shu qurilmada saqlangan maʼlumotlar oʻchirib tashlanadi. Bunga tarix va parollar kirishi mumkin.}}</translation>
 <translation id="6709398533399187136">Parolingiz oshkor qilingan. Google Parollar menejeri uni hoziroq almashtirishni tavsiya etadi.</translation>
 <translation id="6820553595690137150">Kodli ibora bilan shifrlash ichiga toʻlov usullari va manzillar kirmaydi.
 
diff --git a/ios/chrome/app/strings/resources/ios_strings_bs.xtb b/ios/chrome/app/strings/resources/ios_strings_bs.xtb
index 5f58865..f787b4a 100644
--- a/ios/chrome/app/strings/resources/ios_strings_bs.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_bs.xtb
@@ -783,6 +783,7 @@
 <translation id="4971735654804503942">Brža, proaktivna zaštita od opasnih web lokacija, preuzimanja i ekstenzija. Upozorava vas na narušavanje lozinki. Zahtijeva da se podaci o pregledanju šalju Googleu.</translation>
 <translation id="4979397965658815378">Prijavite se na svoj Google račun da dobijete oznake, lozinke, historiju i ostale postavke na svim svojim uređajima.</translation>
 <translation id="4989065233040279145">Odaberite gdje želite sačuvati fajl <ph name="FILENAME" /></translation>
+<translation id="4992255726304765516">Boja grupe kartica <ph name="COLOR" /></translation>
 <translation id="5005498671520578047">Kopiranje lozinke</translation>
 <translation id="5016420433031926653">Pošaljite primaocu <ph name="USER_EMAIL" /></translation>
 <translation id="5017828934289857214">Podsjeti me kasnije</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb b/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb
index 3a1dbee..f0c806d 100644
--- a/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_en-GB.xtb
@@ -1407,7 +1407,7 @@
 <translation id="8027581147000338959">Open in new window</translation>
 <translation id="8032569120109842252">Following</translation>
 <translation id="8040207962129315716">Ask me every time</translation>
-<translation id="8041089156583427627">Send Feedback</translation>
+<translation id="8041089156583427627">Send feedback</translation>
 <translation id="804225253087497565"><ph name="BEGIN_LINK" />Search history<ph name="END_LINK" /> and <ph name="BEGIN_LINK" />other forms of activity<ph name="END_LINK" /> may be saved in your Google Account when you’re signed in. You can delete them at any time.</translation>
 <translation id="804427445359061970">You'll find your tabs from other devices here</translation>
 <translation id="8044568254381073661">Save Without Encryption</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_hr.xtb b/ios/chrome/app/strings/resources/ios_strings_hr.xtb
index 2f1a7b9..e94d065 100644
--- a/ios/chrome/app/strings/resources/ios_strings_hr.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_hr.xtb
@@ -783,6 +783,7 @@
 <translation id="4971735654804503942">Brža, proaktivna zaštita od opasnih web-lokacija, preuzimanja i proširenja. Upozorava vas na povrede zaporki. Traži slanje podataka o pregledavanju Googleu.</translation>
 <translation id="4979397965658815378">Prijavite se Google računom da biste imali pristup svojim oznakama, zaporkama, povijesti i ostalim postavkama na svim svojim uređajima</translation>
 <translation id="4989065233040279145">Odaberite mjesto spremanja datoteke <ph name="FILENAME" /></translation>
+<translation id="4992255726304765516">Boja grupe kartica <ph name="COLOR" /></translation>
 <translation id="5005498671520578047">Kopiranje zaporke</translation>
 <translation id="5016420433031926653">Šalju se na <ph name="USER_EMAIL" /></translation>
 <translation id="5017828934289857214">Podsjeti me kasnije</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_hy.xtb b/ios/chrome/app/strings/resources/ios_strings_hy.xtb
index 27a94a1..e1213812 100644
--- a/ios/chrome/app/strings/resources/ios_strings_hy.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_hy.xtb
@@ -532,6 +532,7 @@
 <translation id="371398631992790800">Թաքցնել «Էջանիշներ» կետը</translation>
 <translation id="37207012422556617">Թրենդային որոնումներ</translation>
 <translation id="3725081662140949903">Որպեսզի թույլ չտաք որևէ մեկին օգտագործել ձեր գաղտնաբառը, բացեք <ph name="APP" /> հավելվածը և փոխեք գաղտնաբառը</translation>
+<translation id="372676576864368480">Ինքնալրացնել քարտի համարը, որի վերջին թվերն են <ph name="LAST_DIGITS" /></translation>
 <translation id="3738428049780661523">Ստեղծվել է <ph name="DATE" /></translation>
 <translation id="374357899112510277">Թաքցնել «Ներբեռնումներ» կետը</translation>
 <translation id="3745190878148784130">Թաքցնել «Փոխել տեքստի չափսը» գործողությունը</translation>
@@ -1097,6 +1098,7 @@
 <translation id="6476800141292307438">Էջը թարգմանվում է <ph name="LANGUAGE" />: Կարգավորումները էկրանի ներքևի հատվածում են:</translation>
 <translation id="648164694371393720">Նույնականացման սխալ</translation>
 <translation id="6494931198667773526">Ավարտը՝</translation>
+<translation id="6500795388871406244">Օգտագործել առաջարկվող գաղտնաբառը՝</translation>
 <translation id="650279896687777322">Իմանալ ավելին…</translation>
 <translation id="6505334220040167806">Ծալել ներդիրների խումբը։</translation>
 <translation id="6507973708545996744">Մուտք գործեք՝ ձեր ընթերցանության ցանկը բոլոր սարքերում տեսնելու համար</translation>
@@ -1310,6 +1312,7 @@
 <translation id="7583004045319035904">Ապակողպեք ձեր ինկոգնիտո ներդիրները՝ օգտագործելով <ph name="BIOMETRIC_AUTHENITCATION_TYPE" />։</translation>
 <translation id="7598439272585186139">Ստացեք ավելի շատ անվտանգություն</translation>
 <translation id="7600965453749440009">Երբեք չթարգմանել <ph name="LANGUAGE" /> էջերը</translation>
+<translation id="7603308509262646847">Ինքնալրացնել քարտապանի անունը՝ <ph name="NAME" /></translation>
 <translation id="7603852183842204213">Ելնող պատուհաններն արգելափակվել են (<ph name="NUMBER_OF_BLOCKED_POPUPS" />)</translation>
 <translation id="7606639338662398635">Ներդիրների խմբեր</translation>
 <translation id="7607521702806708809">Ջնջել գաղտնաբառը</translation>
@@ -1342,6 +1345,7 @@
 <translation id="7749790401023484470">Դուք չեք ընտրել որևէ տեքստ։</translation>
 <translation id="7752405526771734448">Վիզուալ որոնում Տեսապակու միջոցով</translation>
 <translation id="7756478488453921771">Ընտրացանկ → Կարգավորումներ → Վճարման եղանակներ</translation>
+<translation id="775755486779745798">Ինքնալրացնել ժամկետի սպառման ամիսը՝ <ph name="MONTH" /></translation>
 <translation id="7760127703945531263">Ինկոգնիտո ներդիրների կողպում</translation>
 <translation id="7765158879357617694">Տեղափոխել</translation>
 <translation id="7772032839648071052">Հաստատեք անցաբառը</translation>
@@ -1518,6 +1522,7 @@
 <translation id="8556590991644167667">{count,plural, =1{Դուք փակել եք {count} նախազգուշացում}one{Դուք փակել եք {count} նախազգուշացում}other{Դուք փակել եք {count} նախազգուշացում}}</translation>
 <translation id="8560253818350321773">Սկզբում ցուցադրել հաճախակի օգտագործվող տարրերը</translation>
 <translation id="8569721750632860947">Ի՞նչ URL եք ուզում ավելացնել ձեր ընթերցանության ցանկում</translation>
+<translation id="8577056989960190117">Ինքնալրացնել ժամկետի սպառման տարեթիվը՝ <ph name="YEAR" /></translation>
 <translation id="8588404856427128947">Անջատված է</translation>
 <translation id="8591976964826315682">Արգելափակել կողմնակի կայքերի քուքիները ինկոգնիտո ռեժիմում</translation>
 <translation id="8593565399399144771">Կարող եք նոր ներդիր բացել այստեղ։</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_iw.xtb b/ios/chrome/app/strings/resources/ios_strings_iw.xtb
index c2c790e..80bfb96 100644
--- a/ios/chrome/app/strings/resources/ios_strings_iw.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_iw.xtb
@@ -200,6 +200,7 @@
 <translation id="199425419756152024">הצגת הסיסמה</translation>
 <translation id="2010008505735295285">טעינה מחדש</translation>
 <translation id="2015722694326466240">רוצה להציג את הסיסמאות? תחילה עליך להגדיר קוד גישה במכשיר.</translation>
+<translation id="201759455285471444">הרחבה של קבוצת הכרטיסיות.</translation>
 <translation id="2021670401941426298">ניתן לעיין בהוראות של מנוע החיפוש שמשמש אותך לגבי מחיקת היסטוריית החיפושים, אם רלוונטי.</translation>
 <translation id="202292859882676807">יש הרשאת גישה למיקרופון</translation>
 <translation id="20485545164632846">פריט חדש</translation>
@@ -1097,6 +1098,7 @@
 <translation id="648164694371393720">שגיאת אימות</translation>
 <translation id="6494931198667773526">מסתיים</translation>
 <translation id="650279896687777322">למידע נוסף…</translation>
+<translation id="6505334220040167806">כיווץ של קבוצת הכרטיסיות.</translation>
 <translation id="6507973708545996744">כדי שרשימת הקריאה תופיע בכל המכשירים שלך, כדאי להיכנס לחשבון.</translation>
 <translation id="6510072653668207258">קבלת תזכורת מאוחר יותר</translation>
 <translation id="651505212789431520">לבטל את הסנכרון? אפשר להפעיל את הסנכרון בכל זמן דרך 'הגדרות'.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_mr.xtb b/ios/chrome/app/strings/resources/ios_strings_mr.xtb
index 42b55460..aa43c392 100644
--- a/ios/chrome/app/strings/resources/ios_strings_mr.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_mr.xtb
@@ -532,6 +532,7 @@
 <translation id="371398631992790800">बुकमार्क लपवा</translation>
 <translation id="37207012422556617">ट्रेंडिंग शोध</translation>
 <translation id="3725081662140949903">तुमचा पासवर्ड वापरण्यापासून इतरांना थांबवण्यासाठी, तुमचा पासवर्ड बदलण्याकरिता <ph name="APP" /> ॲप उघडा</translation>
+<translation id="372676576864368480"><ph name="LAST_DIGITS" /> ने संपणारा कार्ड नंबर ऑटोफिल करा</translation>
 <translation id="3738428049780661523"><ph name="DATE" /> रोजी तयार केला आहे</translation>
 <translation id="374357899112510277">डाउनलोड लपवा</translation>
 <translation id="3745190878148784130">मजकुरावर झूम करा हे लपवा</translation>
@@ -1098,6 +1099,7 @@
 <translation id="6476800141292307438">पेजचे <ph name="LANGUAGE" /> मध्ये भाषांतर करत आहे. पर्याय स्क्रीनच्या खाली उपलब्ध आहेत.</translation>
 <translation id="648164694371393720">ऑथेंटिकेशन एरर</translation>
 <translation id="6494931198667773526">संपेल</translation>
+<translation id="6500795388871406244">सुचवलेला पासवर्ड वापरा:</translation>
 <translation id="650279896687777322">अधिक जाणून घ्या…</translation>
 <translation id="6505334220040167806">टॅब गट कोलॅप्स करा.</translation>
 <translation id="6507973708545996744">तुमच्या सर्व डिव्हाइसवर तुमची वाचन सूची मिळवण्यासाठी साइन इन करा.</translation>
@@ -1311,6 +1313,7 @@
 <translation id="7583004045319035904">तुमचे गुप्त टॅब अनलॉक करण्यासाठी <ph name="BIOMETRIC_AUTHENITCATION_TYPE" /> वापरा.</translation>
 <translation id="7598439272585186139">आणखी सुरक्षा मिळवा</translation>
 <translation id="7600965453749440009">कधीही <ph name="LANGUAGE" /> चा भाषांतर करु नका</translation>
+<translation id="7603308509262646847"><ph name="NAME" /> कार्डधारक ऑटोफिल करा</translation>
 <translation id="7603852183842204213">(<ph name="NUMBER_OF_BLOCKED_POPUPS" />) पॉप-अप ब्लॉक केले</translation>
 <translation id="7606639338662398635">टॅब गट</translation>
 <translation id="7607521702806708809">पासवर्ड हटवा</translation>
@@ -1343,6 +1346,7 @@
 <translation id="7749790401023484470">तुम्ही कोणताही मजकूर निवडला नाही.</translation>
 <translation id="7752405526771734448">Lens मधील व्हिज्युअल शोध</translation>
 <translation id="7756478488453921771">मेनू → सेटिंग्ज → पेमेंट पद्धती</translation>
+<translation id="775755486779745798">एक्स्पायरीचा महिना <ph name="MONTH" /> ऑटोफिल करा</translation>
 <translation id="7760127703945531263">गुप्त मोड लॉक करण्याची सुविधा</translation>
 <translation id="7765158879357617694">हलवा</translation>
 <translation id="7772032839648071052">सांकेतिक पासफ्रेझ निश्चित करा</translation>
@@ -1519,6 +1523,7 @@
 <translation id="8556590991644167667">{count,plural, =1{तुम्ही {count} चेतावणी डिसमिस केली आहे}other{तुम्ही {count} चेतावण्या डिसमिस केल्या आहेत}}</translation>
 <translation id="8560253818350321773">वारंवार वापरले जाणारे आयटम सर्वप्रथम दाखवा.</translation>
 <translation id="8569721750632860947">तुम्हाला तुमच्या वाचन सूचीमध्ये कोणती URL जोडायची आहे?</translation>
+<translation id="8577056989960190117">एक्स्पायरीचे वर्ष <ph name="YEAR" /> ऑटोफिल करा</translation>
 <translation id="8588404856427128947">बंद करा</translation>
 <translation id="8591976964826315682">तृतीय पक्ष कुकी गुप्त मोडमध्ये ब्लॉक करा</translation>
 <translation id="8593565399399144771">तुम्ही इथे नवीन टॅब उघडू शकता.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ms.xtb b/ios/chrome/app/strings/resources/ios_strings_ms.xtb
index d2bc212c..183822e4 100644
--- a/ios/chrome/app/strings/resources/ios_strings_ms.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_ms.xtb
@@ -532,6 +532,7 @@
 <translation id="371398631992790800">Sembunyikan Penanda Halaman</translation>
 <translation id="37207012422556617">Carian Sohor Kini</translation>
 <translation id="3725081662140949903">Untuk menghalang orang lain daripada menggunakan kata laluan anda, buka apl <ph name="APP" /> untuk menukar kata laluan anda</translation>
+<translation id="372676576864368480">Autoisi nombor kad yang berakhir dengan <ph name="LAST_DIGITS" /></translation>
 <translation id="3738428049780661523">Dibuat <ph name="DATE" /></translation>
 <translation id="374357899112510277">Sembunyikan Muat Turun</translation>
 <translation id="3745190878148784130">Sembunyikan Zum Teks</translation>
@@ -1097,6 +1098,7 @@
 <translation id="6476800141292307438">Menterjemah halaman ini kepada <ph name="LANGUAGE" />. Pilihan tersedia berhampiran bahagian bawah skrin.</translation>
 <translation id="648164694371393720">Ralat Pengesahan</translation>
 <translation id="6494931198667773526">Tamat</translation>
+<translation id="6500795388871406244">Gunakan Kata Laluan yang Dicadangkan:</translation>
 <translation id="650279896687777322">Ketahui Lebih Lanjut...</translation>
 <translation id="6505334220040167806">Kuncupkan kumpulan tab.</translation>
 <translation id="6507973708545996744">Log masuk untuk mendapatkan senarai bacaan pada semua peranti anda.</translation>
@@ -1310,6 +1312,7 @@
 <translation id="7583004045319035904">Gunakan <ph name="BIOMETRIC_AUTHENITCATION_TYPE" /> untuk membuka kunci tab Inkognito anda.</translation>
 <translation id="7598439272585186139">Dapatkan perlindungan lanjut</translation>
 <translation id="7600965453749440009">Jangan sekali-kali terjemahkan <ph name="LANGUAGE" /></translation>
+<translation id="7603308509262646847">Autoisi pemegang kad <ph name="NAME" /></translation>
 <translation id="7603852183842204213">Pop timbul disekat (<ph name="NUMBER_OF_BLOCKED_POPUPS" />)</translation>
 <translation id="7606639338662398635">Kumpulan Tab</translation>
 <translation id="7607521702806708809">Padamkan Kata Laluan</translation>
@@ -1342,6 +1345,7 @@
 <translation id="7749790401023484470">Anda tidak memilih apa-apa teks.</translation>
 <translation id="7752405526771734448">Carian Visual Lens</translation>
 <translation id="7756478488453921771">Menu → Tetapan → Kaedah Pembayaran</translation>
+<translation id="775755486779745798">Autoisi bulan tamat tempoh <ph name="MONTH" /></translation>
 <translation id="7760127703945531263">Kunci Inkognito</translation>
 <translation id="7765158879357617694">Alih</translation>
 <translation id="7772032839648071052">Sahkan frasa laluan</translation>
@@ -1518,6 +1522,7 @@
 <translation id="8556590991644167667">{count,plural, =1{Anda mengetepikan {count} amaran}other{Anda mengetepikan {count} amaran}}</translation>
 <translation id="8560253818350321773">Menunjukkan item yang sering digunakan dahulu.</translation>
 <translation id="8569721750632860947">Apakah URL yang mahu ditambahkan pada senarai bacaan anda?</translation>
+<translation id="8577056989960190117">Autoisi tahun tamat tempoh <ph name="YEAR" /></translation>
 <translation id="8588404856427128947">Mati</translation>
 <translation id="8591976964826315682">Sekat Kuki Pihak Ketiga dalam Inkognito</translation>
 <translation id="8593565399399144771">Anda boleh membuka tab baharu di sini.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_nl.xtb b/ios/chrome/app/strings/resources/ios_strings_nl.xtb
index f32a875..e4cf2b0e 100644
--- a/ios/chrome/app/strings/resources/ios_strings_nl.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_nl.xtb
@@ -532,6 +532,7 @@
 <translation id="371398631992790800">Bookmarks verbergen</translation>
 <translation id="37207012422556617">Trending zoekopdrachten</translation>
 <translation id="3725081662140949903">Als je niet wilt dat anderen je wachtwoord gebruiken, open je de <ph name="APP" />-app om je wachtwoord te wijzigen</translation>
+<translation id="372676576864368480">Het kaartnummer dat eindigt op <ph name="LAST_DIGITS" /> automatisch invullen</translation>
 <translation id="3738428049780661523">Gemaakt: <ph name="DATE" /></translation>
 <translation id="374357899112510277">Downloads verbergen</translation>
 <translation id="3745190878148784130">Tekst zoomen verbergen</translation>
@@ -1097,6 +1098,7 @@
 <translation id="6476800141292307438">De pagina vertalen naar het <ph name="LANGUAGE" />. Opties beschikbaar onderaan het scherm.</translation>
 <translation id="648164694371393720">Verificatiefout</translation>
 <translation id="6494931198667773526">Eindigt</translation>
+<translation id="6500795388871406244">Voorgesteld wachtwoord gebruiken:</translation>
 <translation id="650279896687777322">Meer informatie...</translation>
 <translation id="6505334220040167806">Tabbladgroep samenvouwen.</translation>
 <translation id="6507973708545996744">Log in om je leeslijst op al je apparaten te gebruiken.</translation>
@@ -1310,6 +1312,7 @@
 <translation id="7583004045319035904">Gebruik <ph name="BIOMETRIC_AUTHENITCATION_TYPE" /> om je incognitotabbladen te ontgrendelen.</translation>
 <translation id="7598439272585186139">Meer beveiliging krijgen</translation>
 <translation id="7600965453749440009"><ph name="LANGUAGE" /> nooit vertalen</translation>
+<translation id="7603308509262646847">De kaarthouder <ph name="NAME" /> automatisch invullen</translation>
 <translation id="7603852183842204213">Pop-ups geblokkeerd (<ph name="NUMBER_OF_BLOCKED_POPUPS" />)</translation>
 <translation id="7606639338662398635">Tabbladgroepen</translation>
 <translation id="7607521702806708809">Wachtwoord verwijderen</translation>
@@ -1342,6 +1345,7 @@
 <translation id="7749790401023484470">Je hebt geen tekst geselecteerd.</translation>
 <translation id="7752405526771734448">Visueel zoeken met Lens</translation>
 <translation id="7756478488453921771">Menu → Instellingen → Betaalmethoden</translation>
+<translation id="775755486779745798">De vervalmaand <ph name="MONTH" /> automatisch invullen</translation>
 <translation id="7760127703945531263">Incognitovergrendeling</translation>
 <translation id="7765158879357617694">Verplaatsen</translation>
 <translation id="7772032839648071052">Bevestig de wachtwoordzin</translation>
@@ -1518,6 +1522,7 @@
 <translation id="8556590991644167667">{count,plural, =1{Je hebt {count} waarschuwing gesloten}other{Je hebt {count} waarschuwingen gesloten}}</translation>
 <translation id="8560253818350321773">Toon veelgebruikte items eerst.</translation>
 <translation id="8569721750632860947">Welke URL wil je toevoegen aan je leeslijst?</translation>
+<translation id="8577056989960190117">Het vervaljaar <ph name="YEAR" /> automatisch invullen</translation>
 <translation id="8588404856427128947">Uit</translation>
 <translation id="8591976964826315682">Cookies van derden blokkeren in incognitomodus</translation>
 <translation id="8593565399399144771">Je kunt hier een nieuw tabblad openen.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_si.xtb b/ios/chrome/app/strings/resources/ios_strings_si.xtb
index b1480d85..99f5d099 100644
--- a/ios/chrome/app/strings/resources/ios_strings_si.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_si.xtb
@@ -784,6 +784,7 @@
 <translation id="4971735654804503942">අනතුරුදායක වෙබ් අඩවිවලට, බාගැනීම්වලට, සහ දිගුවලට එරෙහි වඩා වේගවත්, පූර්වාරක්‍ෂාකාරී ආරක්‍ෂාව. මුරපද කඩ කිරීම් ගැන ඔබට අවවාද කරයි. බ්‍රවුස් කිරීමේ දත්ත Google වෙත යැවීම අවශ්‍ය කරයි.</translation>
 <translation id="4979397965658815378">ඔබගේ සියලුම උපාංග මත පිටුසන්, මුරපද, ඉතිහාසය හා අනෙකුත් සැකසීම් ලබා ගැනීමට ඔබගේ Google ගිණුම සමඟ පුරනය වන්න</translation>
 <translation id="4989065233040279145"><ph name="FILENAME" /> සුරකින ස්ථානය තෝරා ගන්න</translation>
+<translation id="4992255726304765516">පටිති සමූහ වර්ණය <ph name="COLOR" /></translation>
 <translation id="5005498671520578047">මුරපදය පිටපත් කරන්න</translation>
 <translation id="5016420433031926653"><ph name="USER_EMAIL" /> වෙත යවන්න</translation>
 <translation id="5017828934289857214">මට පසුව සිහිකැඳවන්න</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_sr-Latn.xtb b/ios/chrome/app/strings/resources/ios_strings_sr-Latn.xtb
index 3901f74..b9d356d 100644
--- a/ios/chrome/app/strings/resources/ios_strings_sr-Latn.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_sr-Latn.xtb
@@ -783,6 +783,7 @@
 <translation id="4971735654804503942">Brža proaktivna zaštita od opasnih veb-sajtova, preuzimanja i dodataka. Upozorava vas o otkrivanju lozinki. Zahteva slanje podataka pregledanja Google-u.</translation>
 <translation id="4979397965658815378">Prijavite se pomoću Google naloga da biste imali obeleživače, lozinke, istoriju i druga podešavanja na svim uređajima</translation>
 <translation id="4989065233040279145">Izaberite gde će fajl <ph name="FILENAME" /> biti sačuvan</translation>
+<translation id="4992255726304765516">Boja grupe kartica <ph name="COLOR" /></translation>
 <translation id="5005498671520578047">Kopiranje lozinke</translation>
 <translation id="5016420433031926653">Pošaljite na <ph name="USER_EMAIL" /></translation>
 <translation id="5017828934289857214">Podseti me kasnije</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_sr.xtb b/ios/chrome/app/strings/resources/ios_strings_sr.xtb
index aa20ada..3071f92 100644
--- a/ios/chrome/app/strings/resources/ios_strings_sr.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_sr.xtb
@@ -783,6 +783,7 @@
 <translation id="4971735654804503942">Бржа проактивна заштита од опасних веб-сајтова, преузимања и додатака. Упозорава вас о откривању лозинки. Захтева слање података прегледања Google-у.</translation>
 <translation id="4979397965658815378">Пријавите се помоћу Google налога да бисте имали обележиваче, лозинке, историју и друга подешавања на свим уређајима</translation>
 <translation id="4989065233040279145">Изаберите где ће фајл <ph name="FILENAME" /> бити сачуван</translation>
+<translation id="4992255726304765516">Боја групе картица <ph name="COLOR" /></translation>
 <translation id="5005498671520578047">Копирање лозинке</translation>
 <translation id="5016420433031926653">Пошаљите на <ph name="USER_EMAIL" /></translation>
 <translation id="5017828934289857214">Подсети ме касније</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_uz.xtb b/ios/chrome/app/strings/resources/ios_strings_uz.xtb
index 2608be5..7f27f52 100644
--- a/ios/chrome/app/strings/resources/ios_strings_uz.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_uz.xtb
@@ -532,6 +532,7 @@
 <translation id="371398631992790800">Bukmarklarni yashirish</translation>
 <translation id="37207012422556617">Qidiruv trendlari</translation>
 <translation id="3725081662140949903">Boshqalar parolingizni ishlatmasligi uchun <ph name="APP" /> ilovasini ochib, parolni almashtiring</translation>
+<translation id="372676576864368480">Karta raqamini (<ph name="LAST_DIGITS" />) avtomatik kiritish</translation>
 <translation id="3738428049780661523">Yaratilgan: <ph name="DATE" /></translation>
 <translation id="374357899112510277">Yuklanmalarni yashirish</translation>
 <translation id="3745190878148784130">Matn masshtabini berkitish</translation>
@@ -1097,6 +1098,7 @@
 <translation id="6476800141292307438">Sahifa <ph name="LANGUAGE" /> tiliga tarjima qilinmoqda. Parametrlar ekranning pastiga yaqin joyda joylashgan.</translation>
 <translation id="648164694371393720">Autentifikatsiya xatosi</translation>
 <translation id="6494931198667773526">Tugashi</translation>
+<translation id="6500795388871406244">Taklif qilingan parolni ishlatish:</translation>
 <translation id="650279896687777322">Batafsil...</translation>
 <translation id="6505334220040167806">Varaqlar guruhini yigʻish.</translation>
 <translation id="6507973708545996744">Oʻqish roʻyxatini barcha qurilmalarda ochish uchun hisobga kiring.</translation>
@@ -1310,6 +1312,7 @@
 <translation id="7583004045319035904">Inkognito varaqlar qulfini <ph name="BIOMETRIC_AUTHENITCATION_TYPE" /> bilan oching.</translation>
 <translation id="7598439272585186139">Xavfsizlikni oshirish</translation>
 <translation id="7600965453749440009"><ph name="LANGUAGE" /> tili hech qachon tarjima qilinmasin</translation>
+<translation id="7603308509262646847">Karta egasini (<ph name="NAME" />) avtomatik kiritish</translation>
 <translation id="7603852183842204213">Qalqib chiquvchi oynalar bloklandi (<ph name="NUMBER_OF_BLOCKED_POPUPS" />)</translation>
 <translation id="7606639338662398635">Varaqlar guruhi</translation>
 <translation id="7607521702806708809">Parolni olib tashlash</translation>
@@ -1342,6 +1345,7 @@
 <translation id="7749790401023484470">Matn tanlang.</translation>
 <translation id="7752405526771734448">Lens orqali vizual qidiruv</translation>
 <translation id="7756478488453921771">Menyu → Sozlamalar → Toʻlov usullari</translation>
+<translation id="775755486779745798">Amal qilish oyini (<ph name="MONTH" />) avtomatik kiritish</translation>
 <translation id="7760127703945531263">Inkognito qulflanishi</translation>
 <translation id="7765158879357617694">Ko‘chirib o‘tkazish</translation>
 <translation id="7772032839648071052">Kodli iborani tasdiqlang</translation>
@@ -1518,6 +1522,7 @@
 <translation id="8556590991644167667">{count,plural, =1{{count} ta ogohlantirishni yopdingiz}other{{count} ta ogohlantirishni yopdingiz}}</translation>
 <translation id="8560253818350321773">Avval tez-tez ishlatilgan elementlarni chiqarish.</translation>
 <translation id="8569721750632860947">Qaysi URL Saqlangan sahifalarga kiritilsin?</translation>
+<translation id="8577056989960190117">Amal qilish yilini (<ph name="YEAR" />) avtomatik kiritish</translation>
 <translation id="8588404856427128947">Oʻchiq</translation>
 <translation id="8591976964826315682">Inkognito rejimidagi tashqi cookie fayllarni taqiqlash</translation>
 <translation id="8593565399399144771">Endi yangi varaq ochish mumkin.</translation>
diff --git a/ios/chrome/browser/autofill/model/form_suggestion_controller.mm b/ios/chrome/browser/autofill/model/form_suggestion_controller.mm
index 1593471..9b0784f 100644
--- a/ios/chrome/browser/autofill/model/form_suggestion_controller.mm
+++ b/ios/chrome/browser/autofill/model/form_suggestion_controller.mm
@@ -403,12 +403,10 @@
   NSMutableArray<FormSuggestion*>* suggestionsCopy = [NSMutableArray array];
   for (FormSuggestion* suggestion : suggestions) {
     BOOL isPlusAddressSuggestion =
-        (suggestion.popupItemId ==
-         autofill::SuggestionType::kCreateNewPlusAddress) ||
-        (suggestion.popupItemId ==
-         autofill::SuggestionType::kFillExistingPlusAddress);
+        (suggestion.type == autofill::SuggestionType::kCreateNewPlusAddress) ||
+        (suggestion.type == autofill::SuggestionType::kFillExistingPlusAddress);
 
-    UIImage* defaultIcon = defaultIconForType(suggestion.popupItemId);
+    UIImage* defaultIcon = defaultIconForType(suggestion.type);
 
     // If there are no icons, but we have a default icon for this suggestion,
     // copy the suggestion and add the default icon. If
@@ -430,7 +428,7 @@
                                         minorValue:suggestion.minorValue
                                 displayDescription:suggestion.displayDescription
                                               icon:defaultIcon
-                                       popupItemId:suggestion.popupItemId
+                                              type:suggestion.type
                                  backendIdentifier:suggestion.backendIdentifier
                                     requiresReauth:suggestion.requiresReauth
                         acceptanceA11yAnnouncement:
diff --git a/ios/chrome/browser/autofill/model/form_suggestion_controller_unittest.mm b/ios/chrome/browser/autofill/model/form_suggestion_controller_unittest.mm
index a7889cc..04f98b4 100644
--- a/ios/chrome/browser/autofill/model/form_suggestion_controller_unittest.mm
+++ b/ios/chrome/browser/autofill/model/form_suggestion_controller_unittest.mm
@@ -81,13 +81,13 @@
         suggestionWithValue:@"foo"
          displayDescription:nil
                        icon:nil
-                popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                       type:autofill::SuggestionType::kAutocompleteEntry
           backendIdentifier:nil
              requiresReauth:NO],
     [FormSuggestion suggestionWithValue:@"bar"
                      displayDescription:nil
                                    icon:nil
-                            popupItemId:autofill::SuggestionType::kAddressEntry
+                                   type:autofill::SuggestionType::kAddressEntry
                       backendIdentifier:nil
                          requiresReauth:NO]
   ];
@@ -399,13 +399,13 @@
         suggestionWithValue:@"foo"
          displayDescription:nil
                        icon:nil
-                popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                       type:autofill::SuggestionType::kAutocompleteEntry
           backendIdentifier:nil
              requiresReauth:NO],
     [FormSuggestion suggestionWithValue:@"bar"
                      displayDescription:nil
                                    icon:nil
-                            popupItemId:autofill::SuggestionType::kAddressEntry
+                                   type:autofill::SuggestionType::kAddressEntry
                       backendIdentifier:nil
                          requiresReauth:NO]
   ];
@@ -452,7 +452,7 @@
         suggestionWithValue:@"foo"
          displayDescription:nil
                        icon:nil
-                popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                       type:autofill::SuggestionType::kAutocompleteEntry
           backendIdentifier:nil
              requiresReauth:NO],
   ];
@@ -490,7 +490,7 @@
       suggestionWithValue:@"foo"
        displayDescription:nil
                      icon:nil
-              popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                     type:autofill::SuggestionType::kAutocompleteEntry
         backendIdentifier:nil
            requiresReauth:NO];
   suggestion.featureForIPH = @"YES";
@@ -523,7 +523,7 @@
       suggestionWithValue:@""
        displayDescription:nil
                      icon:nil
-              popupItemId:autofill::SuggestionType::kGeneratePasswordEntry
+                     type:autofill::SuggestionType::kGeneratePasswordEntry
         backendIdentifier:nil
            requiresReauth:NO];
   [suggestions addObject:suggestion];
@@ -552,7 +552,7 @@
       suggestionWithValue:@""
        displayDescription:nil
                      icon:nil
-              popupItemId:autofill::SuggestionType::kCreateNewPlusAddress
+                     type:autofill::SuggestionType::kCreateNewPlusAddress
         backendIdentifier:nil
            requiresReauth:NO];
   [suggestions addObject:suggestion];
@@ -561,7 +561,7 @@
       suggestionWithValue:@""
        displayDescription:nil
                      icon:nil
-              popupItemId:autofill::SuggestionType::kFillExistingPlusAddress
+                     type:autofill::SuggestionType::kFillExistingPlusAddress
         backendIdentifier:nil
            requiresReauth:NO];
   [suggestions addObject:suggestion];
diff --git a/ios/chrome/browser/ui/browser_view/BUILD.gn b/ios/chrome/browser/browser_view/ui_bundled/BUILD.gn
similarity index 98%
rename from ios/chrome/browser/ui/browser_view/BUILD.gn
rename to ios/chrome/browser/browser_view/ui_bundled/BUILD.gn
index aee5f3a3..e8cd269 100644
--- a/ios/chrome/browser/ui/browser_view/BUILD.gn
+++ b/ios/chrome/browser/browser_view/ui_bundled/BUILD.gn
@@ -2,7 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-source_set("browser_view") {
+source_set("ui_bundled") {
   sources = [
     "browser_coordinator+Testing.h",
     "browser_coordinator.h",
@@ -65,6 +65,9 @@
     "//ios/chrome/browser/crash_report/model",
     "//ios/chrome/browser/credential_provider_promo/ui_bundled:coordinator",
     "//ios/chrome/browser/default_browser/model:utils",
+    "//ios/chrome/browser/default_promo/ui_bundled:coordinator",
+    "//ios/chrome/browser/default_promo/ui_bundled:ui",
+    "//ios/chrome/browser/default_promo/ui_bundled/generic",
     "//ios/chrome/browser/dialogs/ui_bundled:dialogs_internal",
     "//ios/chrome/browser/docking_promo/coordinator",
     "//ios/chrome/browser/download/model",
@@ -84,6 +87,7 @@
     "//ios/chrome/browser/itunes_urls/model",
     "//ios/chrome/browser/language/model",
     "//ios/chrome/browser/lens/model",
+    "//ios/chrome/browser/lens_overlay/coordinator",
     "//ios/chrome/browser/link_to_text/model",
     "//ios/chrome/browser/main/model",
     "//ios/chrome/browser/metrics/model:metrics_browser_agent",
@@ -158,9 +162,6 @@
     "//ios/chrome/browser/ui/browser_container:ui",
     "//ios/chrome/browser/ui/content_suggestions",
     "//ios/chrome/browser/ui/content_suggestions:content_suggestions_constant",
-    "//ios/chrome/browser/ui/default_promo",
-    "//ios/chrome/browser/ui/default_promo:default_promo_ui",
-    "//ios/chrome/browser/ui/default_promo/generic",
     "//ios/chrome/browser/ui/find_bar",
     "//ios/chrome/browser/ui/first_run",
     "//ios/chrome/browser/ui/first_run:utils",
@@ -297,7 +298,7 @@
     "key_commands_provider_unittest.mm",
   ]
   deps = [
-    ":browser_view",
+    ":ui_bundled",
     "//components/bookmarks/browser",
     "//components/bookmarks/test",
     "//components/commerce/core:shopping_service_test_support",
diff --git a/ios/chrome/browser/browser_view/ui_bundled/DEPS b/ios/chrome/browser/browser_view/ui_bundled/DEPS
new file mode 100644
index 0000000..667b897
--- /dev/null
+++ b/ios/chrome/browser/browser_view/ui_bundled/DEPS
@@ -0,0 +1,69 @@
+include_rules = [
+  "+ios/chrome/browser/app_launcher/model",
+  "+ios/chrome/browser/app_store_rating/ui_bundled/features.h",
+  "+ios/chrome/browser/autofill/model",
+  "+ios/chrome/browser/bookmarks/model/bookmark_model_factory.h",
+  "+ios/chrome/browser/bookmarks/ui_bundled/home/bookmarks_coordinator.h",
+  "+ios/chrome/browser/browser_view/ui_bundled",
+  "+ios/chrome/browser/bubble/ui_bundled",
+  "+ios/chrome/browser/commerce/model",
+  "+ios/chrome/browser/content_settings/model/host_content_settings_map_factory.h",
+  "+ios/chrome/browser/context_menu/ui_bundled/context_menu_configuration_provider.h",
+  "+ios/chrome/browser/contextual_panel",
+  "+ios/chrome/browser/crash_report/model/crash_keys_helper.h",
+  "+ios/chrome/browser/credential_provider_promo/ui_bundled/credential_provider_promo_coordinator.h",
+  "+ios/chrome/browser/default_browser/model/utils.h",
+  "+ios/chrome/browser/default_promo/ui_bundled",
+  "+ios/chrome/browser/discover_feed/model/feed_constants.h",
+  "+ios/chrome/browser/docking_promo/coordinator/docking_promo_coordinator.h",
+  "+ios/chrome/browser/download/model",
+  "+ios/chrome/browser/download/ui_bundled",
+  "+ios/chrome/browser/feature_engagement/model",
+  "+ios/chrome/browser/find_in_page/model",
+  "+ios/chrome/browser/follow/model",
+  "+ios/chrome/browser/infobars/model",
+  "+ios/chrome/browser/intents/intents_donation_helper.h",
+  "+ios/chrome/browser/iph_for_new_chrome_user/model/tab_based_iph_browser_agent.h",
+  "+ios/chrome/browser/itunes_urls/model/itunes_urls_handler_tab_helper.h",
+  "+ios/chrome/browser/lens/model/lens_tab_helper.h",
+  "+ios/chrome/browser/lens_overlay/coordinator/lens_overlay_coordinator.h",
+  "+ios/chrome/browser/metrics/model",
+  "+ios/chrome/browser/ntp/model",
+  "+ios/chrome/browser/overscroll_actions/model/overscroll_actions_tab_helper.h",
+  "+ios/chrome/browser/parcel_tracking",
+  "+ios/chrome/browser/passwords",
+  "+ios/chrome/browser/plus_addresses/coordinator/plus_address_bottom_sheet_coordinator.h",
+  "+ios/chrome/browser/policy/model/policy_util.h",
+  "+ios/chrome/browser/prerender/model",
+  "+ios/chrome/browser/promos_manager/model/features.h",
+  "+ios/chrome/browser/qr_scanner/ui_bundled/qr_scanner_legacy_coordinator.h",
+  "+ios/chrome/browser/reading_list/model/reading_list_browser_agent.h",
+  "+ios/chrome/browser/segmentation_platform/model/segmentation_platform_service_factory.h",
+  "+ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h",
+  "+ios/chrome/browser/settings/model/sync/utils/sync_presenter.h",
+  "+ios/chrome/browser/signin/model",
+  "+ios/chrome/browser/snapshots/model",
+  "+ios/chrome/browser/ssl/model/captive_portal_tab_helper.h",
+  "+ios/chrome/browser/store_kit/model",
+  "+ios/chrome/browser/sync/model/sync_error_browser_agent.h",
+  "+ios/chrome/browser/tab_insertion/model/tab_insertion_browser_agent.h",
+  "+ios/chrome/browser/tabs/model/tab_title_util.h",
+  "+ios/chrome/browser/translate/model/chrome_ios_translate_client.h",
+  "+ios/chrome/browser/ui",
+  "+ios/chrome/browser/url_loading/model",
+  "+ios/chrome/browser/view_source/model/view_source_browser_agent.h",
+  "+ios/chrome/browser/voice/ui_bundled",
+  "+ios/chrome/browser/web/model",
+  "+ios/chrome/browser/web_state_list/model",
+  "+ios/chrome/browser/webui",
+  "+ios/chrome/browser/window_activities/model/window_activity_helpers.h",
+]
+
+specific_include_rules = {
+  "key_commands_provider_unittest\.mm": [
+    "+ios/web/find_in_page/java_script_find_in_page_manager_impl.h",
+  ],
+  "browser_view_controller_egtest\.mm": [
+    "+ios/web/public/test/http_server",
+  ],
+}
diff --git a/ios/chrome/browser/ui/browser_view/OWNERS b/ios/chrome/browser/browser_view/ui_bundled/OWNERS
similarity index 100%
rename from ios/chrome/browser/ui/browser_view/OWNERS
rename to ios/chrome/browser/browser_view/ui_bundled/OWNERS
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator+Testing.h b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator+Testing.h
similarity index 70%
rename from ios/chrome/browser/ui/browser_view/browser_coordinator+Testing.h
rename to ios/chrome/browser/browser_view/ui_bundled/browser_coordinator+Testing.h
index 9440a74..2e88dac7 100644
--- a/ios/chrome/browser/ui/browser_view/browser_coordinator+Testing.h
+++ b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator+Testing.h
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_BROWSER_VIEW_BROWSER_COORDINATOR_TESTING_H_
-#define IOS_CHROME_BROWSER_UI_BROWSER_VIEW_BROWSER_COORDINATOR_TESTING_H_
+#ifndef IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_BROWSER_COORDINATOR_TESTING_H_
+#define IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_BROWSER_COORDINATOR_TESTING_H_
 
-#import "ios/chrome/browser/ui/browser_view/browser_coordinator.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.h"
 
 #import "ios/chrome/browser/shared/public/commands/activity_service_commands.h"
 #import "ios/chrome/browser/ui/save_to_photos/save_to_photos_coordinator.h"
@@ -24,4 +24,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_BROWSER_VIEW_BROWSER_COORDINATOR_TESTING_H_
+#endif  // IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_BROWSER_COORDINATOR_TESTING_H_
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.h b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.h
similarity index 79%
rename from ios/chrome/browser/ui/browser_view/browser_coordinator.h
rename to ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.h
index d7b8256e..9e95c62d 100644
--- a/ios/chrome/browser/ui/browser_view/browser_coordinator.h
+++ b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_BROWSER_VIEW_BROWSER_COORDINATOR_H_
-#define IOS_CHROME_BROWSER_UI_BROWSER_VIEW_BROWSER_COORDINATOR_H_
+#ifndef IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_BROWSER_COORDINATOR_H_
+#define IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_BROWSER_COORDINATOR_H_
 
 #include "base/ios/block_types.h"
 #import "ios/chrome/browser/settings/model/sync/utils/sync_presenter.h"
@@ -26,4 +26,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_BROWSER_VIEW_BROWSER_COORDINATOR_H_
+#endif  // IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_BROWSER_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.mm
similarity index 98%
rename from ios/chrome/browser/ui/browser_view/browser_coordinator.mm
rename to ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.mm
index 511ac020..974f686 100644
--- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
+++ b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/browser_view/browser_coordinator.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.h"
 
 #import <StoreKit/StoreKit.h>
 
@@ -32,6 +32,14 @@
 #import "ios/chrome/browser/app_launcher/model/app_launcher_tab_helper_browser_presentation_provider.h"
 #import "ios/chrome/browser/app_store_rating/ui_bundled/features.h"
 #import "ios/chrome/browser/bookmarks/ui_bundled/home/bookmarks_coordinator.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_coordinator+Testing.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_view_controller+private.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_view_visibility_consumer.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/key_commands_provider.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/safe_area_provider.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/tab_events_mediator.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/tab_lifecycle_mediator.h"
 #import "ios/chrome/browser/bubble/ui_bundled/bubble_presenter.h"
 #import "ios/chrome/browser/bubble/ui_bundled/bubble_presenter_delegate.h"
 #import "ios/chrome/browser/bubble/ui_bundled/bubble_view_controller_presenter.h"
@@ -43,6 +51,11 @@
 #import "ios/chrome/browser/contextual_panel/model/contextual_panel_tab_helper.h"
 #import "ios/chrome/browser/credential_provider_promo/ui_bundled/credential_provider_promo_coordinator.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_commands.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_coordinator.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/default_promo_non_modal_presentation_delegate.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_commands.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_coordinator.h"
 #import "ios/chrome/browser/docking_promo/coordinator/docking_promo_coordinator.h"
 #import "ios/chrome/browser/download/model/download_directory_util.h"
 #import "ios/chrome/browser/download/model/external_app_util.h"
@@ -64,6 +77,7 @@
 #import "ios/chrome/browser/infobars/model/infobar_manager_impl.h"
 #import "ios/chrome/browser/intents/intents_donation_helper.h"
 #import "ios/chrome/browser/iph_for_new_chrome_user/model/tab_based_iph_browser_agent.h"
+#import "ios/chrome/browser/lens_overlay/coordinator/lens_overlay_coordinator.h"
 #import "ios/chrome/browser/metrics/model/tab_usage_recorder_browser_agent.h"
 #import "ios/chrome/browser/ntp/model/new_tab_page_state.h"
 #import "ios/chrome/browser/ntp/model/new_tab_page_tab_helper.h"
@@ -165,19 +179,6 @@
 #import "ios/chrome/browser/ui/autofill/progress_dialog/autofill_progress_dialog_coordinator.h"
 #import "ios/chrome/browser/ui/browser_container/browser_container_coordinator.h"
 #import "ios/chrome/browser/ui/browser_container/browser_container_view_controller.h"
-#import "ios/chrome/browser/ui/browser_view/browser_coordinator+Testing.h"
-#import "ios/chrome/browser/ui/browser_view/browser_view_controller+private.h"
-#import "ios/chrome/browser/ui/browser_view/browser_view_controller.h"
-#import "ios/chrome/browser/ui/browser_view/browser_view_visibility_consumer.h"
-#import "ios/chrome/browser/ui/browser_view/key_commands_provider.h"
-#import "ios/chrome/browser/ui/browser_view/safe_area_provider.h"
-#import "ios/chrome/browser/ui/browser_view/tab_events_mediator.h"
-#import "ios/chrome/browser/ui/browser_view/tab_lifecycle_mediator.h"
-#import "ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_commands.h"
-#import "ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_coordinator.h"
-#import "ios/chrome/browser/ui/default_promo/default_promo_non_modal_presentation_delegate.h"
-#import "ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_commands.h"
-#import "ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_coordinator.h"
 #import "ios/chrome/browser/ui/find_bar/find_bar_controller_ios.h"
 #import "ios/chrome/browser/ui/find_bar/find_bar_coordinator.h"
 #import "ios/chrome/browser/ui/first_run/omnibox_position/omnibox_position_choice_coordinator.h"
@@ -564,6 +565,7 @@
   BubbleViewControllerPresenter* _contextualPanelEntrypointHelpPresenter;
   ToolbarAccessoryPresenter* _toolbarAccessoryPresenter;
   LensCoordinator* _lensCoordinator;
+  LensOverlayCoordinator* _lensOverlayCoordinator;
   ToolbarCoordinator* _toolbarCoordinator;
   TabStripCoordinator* _tabStripCoordinator;
   TabStripLegacyCoordinator* _legacyTabStripCoordinator;
@@ -1070,6 +1072,7 @@
   self.tabLifecycleMediator.NTPCoordinator = _NTPCoordinator;
 
   _lensCoordinator = [[LensCoordinator alloc] initWithBrowser:self.browser];
+
   _voiceSearchController =
       ios::provider::CreateVoiceSearchController(self.browser);
 
@@ -1210,6 +1213,9 @@
   [_lensCoordinator stop];
   _lensCoordinator = nil;
 
+  [_lensOverlayCoordinator stop];
+  _lensOverlayCoordinator = nil;
+
   [self.downloadManagerCoordinator stop];
   self.downloadManagerCoordinator = nil;
 
@@ -1373,6 +1379,13 @@
                          browser:self.browser];
   _dockingPromoCoordinator.promosUIHandler = _promosManagerCoordinator;
   [_dockingPromoCoordinator start];
+
+  if (base::FeatureList::IsEnabled(kEnableLensOverlay)) {
+    _lensOverlayCoordinator = [[LensOverlayCoordinator alloc]
+        initWithBaseViewController:self.viewController
+                           browser:self.browser];
+    [_lensOverlayCoordinator start];
+  }
 }
 
 // Stops child coordinators.
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator_unittest.mm
similarity index 97%
rename from ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm
rename to ios/chrome/browser/browser_view/ui_bundled/browser_coordinator_unittest.mm
index d4ad00d..bbecc0bf 100644
--- a/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm
+++ b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator_unittest.mm
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/browser_view/browser_coordinator.h"
-#import "ios/chrome/browser/ui/browser_view/browser_coordinator+Testing.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_coordinator+Testing.h"
 
 #import "base/files/file_util.h"
 #import "base/test/scoped_feature_list.h"
@@ -11,6 +11,7 @@
 #import "components/commerce/core/mock_shopping_service.h"
 #import "ios/chrome/browser/bookmarks/model/bookmark_model_factory.h"
 #import "ios/chrome/browser/bookmarks/model/local_or_syncable_bookmark_model_factory.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.h"
 #import "ios/chrome/browser/commerce/model/shopping_service_factory.h"
 #import "ios/chrome/browser/download/model/download_directory_util.h"
 #import "ios/chrome/browser/download/model/external_app_util.h"
@@ -41,7 +42,6 @@
 #import "ios/chrome/browser/sync/model/sync_error_browser_agent.h"
 #import "ios/chrome/browser/tab_insertion/model/tab_insertion_browser_agent.h"
 #import "ios/chrome/browser/tabs/model/tab_helper_util.h"
-#import "ios/chrome/browser/ui/browser_view/browser_view_controller.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_controller.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_model.h"
 #import "ios/chrome/browser/ui/fullscreen/test/test_fullscreen_controller.h"
@@ -103,13 +103,12 @@
         ios::LocalOrSyncableBookmarkModelFactory::GetDefaultFactory());
     test_cbs_builder.AddTestingFactory(
         AuthenticationServiceFactory::GetInstance(),
-        base::BindRepeating(AuthenticationServiceFactory::GetDefaultFactory()));
+        AuthenticationServiceFactory::GetDefaultFactory());
     test_cbs_builder.AddTestingFactory(
         segmentation_platform::SegmentationPlatformServiceFactory::
             GetInstance(),
-        base::BindRepeating(
-            segmentation_platform::SegmentationPlatformServiceFactory::
-                GetDefaultFactory()));
+        segmentation_platform::SegmentationPlatformServiceFactory::
+            GetDefaultFactory());
     test_cbs_builder.AddTestingFactory(
         commerce::ShoppingServiceFactory::GetInstance(),
         base::BindRepeating(
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller+private.h b/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller+private.h
similarity index 80%
rename from ios/chrome/browser/ui/browser_view/browser_view_controller+private.h
rename to ios/chrome/browser/browser_view/ui_bundled/browser_view_controller+private.h
index bc9bfbf..1d40d0d 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller+private.h
+++ b/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller+private.h
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_BROWSER_VIEW_BROWSER_VIEW_CONTROLLER_PRIVATE_H_
-#define IOS_CHROME_BROWSER_UI_BROWSER_VIEW_BROWSER_VIEW_CONTROLLER_PRIVATE_H_
+#ifndef IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_BROWSER_VIEW_CONTROLLER_PRIVATE_H_
+#define IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_BROWSER_VIEW_CONTROLLER_PRIVATE_H_
 
-#import "ios/chrome/browser/ui/browser_view/browser_view_controller.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.h"
 
 #import "base/ios/block_types.h"
 
@@ -41,4 +41,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_BROWSER_VIEW_BROWSER_VIEW_CONTROLLER_PRIVATE_H_
+#endif  // IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_BROWSER_VIEW_CONTROLLER_PRIVATE_H_
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.h b/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.h
similarity index 94%
rename from ios/chrome/browser/ui/browser_view/browser_view_controller.h
rename to ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.h
index 2b34547..e137942 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.h
+++ b/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.h
@@ -2,18 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_BROWSER_VIEW_BROWSER_VIEW_CONTROLLER_H_
-#define IOS_CHROME_BROWSER_UI_BROWSER_VIEW_BROWSER_VIEW_CONTROLLER_H_
+#ifndef IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_BROWSER_VIEW_CONTROLLER_H_
+#define IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_BROWSER_VIEW_CONTROLLER_H_
 
 #import <UIKit/UIKit.h>
 
 #import "base/ios/block_types.h"
 #import "base/memory/raw_ptr.h"
 #import "base/memory/weak_ptr.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/tab_consumer.h"
 #import "ios/chrome/browser/contextual_panel/coordinator/contextual_sheet_presenter.h"
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
 #import "ios/chrome/browser/shared/public/commands/browser_commands.h"
-#import "ios/chrome/browser/ui/browser_view/tab_consumer.h"
 #import "ios/chrome/browser/ui/find_bar/find_bar_coordinator.h"
 #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_consumer.h"
 #import "ios/chrome/browser/ui/lens/lens_coordinator.h"
@@ -154,4 +154,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_BROWSER_VIEW_BROWSER_VIEW_CONTROLLER_H_
+#endif  // IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_BROWSER_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.mm
similarity index 99%
rename from ios/chrome/browser/ui/browser_view/browser_view_controller.mm
rename to ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.mm
index 5fde212..bbf05fd 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/browser_view/browser_view_controller.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.h"
 
 #import "base/apple/bundle_locations.h"
 #import "base/apple/foundation_util.h"
@@ -16,8 +16,13 @@
 #import "components/strings/grit/components_strings.h"
 #import "components/ukm/ios/ukm_url_recorder.h"
 #import "ios/chrome/browser/bookmarks/ui_bundled/home/bookmarks_coordinator.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_view_controller+private.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_view_visibility_consumer.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/key_commands_provider.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/safe_area_provider.h"
 #import "ios/chrome/browser/bubble/ui_bundled/bubble_presenter.h"
 #import "ios/chrome/browser/crash_report/model/crash_keys_helper.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/default_promo_non_modal_presentation_delegate.h"
 #import "ios/chrome/browser/discover_feed/model/feed_constants.h"
 #import "ios/chrome/browser/find_in_page/model/util.h"
 #import "ios/chrome/browser/intents/intents_donation_helper.h"
@@ -46,12 +51,7 @@
 #import "ios/chrome/browser/snapshots/model/snapshot_tab_helper.h"
 #import "ios/chrome/browser/ui/authentication/re_signin_infobar_delegate.h"
 #import "ios/chrome/browser/ui/browser_container/browser_container_view_controller.h"
-#import "ios/chrome/browser/ui/browser_view/browser_view_controller+private.h"
-#import "ios/chrome/browser/ui/browser_view/browser_view_visibility_consumer.h"
-#import "ios/chrome/browser/ui/browser_view/key_commands_provider.h"
-#import "ios/chrome/browser/ui/browser_view/safe_area_provider.h"
 #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h"
-#import "ios/chrome/browser/ui/default_promo/default_promo_non_modal_presentation_delegate.h"
 #import "ios/chrome/browser/ui/first_run/first_run_util.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_animator.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_ui_element.h"
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_egtest.mm b/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller_egtest.mm
similarity index 100%
rename from ios/chrome/browser/ui/browser_view/browser_view_controller_egtest.mm
rename to ios/chrome/browser/browser_view/ui_bundled/browser_view_controller_egtest.mm
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm b/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller_unittest.mm
similarity index 97%
rename from ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
rename to ios/chrome/browser/browser_view/ui_bundled/browser_view_controller_unittest.mm
index 1564dd8..92cecc9 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
+++ b/ios/chrome/browser/browser_view/ui_bundled/browser_view_controller_unittest.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/browser_view/browser_view_controller.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.h"
 
 #import <Foundation/Foundation.h>
 #import <PassKit/PassKit.h>
@@ -18,6 +18,11 @@
 #import "ios/chrome/browser/bookmarks/model/bookmark_model_factory.h"
 #import "ios/chrome/browser/bookmarks/model/local_or_syncable_bookmark_model_factory.h"
 #import "ios/chrome/browser/bookmarks/ui_bundled/home/bookmarks_coordinator.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_view_controller+private.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/key_commands_provider.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/safe_area_provider.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/tab_consumer.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/tab_events_mediator.h"
 #import "ios/chrome/browser/bubble/ui_bundled/bubble_presenter.h"
 #import "ios/chrome/browser/content_settings/model/host_content_settings_map_factory.h"
 #import "ios/chrome/browser/favicon/model/favicon_service_factory.h"
@@ -53,11 +58,6 @@
 #import "ios/chrome/browser/signin/model/fake_authentication_service_delegate.h"
 #import "ios/chrome/browser/tabs/model/tab_helper_util.h"
 #import "ios/chrome/browser/ui/browser_container/browser_container_view_controller.h"
-#import "ios/chrome/browser/ui/browser_view/browser_view_controller+private.h"
-#import "ios/chrome/browser/ui/browser_view/key_commands_provider.h"
-#import "ios/chrome/browser/ui/browser_view/safe_area_provider.h"
-#import "ios/chrome/browser/ui/browser_view/tab_consumer.h"
-#import "ios/chrome/browser/ui/browser_view/tab_events_mediator.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_controller.h"
 #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_commands.h"
 #import "ios/chrome/browser/ui/ntp/new_tab_page_component_factory.h"
@@ -129,9 +129,8 @@
     test_cbs_builder.AddTestingFactory(
         segmentation_platform::SegmentationPlatformServiceFactory::
             GetInstance(),
-        base::BindRepeating(
-            segmentation_platform::SegmentationPlatformServiceFactory::
-                GetDefaultFactory()));
+        segmentation_platform::SegmentationPlatformServiceFactory::
+            GetDefaultFactory());
 
     chrome_browser_state_ = test_cbs_builder.Build();
     AuthenticationServiceFactory::CreateAndInitializeForBrowserState(
@@ -355,7 +354,7 @@
   std::unique_ptr<web::WebState> CreateOffTheRecordWebState() {
     web::WebState::CreateParams params(
         chrome_browser_state_
-            ->CreateOffTheRecordBrowserStateWithTestingFactories({}));
+            ->CreateOffTheRecordBrowserStateWithTestingFactories());
     auto web_state = web::WebState::Create(params);
     AttachTabHelpers(web_state.get(), NO);
     return web_state;
diff --git a/ios/chrome/browser/browser_view/ui_bundled/browser_view_visibility_consumer.h b/ios/chrome/browser/browser_view/ui_bundled/browser_view_visibility_consumer.h
new file mode 100644
index 0000000..32a188f
--- /dev/null
+++ b/ios/chrome/browser/browser_view/ui_bundled/browser_view_visibility_consumer.h
@@ -0,0 +1,17 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_BROWSER_VIEW_VISIBILITY_CONSUMER_H_
+#define IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_BROWSER_VIEW_VISIBILITY_CONSUMER_H_
+
+/// Consumer protocol that gets notified when the browser view's visibility has
+/// changed.
+@protocol BrowserViewVisibilityConsumer
+
+/// Method that responds to browser view visibility changes.
+- (void)browserViewDidChangeVisibility;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_BROWSER_VIEW_VISIBILITY_CONSUMER_H_
diff --git a/ios/chrome/browser/ui/browser_view/key_commands_provider.h b/ios/chrome/browser/browser_view/ui_bundled/key_commands_provider.h
similarity index 86%
rename from ios/chrome/browser/ui/browser_view/key_commands_provider.h
rename to ios/chrome/browser/browser_view/ui_bundled/key_commands_provider.h
index caaee6d9..1b6a96c 100644
--- a/ios/chrome/browser/ui/browser_view/key_commands_provider.h
+++ b/ios/chrome/browser/browser_view/ui_bundled/key_commands_provider.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_BROWSER_VIEW_KEY_COMMANDS_PROVIDER_H_
-#define IOS_CHROME_BROWSER_UI_BROWSER_VIEW_KEY_COMMANDS_PROVIDER_H_
+#ifndef IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_KEY_COMMANDS_PROVIDER_H_
+#define IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_KEY_COMMANDS_PROVIDER_H_
 
 #import <UIKit/UIKit.h>
 
@@ -43,4 +43,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_BROWSER_VIEW_KEY_COMMANDS_PROVIDER_H_
+#endif  // IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_KEY_COMMANDS_PROVIDER_H_
diff --git a/ios/chrome/browser/ui/browser_view/key_commands_provider.mm b/ios/chrome/browser/browser_view/ui_bundled/key_commands_provider.mm
similarity index 99%
rename from ios/chrome/browser/ui/browser_view/key_commands_provider.mm
rename to ios/chrome/browser/browser_view/ui_bundled/key_commands_provider.mm
index df702224..f8281d90 100644
--- a/ios/chrome/browser/ui/browser_view/key_commands_provider.mm
+++ b/ios/chrome/browser/browser_view/ui_bundled/key_commands_provider.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/browser_view/key_commands_provider.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/key_commands_provider.h"
 
 #import <objc/runtime.h>
 
diff --git a/ios/chrome/browser/ui/browser_view/key_commands_provider_unittest.mm b/ios/chrome/browser/browser_view/ui_bundled/key_commands_provider_unittest.mm
similarity index 99%
rename from ios/chrome/browser/ui/browser_view/key_commands_provider_unittest.mm
rename to ios/chrome/browser/browser_view/ui_bundled/key_commands_provider_unittest.mm
index bd607f3..760ffb6 100644
--- a/ios/chrome/browser/ui/browser_view/key_commands_provider_unittest.mm
+++ b/ios/chrome/browser/browser_view/ui_bundled/key_commands_provider_unittest.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/browser_view/key_commands_provider.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/key_commands_provider.h"
 
 #import "base/memory/raw_ptr.h"
 #import "base/test/metrics/user_action_tester.h"
diff --git a/ios/chrome/browser/ui/browser_view/safe_area_provider.h b/ios/chrome/browser/browser_view/ui_bundled/safe_area_provider.h
similarity index 68%
rename from ios/chrome/browser/ui/browser_view/safe_area_provider.h
rename to ios/chrome/browser/browser_view/ui_bundled/safe_area_provider.h
index 21ac0688..4dd509f 100644
--- a/ios/chrome/browser/ui/browser_view/safe_area_provider.h
+++ b/ios/chrome/browser/browser_view/ui_bundled/safe_area_provider.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_BROWSER_VIEW_SAFE_AREA_PROVIDER_H_
-#define IOS_CHROME_BROWSER_UI_BROWSER_VIEW_SAFE_AREA_PROVIDER_H_
+#ifndef IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_SAFE_AREA_PROVIDER_H_
+#define IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_SAFE_AREA_PROVIDER_H_
 
 #import <UIKit/UIKit.h>
 
@@ -20,4 +20,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_BROWSER_VIEW_SAFE_AREA_PROVIDER_H_
+#endif  // IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_SAFE_AREA_PROVIDER_H_
diff --git a/ios/chrome/browser/ui/browser_view/safe_area_provider.mm b/ios/chrome/browser/browser_view/ui_bundled/safe_area_provider.mm
similarity index 93%
rename from ios/chrome/browser/ui/browser_view/safe_area_provider.mm
rename to ios/chrome/browser/browser_view/ui_bundled/safe_area_provider.mm
index c7c75bb..6969752 100644
--- a/ios/chrome/browser/ui/browser_view/safe_area_provider.mm
+++ b/ios/chrome/browser/browser_view/ui_bundled/safe_area_provider.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/browser_view/safe_area_provider.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/safe_area_provider.h"
 
 #import "base/memory/weak_ptr.h"
 #import "ios/chrome/app/application_delegate/app_state.h"
diff --git a/ios/chrome/browser/ui/browser_view/tab_consumer.h b/ios/chrome/browser/browser_view/ui_bundled/tab_consumer.h
similarity index 90%
rename from ios/chrome/browser/ui/browser_view/tab_consumer.h
rename to ios/chrome/browser/browser_view/ui_bundled/tab_consumer.h
index f7d4897..ca76b8f 100644
--- a/ios/chrome/browser/ui/browser_view/tab_consumer.h
+++ b/ios/chrome/browser/browser_view/ui_bundled/tab_consumer.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_BROWSER_VIEW_TAB_CONSUMER_H_
-#define IOS_CHROME_BROWSER_UI_BROWSER_VIEW_TAB_CONSUMER_H_
+#ifndef IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_TAB_CONSUMER_H_
+#define IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_TAB_CONSUMER_H_
 
 #import <Foundation/Foundation.h>
 
@@ -59,4 +59,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_BROWSER_VIEW_TAB_CONSUMER_H_
+#endif  // IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_TAB_CONSUMER_H_
diff --git a/ios/chrome/browser/ui/browser_view/tab_events_mediator.h b/ios/chrome/browser/browser_view/ui_bundled/tab_events_mediator.h
similarity index 89%
rename from ios/chrome/browser/ui/browser_view/tab_events_mediator.h
rename to ios/chrome/browser/browser_view/ui_bundled/tab_events_mediator.h
index 2be19b1..b442462 100644
--- a/ios/chrome/browser/ui/browser_view/tab_events_mediator.h
+++ b/ios/chrome/browser/browser_view/ui_bundled/tab_events_mediator.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_BROWSER_VIEW_TAB_EVENTS_MEDIATOR_H_
-#define IOS_CHROME_BROWSER_UI_BROWSER_VIEW_TAB_EVENTS_MEDIATOR_H_
+#ifndef IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_TAB_EVENTS_MEDIATOR_H_
+#define IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_TAB_EVENTS_MEDIATOR_H_
 
 #import <UIKit/UIKit.h>
 
@@ -49,4 +49,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_BROWSER_VIEW_TAB_EVENTS_MEDIATOR_H_
+#endif  // IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_TAB_EVENTS_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/browser_view/tab_events_mediator.mm b/ios/chrome/browser/browser_view/ui_bundled/tab_events_mediator.mm
similarity index 98%
rename from ios/chrome/browser/ui/browser_view/tab_events_mediator.mm
rename to ios/chrome/browser/browser_view/ui_bundled/tab_events_mediator.mm
index d6db356..86b81ce3 100644
--- a/ios/chrome/browser/ui/browser_view/tab_events_mediator.mm
+++ b/ios/chrome/browser/browser_view/ui_bundled/tab_events_mediator.mm
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/browser_view/tab_events_mediator.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/tab_events_mediator.h"
 
 #import "base/memory/raw_ptr.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/tab_consumer.h"
 #import "ios/chrome/browser/feature_engagement/model/tracker_util.h"
 #import "ios/chrome/browser/metrics/model/new_tab_page_uma.h"
 #import "ios/chrome/browser/ntp/model/new_tab_page_tab_helper.h"
@@ -14,7 +15,6 @@
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list_observer_bridge.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
 #import "ios/chrome/browser/snapshots/model/snapshot_tab_helper.h"
-#import "ios/chrome/browser/ui/browser_view/tab_consumer.h"
 #import "ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h"
 #import "ios/chrome/browser/ui/tabs/switch_to_tab_animation_view.h"
 #import "ios/chrome/browser/ui/toolbar/public/side_swipe_toolbar_snapshot_providing.h"
diff --git a/ios/chrome/browser/ui/browser_view/tab_lifecycle_mediator.h b/ios/chrome/browser/browser_view/ui_bundled/tab_lifecycle_mediator.h
similarity index 92%
rename from ios/chrome/browser/ui/browser_view/tab_lifecycle_mediator.h
rename to ios/chrome/browser/browser_view/ui_bundled/tab_lifecycle_mediator.h
index 89ead70..33bfca2 100644
--- a/ios/chrome/browser/ui/browser_view/tab_lifecycle_mediator.h
+++ b/ios/chrome/browser/browser_view/ui_bundled/tab_lifecycle_mediator.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_BROWSER_VIEW_TAB_LIFECYCLE_MEDIATOR_H_
-#define IOS_CHROME_BROWSER_UI_BROWSER_VIEW_TAB_LIFECYCLE_MEDIATOR_H_
+#ifndef IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_TAB_LIFECYCLE_MEDIATOR_H_
+#define IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_TAB_LIFECYCLE_MEDIATOR_H_
 
 #import <UIKit/UIKit.h>
 
@@ -71,4 +71,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_BROWSER_VIEW_TAB_LIFECYCLE_MEDIATOR_H_
+#endif  // IOS_CHROME_BROWSER_BROWSER_VIEW_UI_BUNDLED_TAB_LIFECYCLE_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/browser_view/tab_lifecycle_mediator.mm b/ios/chrome/browser/browser_view/ui_bundled/tab_lifecycle_mediator.mm
similarity index 98%
rename from ios/chrome/browser/ui/browser_view/tab_lifecycle_mediator.mm
rename to ios/chrome/browser/browser_view/ui_bundled/tab_lifecycle_mediator.mm
index 3ce05604..fcb2b3b 100644
--- a/ios/chrome/browser/ui/browser_view/tab_lifecycle_mediator.mm
+++ b/ios/chrome/browser/browser_view/ui_bundled/tab_lifecycle_mediator.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/browser_view/tab_lifecycle_mediator.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/tab_lifecycle_mediator.h"
 
 #import "ios/chrome/browser/app_launcher/model/app_launcher_tab_helper.h"
 #import "ios/chrome/browser/autofill/model/autofill_tab_helper.h"
diff --git a/ios/chrome/browser/ui/default_promo/BUILD.gn b/ios/chrome/browser/default_promo/ui_bundled/BUILD.gn
similarity index 96%
rename from ios/chrome/browser/ui/default_promo/BUILD.gn
rename to ios/chrome/browser/default_promo/ui_bundled/BUILD.gn
index e7da4af0..3b9d0738 100644
--- a/ios/chrome/browser/ui/default_promo/BUILD.gn
+++ b/ios/chrome/browser/default_promo/ui_bundled/BUILD.gn
@@ -2,7 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-source_set("default_promo") {
+source_set("coordinator") {
   sources = [
     "all_tabs_default_browser_promo_view_provider.h",
     "all_tabs_default_browser_promo_view_provider.mm",
@@ -27,7 +27,7 @@
     "//ios/chrome/browser/promos_manager/model:constants",
     "//ios/chrome/browser/promos_manager/model:types",
     "//ios/chrome/browser/shared/ui/elements",
-    "//ios/chrome/browser/ui/default_promo/resources",
+    "//ios/chrome/browser/default_promo/ui_bundled/resources",
     "//ios/chrome/browser/ui/promos_manager:promos",
     "//ios/chrome/common/ui/colors",
     "//ios/chrome/common/ui/confirmation_alert",
@@ -40,13 +40,13 @@
   frameworks = [ "UIKit.framework" ]
 }
 
-source_set("default_promo_ui") {
+source_set("ui") {
   sources = [
     "default_browser_promo_non_modal_coordinator.h",
     "default_browser_promo_non_modal_coordinator.mm",
   ]
   deps = [
-    ":default_promo",
+    ":coordinator",
     "//base",
     "//components/feature_engagement/public",
     "//ios/chrome/app/strings",
@@ -72,7 +72,7 @@
     "default_browser_instructions_view_unittest.mm",
   ]
   deps = [
-    ":default_promo",
+    ":coordinator",
     "//base/test:test_support",
     "//components/feature_engagement/public",
     "//components/feature_engagement/test:test_support",
diff --git a/ios/chrome/browser/default_promo/ui_bundled/DEPS b/ios/chrome/browser/default_promo/ui_bundled/DEPS
new file mode 100644
index 0000000..a386d0d
--- /dev/null
+++ b/ios/chrome/browser/default_promo/ui_bundled/DEPS
@@ -0,0 +1,7 @@
+include_rules = [
+  "+ios/chrome/browser/default_browser/model/utils.h",
+  "+ios/chrome/browser/feature_engagement/model/tracker_factory.h",
+  "+ios/chrome/browser/promos_manager/model",
+  "+ios/chrome/browser/ui/infobars",
+  "+ios/chrome/browser/ui/promos_manager",
+]
diff --git a/ios/chrome/browser/ui/default_promo/OWNERS b/ios/chrome/browser/default_promo/ui_bundled/OWNERS
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/OWNERS
rename to ios/chrome/browser/default_promo/ui_bundled/OWNERS
diff --git a/ios/chrome/browser/default_promo/ui_bundled/all_tabs_default_browser_promo_view_provider.h b/ios/chrome/browser/default_promo/ui_bundled/all_tabs_default_browser_promo_view_provider.h
new file mode 100644
index 0000000..8f9cb1e91
--- /dev/null
+++ b/ios/chrome/browser/default_promo/ui_bundled/all_tabs_default_browser_promo_view_provider.h
@@ -0,0 +1,15 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_ALL_TABS_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_ALL_TABS_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
+
+#import "ios/chrome/browser/default_promo/ui_bundled/base_default_browser_promo_view_provider.h"
+
+// Provider for displaying the All Tabs Default Browser Promo.
+@interface AllTabsDefaultBrowserPromoViewProvider
+    : BaseDefaultBrowserPromoViewProvider
+@end
+
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_ALL_TABS_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
diff --git a/ios/chrome/browser/ui/default_promo/all_tabs_default_browser_promo_view_provider.mm b/ios/chrome/browser/default_promo/ui_bundled/all_tabs_default_browser_promo_view_provider.mm
similarity index 91%
rename from ios/chrome/browser/ui/default_promo/all_tabs_default_browser_promo_view_provider.mm
rename to ios/chrome/browser/default_promo/ui_bundled/all_tabs_default_browser_promo_view_provider.mm
index 357fee9..2e4c07f 100644
--- a/ios/chrome/browser/ui/default_promo/all_tabs_default_browser_promo_view_provider.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/all_tabs_default_browser_promo_view_provider.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/all_tabs_default_browser_promo_view_provider.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/all_tabs_default_browser_promo_view_provider.h"
 
 #import "components/feature_engagement/public/feature_constants.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
diff --git a/ios/chrome/browser/ui/default_promo/base_default_browser_promo_view_provider.h b/ios/chrome/browser/default_promo/ui_bundled/base_default_browser_promo_view_provider.h
similarity index 79%
rename from ios/chrome/browser/ui/default_promo/base_default_browser_promo_view_provider.h
rename to ios/chrome/browser/default_promo/ui_bundled/base_default_browser_promo_view_provider.h
index 0b4a4f9..02c7e86 100644
--- a/ios/chrome/browser/ui/default_promo/base_default_browser_promo_view_provider.h
+++ b/ios/chrome/browser/default_promo/ui_bundled/base_default_browser_promo_view_provider.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_BASE_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_BASE_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_BASE_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_BASE_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
 
 #import "base/feature_list.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
@@ -38,4 +38,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_BASE_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_BASE_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
diff --git a/ios/chrome/browser/ui/default_promo/base_default_browser_promo_view_provider.mm b/ios/chrome/browser/default_promo/ui_bundled/base_default_browser_promo_view_provider.mm
similarity index 98%
rename from ios/chrome/browser/ui/default_promo/base_default_browser_promo_view_provider.mm
rename to ios/chrome/browser/default_promo/ui_bundled/base_default_browser_promo_view_provider.mm
index 99a8eb9..7d088ae 100644
--- a/ios/chrome/browser/ui/default_promo/base_default_browser_promo_view_provider.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/base_default_browser_promo_view_provider.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/base_default_browser_promo_view_provider.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/base_default_browser_promo_view_provider.h"
 
 #import "base/metrics/histogram_functions.h"
 #import "base/metrics/user_metrics.h"
diff --git a/ios/chrome/browser/ui/default_promo/base_default_browser_promo_view_provider_unittest.mm b/ios/chrome/browser/default_promo/ui_bundled/base_default_browser_promo_view_provider_unittest.mm
similarity index 96%
rename from ios/chrome/browser/ui/default_promo/base_default_browser_promo_view_provider_unittest.mm
rename to ios/chrome/browser/default_promo/ui_bundled/base_default_browser_promo_view_provider_unittest.mm
index a57fc44..9b1c3dc 100644
--- a/ios/chrome/browser/ui/default_promo/base_default_browser_promo_view_provider_unittest.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/base_default_browser_promo_view_provider_unittest.mm
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/base_default_browser_promo_view_provider.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/base_default_browser_promo_view_provider.h"
 
 #import "base/test/metrics/histogram_tester.h"
 #import "base/test/metrics/user_action_tester.h"
 #import "components/feature_engagement/public/feature_constants.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
 #import "ios/chrome/browser/default_browser/model/utils_test_support.h"
-#import "ios/chrome/browser/ui/default_promo/all_tabs_default_browser_promo_view_provider.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/all_tabs_default_browser_promo_view_provider.h"
 #import "ios/chrome/test/ios_chrome_scoped_testing_local_state.h"
 #import "testing/gtest_mac.h"
 #import "testing/platform_test.h"
diff --git a/ios/chrome/browser/ui/default_promo/default_browser_feature_engagement_unittest.mm b/ios/chrome/browser/default_promo/ui_bundled/default_browser_feature_engagement_unittest.mm
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/default_browser_feature_engagement_unittest.mm
rename to ios/chrome/browser/default_promo/ui_bundled/default_browser_feature_engagement_unittest.mm
diff --git a/ios/chrome/browser/ui/default_promo/default_browser_instructions_view.h b/ios/chrome/browser/default_promo/ui_bundled/default_browser_instructions_view.h
similarity index 78%
rename from ios/chrome/browser/ui/default_promo/default_browser_instructions_view.h
rename to ios/chrome/browser/default_promo/ui_bundled/default_browser_instructions_view.h
index d5fbe74..afdd6e2 100644
--- a/ios/chrome/browser/ui/default_promo/default_browser_instructions_view.h
+++ b/ios/chrome/browser/default_promo/ui_bundled/default_browser_instructions_view.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_DEFAULT_BROWSER_INSTRUCTIONS_VIEW_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_DEFAULT_BROWSER_INSTRUCTIONS_VIEW_H_
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_DEFAULT_BROWSER_INSTRUCTIONS_VIEW_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_DEFAULT_BROWSER_INSTRUCTIONS_VIEW_H_
 
 #import <UIKit/UIKit.h>
 
@@ -29,4 +29,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_DEFAULT_BROWSER_INSTRUCTIONS_VIEW_H_
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_DEFAULT_BROWSER_INSTRUCTIONS_VIEW_H_
diff --git a/ios/chrome/browser/ui/default_promo/default_browser_instructions_view.mm b/ios/chrome/browser/default_promo/ui_bundled/default_browser_instructions_view.mm
similarity index 98%
rename from ios/chrome/browser/ui/default_promo/default_browser_instructions_view.mm
rename to ios/chrome/browser/default_promo/ui_bundled/default_browser_instructions_view.mm
index 71d9d072..26f321a 100644
--- a/ios/chrome/browser/ui/default_promo/default_browser_instructions_view.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/default_browser_instructions_view.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/default_browser_instructions_view.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/default_browser_instructions_view.h"
 
 #import "base/i18n/rtl.h"
 #import "ios/chrome/browser/shared/ui/elements/instruction_view.h"
diff --git a/ios/chrome/browser/ui/default_promo/default_browser_instructions_view_unittest.mm b/ios/chrome/browser/default_promo/ui_bundled/default_browser_instructions_view_unittest.mm
similarity index 98%
rename from ios/chrome/browser/ui/default_promo/default_browser_instructions_view_unittest.mm
rename to ios/chrome/browser/default_promo/ui_bundled/default_browser_instructions_view_unittest.mm
index bd47e2cd..82477af 100644
--- a/ios/chrome/browser/ui/default_promo/default_browser_instructions_view_unittest.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/default_browser_instructions_view_unittest.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/default_browser_instructions_view.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/default_browser_instructions_view.h"
 
 #import "ios/chrome/common/ui/confirmation_alert/constants.h"
 #import "ios/public/provider/chrome/browser/lottie/lottie_animation_api.h"
diff --git a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_commands.h b/ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_commands.h
similarity index 64%
rename from ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_commands.h
rename to ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_commands.h
index 79e361e67..a3c49dd 100644
--- a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_commands.h
+++ b/ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_commands.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_DEFAULT_BROWSER_PROMO_NON_MODAL_COMMANDS_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_DEFAULT_BROWSER_PROMO_NON_MODAL_COMMANDS_H_
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_DEFAULT_BROWSER_PROMO_NON_MODAL_COMMANDS_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_DEFAULT_BROWSER_PROMO_NON_MODAL_COMMANDS_H_
 
 @protocol DefaultBrowserPromoNonModalCommands
 
@@ -19,4 +19,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_DEFAULT_BROWSER_PROMO_NON_MODAL_COMMANDS_H_
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_DEFAULT_BROWSER_PROMO_NON_MODAL_COMMANDS_H_
diff --git a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_coordinator.h b/ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_coordinator.h
similarity index 72%
rename from ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_coordinator.h
rename to ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_coordinator.h
index ab272ff..31340cd9 100644
--- a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_coordinator.h
+++ b/ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_coordinator.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_DEFAULT_BROWSER_PROMO_NON_MODAL_COORDINATOR_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_DEFAULT_BROWSER_PROMO_NON_MODAL_COORDINATOR_H_
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_DEFAULT_BROWSER_PROMO_NON_MODAL_COORDINATOR_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_DEFAULT_BROWSER_PROMO_NON_MODAL_COORDINATOR_H_
 
 #import "ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.h"
 
@@ -21,4 +21,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_DEFAULT_BROWSER_PROMO_NON_MODAL_COORDINATOR_H_
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_DEFAULT_BROWSER_PROMO_NON_MODAL_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_coordinator.mm b/ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_coordinator.mm
similarity index 95%
rename from ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_coordinator.mm
rename to ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_coordinator.mm
index 2656075..d55ed7d 100644
--- a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_coordinator.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_coordinator.mm
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_coordinator.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_coordinator.h"
 
 #import "base/notreached.h"
 #import "components/feature_engagement/public/tracker.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_commands.h"
 #import "ios/chrome/browser/feature_engagement/model/tracker_factory.h"
 #import "ios/chrome/browser/shared/coordinator/default_browser_promo/non_modal_default_browser_promo_scheduler_scene_agent.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
 #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
-#import "ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_commands.h"
 #import "ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.h"
 #import "ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator+subclassing.h"
 #import "ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator_implementation.h"
diff --git a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_egtest.mm b/ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_egtest.mm
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_egtest.mm
rename to ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_egtest.mm
diff --git a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_metrics_util.h b/ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_metrics_util.h
similarity index 76%
rename from ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_metrics_util.h
rename to ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_metrics_util.h
index 85b50b64..e42ed44 100644
--- a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_metrics_util.h
+++ b/ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_metrics_util.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_DEFAULT_BROWSER_PROMO_NON_MODAL_METRICS_UTIL_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_DEFAULT_BROWSER_PROMO_NON_MODAL_METRICS_UTIL_H_
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_DEFAULT_BROWSER_PROMO_NON_MODAL_METRICS_UTIL_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_DEFAULT_BROWSER_PROMO_NON_MODAL_METRICS_UTIL_H_
 
 #import "base/time/time.h"
 
@@ -36,4 +36,4 @@
 // Logs the time a non modal promo was on screen.
 void LogNonModalTimeOnScreen(base::TimeTicks initial_time);
 
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_DEFAULT_BROWSER_PROMO_NON_MODAL_METRICS_UTIL_H_
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_DEFAULT_BROWSER_PROMO_NON_MODAL_METRICS_UTIL_H_
diff --git a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_metrics_util.mm b/ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_metrics_util.mm
similarity index 96%
rename from ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_metrics_util.mm
rename to ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_metrics_util.mm
index 2b5453ba..396af42 100644
--- a/ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_metrics_util.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_metrics_util.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_metrics_util.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_metrics_util.h"
 
 #import "base/metrics/histogram_functions.h"
 #import "base/metrics/user_metrics.h"
diff --git a/ios/chrome/browser/ui/default_promo/default_promo_non_modal_presentation_delegate.h b/ios/chrome/browser/default_promo/ui_bundled/default_promo_non_modal_presentation_delegate.h
similarity index 66%
rename from ios/chrome/browser/ui/default_promo/default_promo_non_modal_presentation_delegate.h
rename to ios/chrome/browser/default_promo/ui_bundled/default_promo_non_modal_presentation_delegate.h
index e4dc0f4..503cd4d9 100644
--- a/ios/chrome/browser/ui/default_promo/default_promo_non_modal_presentation_delegate.h
+++ b/ios/chrome/browser/default_promo/ui_bundled/default_promo_non_modal_presentation_delegate.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_DEFAULT_PROMO_NON_MODAL_PRESENTATION_DELEGATE_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_DEFAULT_PROMO_NON_MODAL_PRESENTATION_DELEGATE_H_
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_DEFAULT_PROMO_NON_MODAL_PRESENTATION_DELEGATE_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_DEFAULT_PROMO_NON_MODAL_PRESENTATION_DELEGATE_H_
 
 // Delegate used for presenting and dismissing the non-modal default browser
 // promo.
@@ -19,4 +19,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_DEFAULT_PROMO_NON_MODAL_PRESENTATION_DELEGATE_H_
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_DEFAULT_PROMO_NON_MODAL_PRESENTATION_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/default_promo/generic/BUILD.gn b/ios/chrome/browser/default_promo/ui_bundled/generic/BUILD.gn
similarity index 95%
rename from ios/chrome/browser/ui/default_promo/generic/BUILD.gn
rename to ios/chrome/browser/default_promo/ui_bundled/generic/BUILD.gn
index 97f08cc..63a4e953 100644
--- a/ios/chrome/browser/ui/default_promo/generic/BUILD.gn
+++ b/ios/chrome/browser/default_promo/ui_bundled/generic/BUILD.gn
@@ -16,6 +16,7 @@
   deps = [
     "//components/feature_engagement/public",
     "//ios/chrome/browser/default_browser/model:utils",
+    "//ios/chrome/browser/default_promo/ui_bundled:coordinator",
     "//ios/chrome/browser/feature_engagement/model",
     "//ios/chrome/browser/promos_manager/model",
     "//ios/chrome/browser/promos_manager/model:factory",
@@ -23,7 +24,6 @@
     "//ios/chrome/browser/shared/model/browser",
     "//ios/chrome/browser/shared/model/browser_state",
     "//ios/chrome/browser/shared/public/commands",
-    "//ios/chrome/browser/ui/default_promo",
     "//ios/chrome/browser/ui/promos_manager:promos",
     "//ios/chrome/common/ui/confirmation_alert",
   ]
diff --git a/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_commands.h b/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_commands.h
new file mode 100644
index 0000000..a2f42de
--- /dev/null
+++ b/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_commands.h
@@ -0,0 +1,15 @@
+// Copyright 2020 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_COMMANDS_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_COMMANDS_H_
+
+@protocol DefaultBrowserGenericPromoCommands <NSObject>
+
+// Command the promo to be hidden.
+- (void)hidePromo;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_COMMANDS_H_
diff --git a/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_coordinator.h b/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_coordinator.h
similarity index 66%
rename from ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_coordinator.h
rename to ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_coordinator.h
index 7a59c94c..1b1ceac 100644
--- a/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_coordinator.h
+++ b/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_coordinator.h
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_COORDINATOR_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_COORDINATOR_H_
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_COORDINATOR_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_COORDINATOR_H_
 
 #import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h"
-#import "ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_commands.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_commands.h"
 
 @protocol PromosManagerUIHandler;
 
@@ -24,4 +24,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_COORDINATOR_H_
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_coordinator.mm b/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_coordinator.mm
similarity index 94%
rename from ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_coordinator.mm
rename to ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_coordinator.mm
index e520faf..6035498 100644
--- a/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_coordinator.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_coordinator.mm
@@ -2,22 +2,22 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_coordinator.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_coordinator.h"
 
 #import "base/metrics/histogram_functions.h"
 #import "base/metrics/user_metrics.h"
 #import "components/feature_engagement/public/event_constants.h"
 #import "components/feature_engagement/public/tracker.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_commands.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_mediator.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_view_controller.h"
 #import "ios/chrome/browser/feature_engagement/model/tracker_factory.h"
 #import "ios/chrome/browser/promos_manager/model/promos_manager.h"
 #import "ios/chrome/browser/promos_manager/model/promos_manager_factory.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
-#import "ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_commands.h"
-#import "ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_mediator.h"
-#import "ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_view_controller.h"
 #import "ios/chrome/browser/ui/promos_manager/promos_manager_ui_handler.h"
 #import "ios/chrome/common/ui/confirmation_alert/confirmation_alert_action_handler.h"
 
diff --git a/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_coordinator_unittest.mm b/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_coordinator_unittest.mm
similarity index 97%
rename from ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_coordinator_unittest.mm
rename to ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_coordinator_unittest.mm
index 860abc0..eb21fed 100644
--- a/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_coordinator_unittest.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_coordinator_unittest.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_coordinator.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_coordinator.h"
 
 #import "base/apple/foundation_util.h"
 #import "base/memory/raw_ptr.h"
@@ -13,10 +13,10 @@
 #import "components/feature_engagement/public/event_constants.h"
 #import "components/feature_engagement/public/feature_constants.h"
 #import "components/feature_engagement/test/mock_tracker.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_view_controller.h"
 #import "ios/chrome/browser/feature_engagement/model/tracker_factory.h"
 #import "ios/chrome/browser/shared/model/browser/test/test_browser.h"
 #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
-#import "ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_view_controller.h"
 #import "ios/chrome/test/ios_chrome_scoped_testing_local_state.h"
 #import "ios/chrome/test/scoped_key_window.h"
 #import "testing/gtest_mac.h"
diff --git a/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_mediator.h b/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_mediator.h
new file mode 100644
index 0000000..5528c8a
--- /dev/null
+++ b/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_mediator.h
@@ -0,0 +1,18 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_MEDIATOR_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_MEDIATOR_H_
+
+#import <UIKit/UIKit.h>
+
+// The mediator for the generic default browser promo.
+@interface DefaultBrowserGenericPromoMediator : NSObject
+
+// Handles user tap on primary action.
+- (void)didTapPrimaryActionButton;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_mediator.mm b/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_mediator.mm
similarity index 84%
rename from ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_mediator.mm
rename to ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_mediator.mm
index 1d6dc52..9ac90f32 100644
--- a/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_mediator.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_mediator.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_mediator.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_mediator.h"
 
 @implementation DefaultBrowserGenericPromoMediator
 
diff --git a/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_view_controller.h b/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_view_controller.h
similarity index 66%
rename from ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_view_controller.h
rename to ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_view_controller.h
index b7d85a70..861e91e 100644
--- a/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_view_controller.h
+++ b/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_view_controller.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_VIEW_CONTROLLER_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_VIEW_CONTROLLER_H_
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_VIEW_CONTROLLER_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_VIEW_CONTROLLER_H_
 
 #import <UIKit/UIKit.h>
 
@@ -20,4 +20,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_VIEW_CONTROLLER_H_
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_view_controller.mm b/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_view_controller.mm
similarity index 71%
rename from ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_view_controller.mm
rename to ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_view_controller.mm
index 53ffdb24..81e51905 100644
--- a/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_view_controller.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_view_controller.mm
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_view_controller.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/generic/default_browser_generic_promo_view_controller.h"
 
-#import "ios/chrome/browser/ui/default_promo/default_browser_instructions_view.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/default_browser_instructions_view.h"
 
 @implementation DefaultBrowserGenericPromoViewController
 
diff --git a/ios/chrome/browser/default_promo/ui_bundled/made_for_ios_default_browser_promo_view_provider.h b/ios/chrome/browser/default_promo/ui_bundled/made_for_ios_default_browser_promo_view_provider.h
new file mode 100644
index 0000000..dcbfd48
--- /dev/null
+++ b/ios/chrome/browser/default_promo/ui_bundled/made_for_ios_default_browser_promo_view_provider.h
@@ -0,0 +1,15 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_MADE_FOR_IOS_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_MADE_FOR_IOS_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
+
+#import "ios/chrome/browser/default_promo/ui_bundled/base_default_browser_promo_view_provider.h"
+
+// Provider for displaying the Made For iOS Default Browser Promo.
+@interface MadeForIOSDefaultBrowserPromoViewProvider
+    : BaseDefaultBrowserPromoViewProvider
+@end
+
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_MADE_FOR_IOS_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
diff --git a/ios/chrome/browser/ui/default_promo/made_for_ios_default_browser_promo_view_provider.mm b/ios/chrome/browser/default_promo/ui_bundled/made_for_ios_default_browser_promo_view_provider.mm
similarity index 93%
rename from ios/chrome/browser/ui/default_promo/made_for_ios_default_browser_promo_view_provider.mm
rename to ios/chrome/browser/default_promo/ui_bundled/made_for_ios_default_browser_promo_view_provider.mm
index 67251f9..3c69de6 100644
--- a/ios/chrome/browser/ui/default_promo/made_for_ios_default_browser_promo_view_provider.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/made_for_ios_default_browser_promo_view_provider.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/made_for_ios_default_browser_promo_view_provider.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/made_for_ios_default_browser_promo_view_provider.h"
 
 #import "components/feature_engagement/public/feature_constants.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
diff --git a/ios/chrome/browser/ui/default_promo/post_default_abandonment/BUILD.gn b/ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/BUILD.gn
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/post_default_abandonment/BUILD.gn
rename to ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/BUILD.gn
diff --git a/ios/chrome/browser/ui/default_promo/post_default_abandonment/features.h b/ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/features.h
similarity index 83%
rename from ios/chrome/browser/ui/default_promo/post_default_abandonment/features.h
rename to ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/features.h
index b0a156a..5635edf9 100644
--- a/ios/chrome/browser/ui/default_promo/post_default_abandonment/features.h
+++ b/ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/features.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_POST_DEFAULT_ABANDONMENT_FEATURES_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_POST_DEFAULT_ABANDONMENT_FEATURES_H_
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_POST_DEFAULT_ABANDONMENT_FEATURES_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_POST_DEFAULT_ABANDONMENT_FEATURES_H_
 
 #import "base/feature_list.h"
 
@@ -31,4 +31,4 @@
 // abandonment feature.
 bool IsEligibleForPostDefaultAbandonmentPromo();
 
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_POST_DEFAULT_ABANDONMENT_FEATURES_H_
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_POST_DEFAULT_ABANDONMENT_FEATURES_H_
diff --git a/ios/chrome/browser/ui/default_promo/post_default_abandonment/features.mm b/ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/features.mm
similarity index 92%
rename from ios/chrome/browser/ui/default_promo/post_default_abandonment/features.mm
rename to ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/features.mm
index 6dfa12f..42aebf6 100644
--- a/ios/chrome/browser/ui/default_promo/post_default_abandonment/features.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/features.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/post_default_abandonment/features.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/features.h"
 
 #import "ios/chrome/browser/default_browser/model/utils.h"
 
diff --git a/ios/chrome/browser/ui/default_promo/post_default_abandonment/metrics.h b/ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/metrics.h
similarity index 70%
rename from ios/chrome/browser/ui/default_promo/post_default_abandonment/metrics.h
rename to ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/metrics.h
index fd28946..3aa3834 100644
--- a/ios/chrome/browser/ui/default_promo/post_default_abandonment/metrics.h
+++ b/ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/metrics.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_POST_DEFAULT_ABANDONMENT_METRICS_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_POST_DEFAULT_ABANDONMENT_METRICS_H_
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_POST_DEFAULT_ABANDONMENT_METRICS_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_POST_DEFAULT_ABANDONMENT_METRICS_H_
 
 namespace post_default_abandonment {
 
@@ -21,4 +21,4 @@
 
 }  // namespace post_default_abandonment
 
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_POST_DEFAULT_ABANDONMENT_METRICS_H_
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_POST_DEFAULT_ABANDONMENT_METRICS_H_
diff --git a/ios/chrome/browser/ui/default_promo/post_default_abandonment/metrics.mm b/ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/metrics.mm
similarity index 85%
rename from ios/chrome/browser/ui/default_promo/post_default_abandonment/metrics.mm
rename to ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/metrics.mm
index a6adf47..b75ee4a 100644
--- a/ios/chrome/browser/ui/default_promo/post_default_abandonment/metrics.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/metrics.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/post_default_abandonment/metrics.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/metrics.h"
 
 #import "base/metrics/histogram_functions.h"
 #import "base/metrics/user_metrics.h"
diff --git a/ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/post_default_abandonment_promo_provider.h b/ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/post_default_abandonment_promo_provider.h
new file mode 100644
index 0000000..4065ba1
--- /dev/null
+++ b/ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/post_default_abandonment_promo_provider.h
@@ -0,0 +1,17 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_POST_DEFAULT_ABANDONMENT_POST_DEFAULT_ABANDONMENT_PROMO_PROVIDER_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_POST_DEFAULT_ABANDONMENT_POST_DEFAULT_ABANDONMENT_PROMO_PROVIDER_H_
+
+#import "ios/chrome/browser/shared/public/commands/promos_manager_commands.h"
+#import "ios/chrome/browser/ui/promos_manager/standard_promo_alert_provider.h"
+
+// Provider for displaying the post-default browser abandonment alert.
+@interface PostDefaultBrowserAbandonmentPromoProvider
+    : NSObject <StandardPromoAlertProvider>
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_POST_DEFAULT_ABANDONMENT_POST_DEFAULT_ABANDONMENT_PROMO_PROVIDER_H_
diff --git a/ios/chrome/browser/ui/default_promo/post_default_abandonment/post_default_abandonment_promo_provider.mm b/ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/post_default_abandonment_promo_provider.mm
similarity index 90%
rename from ios/chrome/browser/ui/default_promo/post_default_abandonment/post_default_abandonment_promo_provider.mm
rename to ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/post_default_abandonment_promo_provider.mm
index 26f8c738..000fe28 100644
--- a/ios/chrome/browser/ui/default_promo/post_default_abandonment/post_default_abandonment_promo_provider.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/post_default_abandonment_promo_provider.mm
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/post_default_abandonment/post_default_abandonment_promo_provider.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/post_default_abandonment_promo_provider.h"
 
 #import "components/feature_engagement/public/feature_constants.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/metrics.h"
 #import "ios/chrome/browser/promos_manager/model/promo_config.h"
-#import "ios/chrome/browser/ui/default_promo/post_default_abandonment/metrics.h"
 #import "ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h"
 #import "ios/chrome/grit/ios_branded_strings.h"
 #import "ios/chrome/grit/ios_strings.h"
diff --git a/ios/chrome/browser/ui/default_promo/post_restore/BUILD.gn b/ios/chrome/browser/default_promo/ui_bundled/post_restore/BUILD.gn
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/post_restore/BUILD.gn
rename to ios/chrome/browser/default_promo/ui_bundled/post_restore/BUILD.gn
diff --git a/ios/chrome/browser/ui/default_promo/post_restore/metrics.h b/ios/chrome/browser/default_promo/ui_bundled/post_restore/metrics.h
similarity index 78%
rename from ios/chrome/browser/ui/default_promo/post_restore/metrics.h
rename to ios/chrome/browser/default_promo/ui_bundled/post_restore/metrics.h
index b992187..eeb1f7a 100644
--- a/ios/chrome/browser/ui/default_promo/post_restore/metrics.h
+++ b/ios/chrome/browser/default_promo/ui_bundled/post_restore/metrics.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_POST_RESTORE_METRICS_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_POST_RESTORE_METRICS_H_
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_POST_RESTORE_METRICS_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_POST_RESTORE_METRICS_H_
 
 namespace post_restore_default_browser {
 
@@ -27,4 +27,4 @@
 
 }  // namespace post_restore_default_browser
 
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_POST_RESTORE_METRICS_H_
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_POST_RESTORE_METRICS_H_
diff --git a/ios/chrome/browser/ui/default_promo/post_restore/metrics.mm b/ios/chrome/browser/default_promo/ui_bundled/post_restore/metrics.mm
similarity index 84%
rename from ios/chrome/browser/ui/default_promo/post_restore/metrics.mm
rename to ios/chrome/browser/default_promo/ui_bundled/post_restore/metrics.mm
index 0a2e5ad..1aefde9 100644
--- a/ios/chrome/browser/ui/default_promo/post_restore/metrics.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/post_restore/metrics.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/post_restore/metrics.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/post_restore/metrics.h"
 
 namespace post_restore_default_browser {
 
diff --git a/ios/chrome/browser/ui/default_promo/post_restore/post_restore_default_browser_egtest.mm b/ios/chrome/browser/default_promo/ui_bundled/post_restore/post_restore_default_browser_egtest.mm
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/post_restore/post_restore_default_browser_egtest.mm
rename to ios/chrome/browser/default_promo/ui_bundled/post_restore/post_restore_default_browser_egtest.mm
diff --git a/ios/chrome/browser/ui/default_promo/post_restore/post_restore_default_browser_promo_provider.h b/ios/chrome/browser/default_promo/ui_bundled/post_restore/post_restore_default_browser_promo_provider.h
similarity index 70%
rename from ios/chrome/browser/ui/default_promo/post_restore/post_restore_default_browser_promo_provider.h
rename to ios/chrome/browser/default_promo/ui_bundled/post_restore/post_restore_default_browser_promo_provider.h
index 4b17cf5..cc371e099 100644
--- a/ios/chrome/browser/ui/default_promo/post_restore/post_restore_default_browser_promo_provider.h
+++ b/ios/chrome/browser/default_promo/ui_bundled/post_restore/post_restore_default_browser_promo_provider.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_POST_RESTORE_POST_RESTORE_DEFAULT_BROWSER_PROMO_PROVIDER_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_POST_RESTORE_POST_RESTORE_DEFAULT_BROWSER_PROMO_PROVIDER_H_
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_POST_RESTORE_POST_RESTORE_DEFAULT_BROWSER_PROMO_PROVIDER_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_POST_RESTORE_POST_RESTORE_DEFAULT_BROWSER_PROMO_PROVIDER_H_
 
 #import "ios/chrome/browser/shared/public/commands/promos_manager_commands.h"
 #import "ios/chrome/browser/ui/promos_manager/standard_promo_alert_provider.h"
@@ -22,4 +22,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_POST_RESTORE_POST_RESTORE_DEFAULT_BROWSER_PROMO_PROVIDER_H_
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_POST_RESTORE_POST_RESTORE_DEFAULT_BROWSER_PROMO_PROVIDER_H_
diff --git a/ios/chrome/browser/ui/default_promo/post_restore/post_restore_default_browser_promo_provider.mm b/ios/chrome/browser/default_promo/ui_bundled/post_restore/post_restore_default_browser_promo_provider.mm
similarity index 93%
rename from ios/chrome/browser/ui/default_promo/post_restore/post_restore_default_browser_promo_provider.mm
rename to ios/chrome/browser/default_promo/ui_bundled/post_restore/post_restore_default_browser_promo_provider.mm
index 9d71e5a..4a290831 100644
--- a/ios/chrome/browser/ui/default_promo/post_restore/post_restore_default_browser_promo_provider.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/post_restore/post_restore_default_browser_promo_provider.mm
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/post_restore/post_restore_default_browser_promo_provider.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/post_restore/post_restore_default_browser_promo_provider.h"
 
 #import "base/metrics/histogram_functions.h"
 #import "base/metrics/user_metrics.h"
 #import "base/metrics/user_metrics_action.h"
 #import "components/feature_engagement/public/feature_constants.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/post_restore/metrics.h"
 #import "ios/chrome/browser/promos_manager/model/promo_config.h"
-#import "ios/chrome/browser/ui/default_promo/post_restore/metrics.h"
 #import "ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h"
 #import "ios/chrome/grit/ios_branded_strings.h"
 #import "ios/chrome/grit/ios_strings.h"
diff --git a/ios/chrome/browser/ui/default_promo/promo_handler/BUILD.gn b/ios/chrome/browser/default_promo/ui_bundled/promo_handler/BUILD.gn
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/promo_handler/BUILD.gn
rename to ios/chrome/browser/default_promo/ui_bundled/promo_handler/BUILD.gn
diff --git a/ios/chrome/browser/ui/default_promo/promo_handler/default_browser_promo_display_handler.h b/ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_promo_display_handler.h
similarity index 64%
rename from ios/chrome/browser/ui/default_promo/promo_handler/default_browser_promo_display_handler.h
rename to ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_promo_display_handler.h
index f77d6c9..019f2f1 100644
--- a/ios/chrome/browser/ui/default_promo/promo_handler/default_browser_promo_display_handler.h
+++ b/ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_promo_display_handler.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_PROMO_HANDLER_DEFAULT_BROWSER_PROMO_DISPLAY_HANDLER_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_PROMO_HANDLER_DEFAULT_BROWSER_PROMO_DISPLAY_HANDLER_H_
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_PROMO_HANDLER_DEFAULT_BROWSER_PROMO_DISPLAY_HANDLER_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_PROMO_HANDLER_DEFAULT_BROWSER_PROMO_DISPLAY_HANDLER_H_
 
 #import "ios/chrome/browser/ui/promos_manager/standard_promo_display_handler.h"
 
@@ -19,4 +19,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_PROMO_HANDLER_DEFAULT_BROWSER_PROMO_DISPLAY_HANDLER_H_
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_PROMO_HANDLER_DEFAULT_BROWSER_PROMO_DISPLAY_HANDLER_H_
diff --git a/ios/chrome/browser/ui/default_promo/promo_handler/default_browser_promo_display_handler.mm b/ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_promo_display_handler.mm
similarity index 87%
rename from ios/chrome/browser/ui/default_promo/promo_handler/default_browser_promo_display_handler.mm
rename to ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_promo_display_handler.mm
index 0ec5093..1e83dbb2 100644
--- a/ios/chrome/browser/ui/default_promo/promo_handler/default_browser_promo_display_handler.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_promo_display_handler.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/promo_handler/default_browser_promo_display_handler.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_promo_display_handler.h"
 
 #import "base/check.h"
 #import "base/metrics/user_metrics.h"
diff --git a/ios/chrome/browser/ui/default_promo/promo_handler/default_browser_remind_me_later_promo_display_handler.h b/ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_remind_me_later_promo_display_handler.h
similarity index 63%
rename from ios/chrome/browser/ui/default_promo/promo_handler/default_browser_remind_me_later_promo_display_handler.h
rename to ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_remind_me_later_promo_display_handler.h
index d77de57..5d922eb8 100644
--- a/ios/chrome/browser/ui/default_promo/promo_handler/default_browser_remind_me_later_promo_display_handler.h
+++ b/ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_remind_me_later_promo_display_handler.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_PROMO_HANDLER_DEFAULT_BROWSER_REMIND_ME_LATER_PROMO_DISPLAY_HANDLER_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_PROMO_HANDLER_DEFAULT_BROWSER_REMIND_ME_LATER_PROMO_DISPLAY_HANDLER_H_
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_PROMO_HANDLER_DEFAULT_BROWSER_REMIND_ME_LATER_PROMO_DISPLAY_HANDLER_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_PROMO_HANDLER_DEFAULT_BROWSER_REMIND_ME_LATER_PROMO_DISPLAY_HANDLER_H_
 
 #import "ios/chrome/browser/ui/promos_manager/standard_promo_display_handler.h"
 
@@ -18,4 +18,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_PROMO_HANDLER_DEFAULT_BROWSER_REMIND_ME_LATER_PROMO_DISPLAY_HANDLER_H_
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_PROMO_HANDLER_DEFAULT_BROWSER_REMIND_ME_LATER_PROMO_DISPLAY_HANDLER_H_
diff --git a/ios/chrome/browser/ui/default_promo/promo_handler/default_browser_remind_me_later_promo_display_handler.mm b/ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_remind_me_later_promo_display_handler.mm
similarity index 86%
rename from ios/chrome/browser/ui/default_promo/promo_handler/default_browser_remind_me_later_promo_display_handler.mm
rename to ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_remind_me_later_promo_display_handler.mm
index 5ceb5b7..ad570e8 100644
--- a/ios/chrome/browser/ui/default_promo/promo_handler/default_browser_remind_me_later_promo_display_handler.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_remind_me_later_promo_display_handler.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/promo_handler/default_browser_remind_me_later_promo_display_handler.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_remind_me_later_promo_display_handler.h"
 
 #import "base/check.h"
 #import "base/metrics/user_metrics.h"
diff --git a/ios/chrome/browser/ui/default_promo/promo_handler/default_browser_remind_me_later_promo_display_handler_unittest.mm b/ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_remind_me_later_promo_display_handler_unittest.mm
similarity index 94%
rename from ios/chrome/browser/ui/default_promo/promo_handler/default_browser_remind_me_later_promo_display_handler_unittest.mm
rename to ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_remind_me_later_promo_display_handler_unittest.mm
index d1a2fae..d3274f2 100644
--- a/ios/chrome/browser/ui/default_promo/promo_handler/default_browser_remind_me_later_promo_display_handler_unittest.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_remind_me_later_promo_display_handler_unittest.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/promo_handler/default_browser_remind_me_later_promo_display_handler.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_remind_me_later_promo_display_handler.h"
 
 #import "components/feature_engagement/public/feature_constants.h"
 #import "ios/chrome/browser/promos_manager/model/constants.h"
diff --git a/ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/Contents.json b/ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/Contents.json
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/Contents.json
rename to ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/Contents.json
diff --git a/ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/all_your_tabs.imageset/Contents.json b/ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/all_your_tabs.imageset/Contents.json
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/all_your_tabs.imageset/Contents.json
rename to ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/all_your_tabs.imageset/Contents.json
diff --git a/ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/all_your_tabs.imageset/all_your_tabs.png b/ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/all_your_tabs.imageset/all_your_tabs.png
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/all_your_tabs.imageset/all_your_tabs.png
rename to ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/all_your_tabs.imageset/all_your_tabs.png
Binary files differ
diff --git a/ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/all_your_tabs.imageset/all_your_tabs@2x.png b/ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/all_your_tabs.imageset/all_your_tabs@2x.png
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/all_your_tabs.imageset/all_your_tabs@2x.png
rename to ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/all_your_tabs.imageset/all_your_tabs@2x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/all_your_tabs.imageset/all_your_tabs@3x.png b/ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/all_your_tabs.imageset/all_your_tabs@3x.png
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/all_your_tabs.imageset/all_your_tabs@3x.png
rename to ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/all_your_tabs.imageset/all_your_tabs@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/default_browser_illustration.imageset/Contents.json b/ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/default_browser_illustration.imageset/Contents.json
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/default_browser_illustration.imageset/Contents.json
rename to ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/default_browser_illustration.imageset/Contents.json
diff --git a/ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/default_browser_illustration.imageset/default_browser_dark@2x.png b/ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/default_browser_illustration.imageset/default_browser_dark@2x.png
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/default_browser_illustration.imageset/default_browser_dark@2x.png
rename to ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/default_browser_illustration.imageset/default_browser_dark@2x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/default_browser_illustration.imageset/default_browser_dark@3x.png b/ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/default_browser_illustration.imageset/default_browser_dark@3x.png
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/default_browser_illustration.imageset/default_browser_dark@3x.png
rename to ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/default_browser_illustration.imageset/default_browser_dark@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/default_browser_illustration.imageset/default_browser_light@2x.png b/ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/default_browser_illustration.imageset/default_browser_light@2x.png
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/default_browser_illustration.imageset/default_browser_light@2x.png
rename to ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/default_browser_illustration.imageset/default_browser_light@2x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/default_browser_illustration.imageset/default_browser_light@3x.png b/ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/default_browser_illustration.imageset/default_browser_light@3x.png
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/resources/Assets.xcassets/default_browser_illustration.imageset/default_browser_light@3x.png
rename to ios/chrome/browser/default_promo/ui_bundled/resources/Assets.xcassets/default_browser_illustration.imageset/default_browser_light@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/default_promo/resources/BUILD.gn b/ios/chrome/browser/default_promo/ui_bundled/resources/BUILD.gn
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/resources/BUILD.gn
rename to ios/chrome/browser/default_promo/ui_bundled/resources/BUILD.gn
diff --git a/ios/chrome/browser/ui/default_promo/resources/default_browser_animation.json b/ios/chrome/browser/default_promo/ui_bundled/resources/default_browser_animation.json
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/resources/default_browser_animation.json
rename to ios/chrome/browser/default_promo/ui_bundled/resources/default_browser_animation.json
diff --git a/ios/chrome/browser/ui/default_promo/resources/default_browser_animation_darkmode.json b/ios/chrome/browser/default_promo/ui_bundled/resources/default_browser_animation_darkmode.json
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/resources/default_browser_animation_darkmode.json
rename to ios/chrome/browser/default_promo/ui_bundled/resources/default_browser_animation_darkmode.json
diff --git a/ios/chrome/browser/ui/default_promo/resources/default_browser_animation_rtl.json b/ios/chrome/browser/default_promo/ui_bundled/resources/default_browser_animation_rtl.json
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/resources/default_browser_animation_rtl.json
rename to ios/chrome/browser/default_promo/ui_bundled/resources/default_browser_animation_rtl.json
diff --git a/ios/chrome/browser/ui/default_promo/resources/default_browser_animation_rtl_darkmode.json b/ios/chrome/browser/default_promo/ui_bundled/resources/default_browser_animation_rtl_darkmode.json
similarity index 100%
rename from ios/chrome/browser/ui/default_promo/resources/default_browser_animation_rtl_darkmode.json
rename to ios/chrome/browser/default_promo/ui_bundled/resources/default_browser_animation_rtl_darkmode.json
diff --git a/ios/chrome/browser/default_promo/ui_bundled/stay_safe_default_browser_promo_view_provider.h b/ios/chrome/browser/default_promo/ui_bundled/stay_safe_default_browser_promo_view_provider.h
new file mode 100644
index 0000000..600eee2
--- /dev/null
+++ b/ios/chrome/browser/default_promo/ui_bundled/stay_safe_default_browser_promo_view_provider.h
@@ -0,0 +1,15 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_STAY_SAFE_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
+#define IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_STAY_SAFE_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
+
+#import "ios/chrome/browser/default_promo/ui_bundled/base_default_browser_promo_view_provider.h"
+
+// Provider for displaying the Stay Safe Default Browser Promo.
+@interface StaySafeDefaultBrowserPromoViewProvider
+    : BaseDefaultBrowserPromoViewProvider
+@end
+
+#endif  // IOS_CHROME_BROWSER_DEFAULT_PROMO_UI_BUNDLED_STAY_SAFE_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
diff --git a/ios/chrome/browser/ui/default_promo/stay_safe_default_browser_promo_view_provider.mm b/ios/chrome/browser/default_promo/ui_bundled/stay_safe_default_browser_promo_view_provider.mm
similarity index 91%
rename from ios/chrome/browser/ui/default_promo/stay_safe_default_browser_promo_view_provider.mm
rename to ios/chrome/browser/default_promo/ui_bundled/stay_safe_default_browser_promo_view_provider.mm
index 7102193c..cd0d601 100644
--- a/ios/chrome/browser/ui/default_promo/stay_safe_default_browser_promo_view_provider.mm
+++ b/ios/chrome/browser/default_promo/ui_bundled/stay_safe_default_browser_promo_view_provider.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/default_promo/stay_safe_default_browser_promo_view_provider.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/stay_safe_default_browser_promo_view_provider.h"
 
 #import "components/feature_engagement/public/feature_constants.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
diff --git a/ios/chrome/browser/docking_promo/model/utils.mm b/ios/chrome/browser/docking_promo/model/utils.mm
index c2604dd..958fca4 100644
--- a/ios/chrome/browser/docking_promo/model/utils.mm
+++ b/ios/chrome/browser/docking_promo/model/utils.mm
@@ -4,10 +4,7 @@
 
 #import "ios/chrome/browser/docking_promo/model/utils.h"
 
-#import "base/feature_list.h"
-#import "base/metrics/histogram_macros.h"
 #import "base/strings/sys_string_conversions.h"
-#import "base/time/time.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
 #import "ios/chrome/browser/promos_manager/model/constants.h"
 #import "ios/chrome/browser/shared/coordinator/scene/scene_state.h"
@@ -16,15 +13,6 @@
 #import "ios/chrome/browser/shared/public/features/system_flags.h"
 #import "ios/chrome/browser/ui/start_surface/start_surface_util.h"
 
-namespace {
-
-// Killswitch to control new DockingPromo histograms.
-BASE_FEATURE(kDockingPromoHistogramKillswitch,
-             "DockingPromoHistogramKillswitch",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
-}  // namespace
-
 BOOL IsDockingPromoForcedForDisplay() {
   NSString* forced_promo_name = experimental_flags::GetForcedPromoToDisplay();
 
@@ -44,15 +32,6 @@
 }
 
 BOOL CanShowDockingPromo(base::TimeDelta time_since_last_foreground) {
-  // TODO(crbug.com/330387623): Cleanup Docking Promo histograms.
-  if (base::FeatureList::IsEnabled(kDockingPromoHistogramKillswitch)) {
-    // Logs the time since last foreground over a range of 2 weeks.
-    UMA_HISTOGRAM_CUSTOM_COUNTS(
-        "IOS.DockingPromo.LastForegroundTimeViaAppState",
-        time_since_last_foreground.InMinutes(), 1, base::Days(14).InMinutes(),
-        100);
-  }
-
   if (IsDockingPromoForcedForDisplay()) {
     return YES;
   }
diff --git a/ios/chrome/browser/download/model/document_download_tab_helper.h b/ios/chrome/browser/download/model/document_download_tab_helper.h
index 09196e3..6d11e89 100644
--- a/ios/chrome/browser/download/model/document_download_tab_helper.h
+++ b/ios/chrome/browser/download/model/document_download_tab_helper.h
@@ -28,6 +28,9 @@
 
   ~DocumentDownloadTabHelper() override;
 
+  // Returns whether the current download task was created by this TabHelper.
+  bool IsDownloadTaskCreatedByCurrentTabHelper();
+
   // web::WebStateObserver implementation.
   void WebStateDestroyed(web::WebState* web_state) override;
   void PageLoaded(
diff --git a/ios/chrome/browser/download/model/document_download_tab_helper.mm b/ios/chrome/browser/download/model/document_download_tab_helper.mm
index 1a04c55af..b2a1ddd4 100644
--- a/ios/chrome/browser/download/model/document_download_tab_helper.mm
+++ b/ios/chrome/browser/download/model/document_download_tab_helper.mm
@@ -80,6 +80,10 @@
   }
 }
 
+bool DocumentDownloadTabHelper::IsDownloadTaskCreatedByCurrentTabHelper() {
+  return current_task_is_document_download_;
+}
+
 #pragma mark - web::WebStateObserver
 
 void DocumentDownloadTabHelper::WebStateDestroyed(web::WebState* web_state) {
@@ -179,10 +183,9 @@
       (!web_state->ContentIsHTML() &&
        !base::StartsWith(web_state->GetContentsMimeType(), "video/"));
 
-  // Only triggers on http(s) or external file.
+  // Only triggers on http(s).
   GURL url = web_state->GetLastCommittedURL();
-  should_trigger = should_trigger && (url.SchemeIsHTTPOrHTTPS() ||
-                                      url.host() == kChromeUIExternalFileHost);
+  should_trigger = should_trigger && url.SchemeIsHTTPOrHTTPS();
 
   if (should_trigger) {
     base::UmaHistogramEnumeration(kIOSDocumentDownloadMimeType,
diff --git a/ios/chrome/browser/download/ui_bundled/download_manager_egtest.mm b/ios/chrome/browser/download/ui_bundled/download_manager_egtest.mm
index 41af599..366203ac 100644
--- a/ios/chrome/browser/download/ui_bundled/download_manager_egtest.mm
+++ b/ios/chrome/browser/download/ui_bundled/download_manager_egtest.mm
@@ -46,14 +46,28 @@
   return result;
 }
 
-// Provides test page for downloads with content disposition
-std::unique_ptr<net::test_server::HttpResponse> GetContentDispositionResponse(
+// Provides test page for new page downloads with content disposition.
+std::unique_ptr<net::test_server::HttpResponse>
+GetLinkToContentDispositionResponse(
     const net::test_server::HttpRequest& request) {
   auto result = std::make_unique<net::test_server::BasicHttpResponse>();
   result->set_code(net::HTTP_OK);
   result->set_content(
-      "<a id='pdf' download='test.pdf' href='/single_page_wide.pdf'>PDF</a>");
-  result->set_content_type("attachment; filename='filename.pdf'");
+      "<a id='pdf' download href='/content-disposition'>PDF</a><br/><a "
+      "id='pdf_new_window' target='_blank' href='/content-disposition'>PDF in "
+      "new tab</a>");
+  return result;
+}
+
+// Provides test page for downloads with content disposition.
+std::unique_ptr<net::test_server::HttpResponse>
+GetContentDispositionPDFResponse(const net::test_server::HttpRequest& request) {
+  auto result = std::make_unique<net::test_server::BasicHttpResponse>();
+  result->set_code(net::HTTP_OK);
+  result->set_content("fakePDFData");
+  result->AddCustomHeader("Content-Type", "application/pdf");
+  result->AddCustomHeader("Content-Disposition",
+                          "attachment; filename=filename.pdf");
   return result;
 }
 
@@ -113,8 +127,12 @@
                           base::BindRepeating(&GetResponse)));
 
   self.testServer->RegisterRequestHandler(base::BindRepeating(
+      &net::test_server::HandlePrefixedRequest, "/link-to-content-disposition",
+      base::BindRepeating(&GetLinkToContentDispositionResponse)));
+
+  self.testServer->RegisterRequestHandler(base::BindRepeating(
       &net::test_server::HandlePrefixedRequest, "/content-disposition",
-      base::BindRepeating(&GetContentDispositionResponse)));
+      base::BindRepeating(&GetContentDispositionPDFResponse)));
 
   self.testServer->RegisterRequestHandler(base::BindRepeating(
       &net::test_server::HandlePrefixedRequest, "/download-example",
@@ -363,7 +381,6 @@
   GREYAssert(WaitForDownloadButton(), @"Download button did not show up");
   [[EarlGrey selectElementWithMatcher:DownloadButton()]
       performAction:grey_tap()];
-
   if (shouldOpen) {
     GREYAssert(WaitForOpenPDFButton(), @"Open button did not show up");
   } else {
@@ -372,17 +389,17 @@
 }
 
 // Tests that a file is downloaded successfully even if it is renderable by the
-// browser. The `shouldOpen` used to wait for the right button once the download
+// browser.The `shouldOpen` used to wait for the right button once the download
 // button is tapped.
 - (void)testSuccessfulDownloadWithContentDisposition:(BOOL)shouldOpen {
-  [ChromeEarlGrey loadURL:self.testServer->GetURL("/content-disposition")];
+  [ChromeEarlGrey
+      loadURL:self.testServer->GetURL("/link-to-content-disposition")];
   [ChromeEarlGrey waitForWebStateContainingText:"PDF"];
   [ChromeEarlGrey tapWebStateElementWithID:@"pdf"];
 
   GREYAssert(WaitForDownloadButton(), @"Download button did not show up");
   [[EarlGrey selectElementWithMatcher:DownloadButton()]
       performAction:grey_tap()];
-
   if (shouldOpen) {
     GREYAssert(WaitForOpenPDFButton(), @"Open button did not show up");
   } else {
@@ -390,6 +407,20 @@
   }
 }
 
+// Tests that a file is downloaded successfully when opened in a new window.
+- (void)testSuccessfulDownloadWithContentDispositionInNewWindow {
+  [ChromeEarlGrey
+      loadURL:self.testServer->GetURL("/link-to-content-disposition")];
+  [ChromeEarlGrey waitForWebStateContainingText:"PDF"];
+  [ChromeEarlGrey tapWebStateElementWithID:@"pdf_new_window"];
+
+  GREYAssert(WaitForDownloadButton(), @"Download button did not show up");
+  [[EarlGrey selectElementWithMatcher:DownloadButton()]
+      performAction:grey_tap()];
+
+  GREYAssert(WaitForOpenPDFButton(), @"Open button did not show up");
+}
+
 @end
 
 // Tests for critical user journeys for Download Manager, without Save to Drive.
@@ -410,6 +441,7 @@
 - (AppLaunchConfiguration)appConfigurationForTestCase {
   AppLaunchConfiguration configuration;
   configuration.features_disabled.push_back(kIOSSaveToDrive);
+  configuration.features_disabled.push_back(kDownloadedPDFOpening);
   return configuration;
 }
 
@@ -524,6 +556,12 @@
   [_helper testSuccessfulDownload];
 }
 
+// Tests successful download, when the download is triggered in a new page, and
+// when finished to "Open" button is displayed.
+- (void)testSuccessfulDownloadWithContentDispositionInNewWindow {
+  [_helper testSuccessfulDownloadWithContentDispositionInNewWindow];
+}
+
 // Tests successful download up to the point where "Open in..." button is
 // presented. EarlGrey does not allow testing "Open in..." dialog, because it
 // is run in a separate process. Performs download in Incognito.
diff --git a/ios/chrome/browser/download/ui_bundled/download_manager_mediator.mm b/ios/chrome/browser/download/ui_bundled/download_manager_mediator.mm
index b7078e3..f8dcdc26 100644
--- a/ios/chrome/browser/download/ui_bundled/download_manager_mediator.mm
+++ b/ios/chrome/browser/download/ui_bundled/download_manager_mediator.mm
@@ -12,6 +12,7 @@
 #import "base/files/file_util.h"
 #import "base/functional/bind.h"
 #import "base/task/thread_pool.h"
+#import "ios/chrome/browser/download/model/document_download_tab_helper.h"
 #import "ios/chrome/browser/download/model/download_directory_util.h"
 #import "ios/chrome/browser/download/model/external_app_util.h"
 #import "ios/chrome/browser/drive/model/drive_availability.h"
@@ -199,7 +200,15 @@
     [consumer_ setSaveToDriveUserEmail:identity.userEmail];
     [consumer_ setInstallDriveButtonVisible:!IsGoogleDriveAppInstalled()
                                    animated:NO];
-    [consumer_ setCanOpenFile:filename.MatchesExtension(".pdf")];
+
+    // A file can be opened if it is not already presented in the web state and
+    // of type PDF.
+    DocumentDownloadTabHelper* document_download_tab_helper =
+        DocumentDownloadTabHelper::FromWebState(download_task_->GetWebState());
+    BOOL can_open_file = !document_download_tab_helper
+                              ->IsDownloadTaskCreatedByCurrentTabHelper() &&
+                         filename.MatchesExtension(".pdf");
+    [consumer_ setCanOpenFile:can_open_file];
   } else if (state == kDownloadManagerStateSucceeded &&
              !IsGoogleDriveAppInstalled()) {
     [consumer_ setInstallDriveButtonVisible:YES animated:YES];
diff --git a/ios/chrome/browser/infobars/model/DEPS b/ios/chrome/browser/infobars/model/DEPS
index 9e7f00b..8b916f0 100644
--- a/ios/chrome/browser/infobars/model/DEPS
+++ b/ios/chrome/browser/infobars/model/DEPS
@@ -9,10 +9,10 @@
     "+ios/chrome/browser/badges/ui_bundled/badge_item.h",
   ],
   "^infobar_metrics_recorder.h": [
-    "+ios/chrome/browser/ui/default_promo/default_browser_utils.h",
+    "+ios/chrome/browser/default_promo/ui_bundled/default_browser_utils.h",
   ],
   "^infobar_metrics_recorder.mm": [
-    "+ios/chrome/browser/ui/default_promo/default_browser_utils.h",
+    "+ios/chrome/browser/default_promo/ui_bundled/default_browser_utils.h",
   ],
 
 }
diff --git a/ios/chrome/browser/lens_overlay/OWNERS b/ios/chrome/browser/lens_overlay/OWNERS
new file mode 100644
index 0000000..96e7948a
--- /dev/null
+++ b/ios/chrome/browser/lens_overlay/OWNERS
@@ -0,0 +1 @@
+stkhapugin@chromium.org
diff --git a/ios/chrome/browser/lens_overlay/coordinator/BUILD.gn b/ios/chrome/browser/lens_overlay/coordinator/BUILD.gn
new file mode 100644
index 0000000..ae15a4b4
--- /dev/null
+++ b/ios/chrome/browser/lens_overlay/coordinator/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2024 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("coordinator") {
+  sources = [
+    "lens_overlay_coordinator.h",
+    "lens_overlay_coordinator.mm",
+  ]
+  deps = [
+    "//base",
+    "//ios/chrome/app/strings:ios_strings_grit",
+    "//ios/chrome/browser/lens_overlay/ui:view_controller",
+    "//ios/chrome/browser/shared/coordinator/chrome_coordinator",
+    "//ios/chrome/browser/shared/model/application_context",
+    "//ios/chrome/browser/shared/model/browser",
+    "//ios/chrome/browser/shared/model/browser_state",
+    "//ios/chrome/browser/shared/model/url",
+    "//ios/chrome/browser/shared/model/web_state_list",
+    "//ios/chrome/browser/shared/public/commands",
+    "//ios/chrome/browser/shared/public/features",
+    "//ios/chrome/browser/shared/ui/symbols",
+    "//ios/chrome/browser/web/model",
+    "//ios/chrome/browser/web_state_list/model",
+    "//ios/web/public/navigation",
+    "//ui/base",
+  ]
+}
diff --git a/ios/chrome/browser/lens_overlay/coordinator/lens_overlay_coordinator.h b/ios/chrome/browser/lens_overlay/coordinator/lens_overlay_coordinator.h
new file mode 100644
index 0000000..164e4e077
--- /dev/null
+++ b/ios/chrome/browser/lens_overlay/coordinator/lens_overlay_coordinator.h
@@ -0,0 +1,15 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_LENS_OVERLAY_COORDINATOR_LENS_OVERLAY_COORDINATOR_H_
+#define IOS_CHROME_BROWSER_LENS_OVERLAY_COORDINATOR_LENS_OVERLAY_COORDINATOR_H_
+
+#import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h"
+
+// LensOverlayCoordinator presents the public interface for the Lens Overlay.
+@interface LensOverlayCoordinator : ChromeCoordinator
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_LENS_OVERLAY_COORDINATOR_LENS_OVERLAY_COORDINATOR_H_
diff --git a/ios/chrome/browser/lens_overlay/coordinator/lens_overlay_coordinator.mm b/ios/chrome/browser/lens_overlay/coordinator/lens_overlay_coordinator.mm
new file mode 100644
index 0000000..137abcc
--- /dev/null
+++ b/ios/chrome/browser/lens_overlay/coordinator/lens_overlay_coordinator.mm
@@ -0,0 +1,115 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/lens_overlay/coordinator/lens_overlay_coordinator.h"
+
+#import "base/check.h"
+#import "ios/chrome/browser/lens_overlay/ui/lens_overlay_container_view_controller.h"
+#import "ios/chrome/browser/shared/model/browser/browser.h"
+#import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
+#import "ios/chrome/browser/shared/public/commands/lens_overlay_commands.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
+
+@interface LensOverlayCoordinator () <LensOverlayCommands>
+
+@end
+
+@implementation LensOverlayCoordinator {
+  /// Container view controller.
+  /// Hosts all of lens UI: contains the selection UI, presents the results UI
+  /// modally.
+  LensOverlayContainerViewController* _containerViewController;
+}
+
+#pragma mark - properties
+
+- (void)createContainerViewController {
+  if (_containerViewController) {
+    return;
+  }
+  _containerViewController = [[LensOverlayContainerViewController alloc] init];
+  _containerViewController.modalPresentationStyle =
+      UIModalPresentationOverFullScreen;
+  _containerViewController.modalTransitionStyle =
+      UIModalTransitionStyleCrossDissolve;
+}
+
+#pragma mark - ChromeCoordinator
+
+- (void)start {
+  DCHECK(base::FeatureList::IsEnabled(kEnableLensOverlay));
+  [super start];
+
+  Browser* browser = self.browser;
+  DCHECK(browser);
+
+  [browser->GetCommandDispatcher()
+      startDispatchingToTarget:self
+                   forProtocol:@protocol(LensOverlayCommands)];
+}
+
+- (void)stop {
+  Browser* browser = self.browser;
+  DCHECK(browser);
+  [browser->GetCommandDispatcher() stopDispatchingToTarget:self];
+
+  [super stop];
+}
+
+#pragma mark - LensOverlayCommands
+
+- (void)createAndShowLensUI:(BOOL)animated {
+  if ([self isUICreated]) {
+    // The UI is probably associated with the non-active tab. Destroy it with no
+    // animation.
+    [self destroyLensUI:NO];
+  }
+  [self createContainerViewController];
+  [self showLensUI:animated];
+}
+
+- (void)showLensUI:(BOOL)animated {
+  if (![self isUICreated]) {
+    return;
+  }
+
+  [self.baseViewController presentViewController:_containerViewController
+                                        animated:animated
+                                      completion:nil];
+}
+
+- (void)hideLensUI:(BOOL)animated {
+  if (![self isUICreated]) {
+    return;
+  }
+
+  [_containerViewController.presentingViewController
+      dismissViewControllerAnimated:animated
+                         completion:nil];
+}
+
+- (void)destroyLensUI:(BOOL)animated {
+  if (_containerViewController.presentingViewController) {
+    [_containerViewController.presentingViewController
+        dismissViewControllerAnimated:animated
+                           completion:^{
+                             [self destroyViewControllers];
+                           }];
+  } else {
+    [self destroyViewControllers];
+  }
+}
+
+#pragma mark - private
+
+- (BOOL)isUICreated {
+  return _containerViewController != nil;
+}
+
+// Disconnect and destroy all of the owned view controllers.
+- (void)destroyViewControllers {
+  _containerViewController = nil;
+}
+
+@end
diff --git a/ios/chrome/browser/lens_overlay/model/BUILD.gn b/ios/chrome/browser/lens_overlay/model/BUILD.gn
new file mode 100644
index 0000000..7368e1f
--- /dev/null
+++ b/ios/chrome/browser/lens_overlay/model/BUILD.gn
@@ -0,0 +1,35 @@
+# Copyright 2022 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("model") {
+  sources = [
+    "lens_overlay_tab_helper.h",
+    "lens_overlay_tab_helper.mm",
+  ]
+  deps = [
+    "//base",
+    "//ios/chrome/browser/shared/model/web_state_list",
+    "//ios/chrome/browser/shared/public/commands",
+    "//ios/chrome/browser/shared/public/features",
+    "//ios/web/public",
+  ]
+  public_deps = [ "//base" ]
+}
+
+source_set("unit_tests") {
+  testonly = true
+  sources = [ "lens_overlay_tab_helper_unittest.mm" ]
+  deps = [
+    ":model",
+    "//base/test:test_support",
+    "//ios/chrome/browser/shared/model/browser_state:test_support",
+    "//ios/chrome/browser/shared/public/commands",
+    "//ios/chrome/browser/shared/public/features",
+    "//ios/chrome/browser/ui/lens:lens_entrypoint",
+    "//ios/testing:ocmock_support",
+    "//ios/web/public/test",
+    "//testing/gtest",
+    "//third_party/ocmock",
+  ]
+}
diff --git a/ios/chrome/browser/lens_overlay/model/lens_overlay_tab_helper.h b/ios/chrome/browser/lens_overlay/model/lens_overlay_tab_helper.h
new file mode 100644
index 0000000..6a639807
--- /dev/null
+++ b/ios/chrome/browser/lens_overlay/model/lens_overlay_tab_helper.h
@@ -0,0 +1,48 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_LENS_OVERLAY_MODEL_LENS_OVERLAY_TAB_HELPER_H_
+#define IOS_CHROME_BROWSER_LENS_OVERLAY_MODEL_LENS_OVERLAY_TAB_HELPER_H_
+
+#import "ios/web/public/web_state_observer.h"
+#import "ios/web/public/web_state_user_data.h"
+
+@protocol LensOverlayCommands;
+
+// A tab helper that handles navigation to the tab with Lens Overlay
+// by showing/hiding/killing the Lens Overlay UI.
+class LensOverlayTabHelper : public web::WebStateUserData<LensOverlayTabHelper>,
+                             public web::WebStateObserver {
+ public:
+  ~LensOverlayTabHelper() override;
+
+  LensOverlayTabHelper(const LensOverlayTabHelper&) = delete;
+  LensOverlayTabHelper& operator=(const LensOverlayTabHelper&) = delete;
+
+  // Sets the Lens Overlay commands handler.
+  void SetLensOverlayCommandsHandler(id<LensOverlayCommands> commands_handler) {
+    commands_handler_ = commands_handler;
+  }
+
+  // web::WebStateObserver:
+  void WebStateDestroyed(web::WebState* web_state) override;
+
+ private:
+  explicit LensOverlayTabHelper(web::WebState* web_state);
+
+  // Handler used to request showing the password bottom sheet.
+  __weak id<LensOverlayCommands> commands_handler_;
+
+  // Tracks if lens overlay is displayed by the current tab helper
+  bool is_showing_lens_overlay_ = false;
+
+  // The WebState this instance is observing. Will be null after
+  // WebStateDestroyed has been called.
+  raw_ptr<web::WebState> web_state_ = nullptr;
+
+  friend class web::WebStateUserData<LensOverlayTabHelper>;
+  WEB_STATE_USER_DATA_KEY_DECL();
+};
+
+#endif  // IOS_CHROME_BROWSER_LENS_OVERLAY_MODEL_LENS_OVERLAY_TAB_HELPER_H_
diff --git a/ios/chrome/browser/lens_overlay/model/lens_overlay_tab_helper.mm b/ios/chrome/browser/lens_overlay/model/lens_overlay_tab_helper.mm
new file mode 100644
index 0000000..08298548
--- /dev/null
+++ b/ios/chrome/browser/lens_overlay/model/lens_overlay_tab_helper.mm
@@ -0,0 +1,33 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/lens_overlay/model/lens_overlay_tab_helper.h"
+
+#import "base/check_op.h"
+#import "ios/chrome/browser/shared/public/commands/lens_overlay_commands.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
+
+LensOverlayTabHelper::LensOverlayTabHelper(web::WebState* web_state)
+    : web_state_(web_state) {
+  DCHECK(base::FeatureList::IsEnabled(kEnableLensOverlay));
+  web_state->AddObserver(this);
+}
+
+LensOverlayTabHelper::~LensOverlayTabHelper() {
+  if (web_state_) {
+    web_state_->RemoveObserver(this);
+    web_state_ = nullptr;
+  }
+}
+
+#pragma mark - WebStateObserver
+
+void LensOverlayTabHelper::WebStateDestroyed(web::WebState* web_state) {
+  DCHECK_EQ(web_state, web_state_);
+  [commands_handler_ destroyLensUI:NO];
+  web_state_->RemoveObserver(this);
+  web_state_ = nullptr;
+}
+
+WEB_STATE_USER_DATA_KEY_IMPL(LensOverlayTabHelper)
diff --git a/ios/chrome/browser/lens_overlay/model/lens_overlay_tab_helper_unittest.mm b/ios/chrome/browser/lens_overlay/model/lens_overlay_tab_helper_unittest.mm
new file mode 100644
index 0000000..13710c4f
--- /dev/null
+++ b/ios/chrome/browser/lens_overlay/model/lens_overlay_tab_helper_unittest.mm
@@ -0,0 +1,68 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/lens_overlay/model/lens_overlay_tab_helper.h"
+
+#import "base/memory/raw_ptr.h"
+#import "base/test/scoped_feature_list.h"
+#import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
+#import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
+#import "ios/chrome/browser/shared/public/commands/lens_overlay_commands.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
+#import "ios/web/public/test/web_task_environment.h"
+#import "testing/gtest/include/gtest/gtest.h"
+#import "testing/platform_test.h"
+#import "third_party/ocmock/OCMock/OCMock.h"
+#import "third_party/ocmock/gtest_support.h"
+
+namespace {
+
+class LensOverlayTabHelperTest : public PlatformTest {
+ public:
+  LensOverlayTabHelperTest() {
+    browser_state_ = TestChromeBrowserState::Builder().Build();
+  }
+
+  void SetUp() override {
+    PlatformTest::SetUp();
+
+    feature_list_.InitAndEnableFeature(kEnableLensOverlay);
+
+    web::WebState::CreateParams params(browser_state_.get());
+    web_state_ = web::WebState::Create(params);
+
+    id dispatcher = [[CommandDispatcher alloc] init];
+    dispatcher_ = dispatcher;
+
+    LensOverlayTabHelper::CreateForWebState(web_state_.get());
+    helper_ = LensOverlayTabHelper::FromWebState(web_state_.get());
+    ASSERT_TRUE(helper_);
+
+    helper_->SetLensOverlayCommandsHandler(dispatcher);
+
+    mock_commands_handler_ = OCMProtocolMock(@protocol(LensOverlayCommands));
+    [dispatcher_ startDispatchingToTarget:mock_commands_handler_
+                              forProtocol:@protocol(LensOverlayCommands)];
+  }
+
+ protected:
+  std::unique_ptr<TestChromeBrowserState> browser_state_;
+  std::unique_ptr<web::WebState> web_state_;
+  web::WebTaskEnvironment task_environment_{
+      web::WebTaskEnvironment::MainThreadType::IO};
+  raw_ptr<LensOverlayTabHelper> helper_ = nullptr;
+  id handler_;
+  id dispatcher_;
+  id mock_commands_handler_;
+  base::test::ScopedFeatureList feature_list_;
+};
+
+// Test that web state destruction causes lens UI to destroy with no animation.
+TEST_F(LensOverlayTabHelperTest, ShouldDestroyUIOnWebStateDestrictuion) {
+  OCMExpect([mock_commands_handler_ destroyLensUI:NO]);
+  web_state_.reset();
+  EXPECT_OCMOCK_VERIFY(mock_commands_handler_);
+}
+
+}  // namespace
diff --git a/ios/chrome/browser/lens_overlay/ui/BUILD.gn b/ios/chrome/browser/lens_overlay/ui/BUILD.gn
new file mode 100644
index 0000000..907b0027
--- /dev/null
+++ b/ios/chrome/browser/lens_overlay/ui/BUILD.gn
@@ -0,0 +1,23 @@
+# Copyright 2024 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("view_controller") {
+  sources = [
+    "lens_overlay_container_view_controller.h",
+    "lens_overlay_container_view_controller.mm",
+  ]
+  deps = [
+    "//base",
+    "//components/strings",
+    "//ios/chrome/app/strings",
+    "//ios/chrome/browser/shared/public/commands",
+    "//ios/chrome/browser/shared/ui/elements",
+    "//ios/chrome/browser/shared/ui/symbols",
+    "//ios/chrome/browser/shared/ui/util",
+    "//ios/chrome/common",
+    "//ios/chrome/common/ui/colors",
+    "//ios/chrome/common/ui/util",
+  ]
+  frameworks = [ "UIKit.framework" ]
+}
diff --git a/ios/chrome/browser/lens_overlay/ui/lens_overlay_container_view_controller.h b/ios/chrome/browser/lens_overlay/ui/lens_overlay_container_view_controller.h
new file mode 100644
index 0000000..dda6a70
--- /dev/null
+++ b/ios/chrome/browser/lens_overlay/ui/lens_overlay_container_view_controller.h
@@ -0,0 +1,17 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_LENS_OVERLAY_UI_LENS_OVERLAY_CONTAINER_VIEW_CONTROLLER_H_
+#define IOS_CHROME_BROWSER_LENS_OVERLAY_UI_LENS_OVERLAY_CONTAINER_VIEW_CONTROLLER_H_
+
+#import <UIKit/UIKit.h>
+
+/// The top level view controller for lens overlay.
+/// Contains or presents the other view controllers.
+/// Displays top-level chrome like close button.
+@interface LensOverlayContainerViewController : UIViewController
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_LENS_OVERLAY_UI_LENS_OVERLAY_CONTAINER_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/lens_overlay/ui/lens_overlay_container_view_controller.mm b/ios/chrome/browser/lens_overlay/ui/lens_overlay_container_view_controller.mm
new file mode 100644
index 0000000..fb2395a
--- /dev/null
+++ b/ios/chrome/browser/lens_overlay/ui/lens_overlay_container_view_controller.mm
@@ -0,0 +1,15 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/lens_overlay/ui/lens_overlay_container_view_controller.h"
+
+@implementation LensOverlayContainerViewController
+
+- (void)viewDidLoad {
+  [super viewDidLoad];
+
+  self.view.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
+}
+
+@end
diff --git a/ios/chrome/browser/metrics/model/DEPS b/ios/chrome/browser/metrics/model/DEPS
index fa95ad1..5893f39 100644
--- a/ios/chrome/browser/metrics/model/DEPS
+++ b/ios/chrome/browser/metrics/model/DEPS
@@ -40,8 +40,8 @@
     "+ios/chrome/browser/shared/coordinator/scene/scene_state.h",
   ],
   "^ios_chrome_default_browser_metrics_provider.mm": [
-    "+ios/chrome/browser/ui/default_promo/default_browser_utils.h",
     "+ios/chrome/browser/default_browser/model/utils.h",
+    "+ios/chrome/browser/default_promo/ui_bundled/default_browser_utils.h",
   ],
   "^ios_chrome_metrics_service_client.mm": [
     "+ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h",
diff --git a/ios/chrome/browser/ntp/model/set_up_list_unittest.mm b/ios/chrome/browser/ntp/model/set_up_list_unittest.mm
index f94c5fb9..5dd143c 100644
--- a/ios/chrome/browser/ntp/model/set_up_list_unittest.mm
+++ b/ios/chrome/browser/ntp/model/set_up_list_unittest.mm
@@ -49,7 +49,7 @@
     TestChromeBrowserState::Builder builder;
     builder.AddTestingFactory(
         AuthenticationServiceFactory::GetInstance(),
-        base::BindRepeating(AuthenticationServiceFactory::GetDefaultFactory()));
+        AuthenticationServiceFactory::GetDefaultFactory());
     std::unique_ptr<TestChromeBrowserState> browser_state = builder.Build();
     test_manager_ = std::make_unique<TestChromeBrowserStateManager>(
         std::move(browser_state));
diff --git a/ios/chrome/browser/passwords/model/password_controller.mm b/ios/chrome/browser/passwords/model/password_controller.mm
index 991abbd..8dd6b2d 100644
--- a/ios/chrome/browser/passwords/model/password_controller.mm
+++ b/ios/chrome/browser/passwords/model/password_controller.mm
@@ -514,8 +514,7 @@
 
 - (void)sharedPasswordController:(SharedPasswordController*)controller
              didAcceptSuggestion:(FormSuggestion*)suggestion {
-  if (suggestion.popupItemId ==
-      autofill::SuggestionType::kAllSavedPasswordsEntry) {
+  if (suggestion.type == autofill::SuggestionType::kAllSavedPasswordsEntry) {
     // Navigate to the settings list.
     [self.delegate displaySavedPasswordList];
   }
diff --git a/ios/chrome/browser/passwords/model/password_controller_unittest.mm b/ios/chrome/browser/passwords/model/password_controller_unittest.mm
index e9a54fc5..5a11cd53 100644
--- a/ios/chrome/browser/passwords/model/password_controller_unittest.mm
+++ b/ios/chrome/browser/passwords/model/password_controller_unittest.mm
@@ -617,7 +617,7 @@
       suggestionWithValue:suggestion_text
        displayDescription:nil
                      icon:nil
-              popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                     type:autofill::SuggestionType::kAutocompleteEntry
         backendIdentifier:nil
            requiresReauth:NO];
 
diff --git a/ios/chrome/browser/passwords/ui_bundled/bottom_sheet/password_suggestion_bottom_sheet_mediator_unittest.mm b/ios/chrome/browser/passwords/ui_bundled/bottom_sheet/password_suggestion_bottom_sheet_mediator_unittest.mm
index 06f1318f..3b24542 100644
--- a/ios/chrome/browser/passwords/ui_bundled/bottom_sheet/password_suggestion_bottom_sheet_mediator_unittest.mm
+++ b/ios/chrome/browser/passwords/ui_bundled/bottom_sheet/password_suggestion_bottom_sheet_mediator_unittest.mm
@@ -46,7 +46,7 @@
              suggestionWithValue:@"foo"
               displayDescription:nil
                             icon:nil
-                     popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                            type:autofill::SuggestionType::kAutocompleteEntry
                backendIdentifier:nil
                   requiresReauth:NO
       acceptanceA11yAnnouncement:nil
@@ -113,13 +113,13 @@
         suggestionWithValue:@"foo"
          displayDescription:nil
                        icon:nil
-                popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                       type:autofill::SuggestionType::kAutocompleteEntry
           backendIdentifier:nil
              requiresReauth:NO],
     [FormSuggestion suggestionWithValue:@"bar"
                      displayDescription:nil
                                    icon:nil
-                            popupItemId:autofill::SuggestionType::kAddressEntry
+                                   type:autofill::SuggestionType::kAddressEntry
                       backendIdentifier:nil
                          requiresReauth:NO]
   ];
@@ -414,7 +414,7 @@
                                                kPasswordFormSuggestionSuffix]
        displayDescription:nil
                      icon:nil
-              popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                     type:autofill::SuggestionType::kAutocompleteEntry
         backendIdentifier:nil
            requiresReauth:NO];
   std::optional<password_manager::CredentialUIEntry> credential =
@@ -441,7 +441,7 @@
       suggestionWithValue:@"test1"
        displayDescription:nil
                      icon:nil
-              popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                     type:autofill::SuggestionType::kAutocompleteEntry
         backendIdentifier:nil
            requiresReauth:NO];
   std::optional<password_manager::CredentialUIEntry> credential =
diff --git a/ios/chrome/browser/price_insights/coordinator/BUILD.gn b/ios/chrome/browser/price_insights/coordinator/BUILD.gn
index a7173f17..9f61f2a 100644
--- a/ios/chrome/browser/price_insights/coordinator/BUILD.gn
+++ b/ios/chrome/browser/price_insights/coordinator/BUILD.gn
@@ -12,7 +12,6 @@
     ":delegates",
     "//components/commerce/core:commerce_constants",
     "//components/image_fetcher/core",
-    "//components/payments/core",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/commerce/model:shopping_service",
     "//ios/chrome/browser/contextual_panel/coordinator:public",
diff --git a/ios/chrome/browser/price_insights/coordinator/price_insights_modulator.mm b/ios/chrome/browser/price_insights/coordinator/price_insights_modulator.mm
index 9524050..03c7e8b 100644
--- a/ios/chrome/browser/price_insights/coordinator/price_insights_modulator.mm
+++ b/ios/chrome/browser/price_insights/coordinator/price_insights_modulator.mm
@@ -8,7 +8,6 @@
 #import "base/strings/sys_string_conversions.h"
 #import "components/commerce/core/commerce_constants.h"
 #import "components/image_fetcher/core/image_data_fetcher.h"
-#import "components/payments/core/currency_formatter.h"
 #import "ios/chrome/browser/commerce/model/shopping_service_factory.h"
 #import "ios/chrome/browser/price_insights/model/price_insights_model.h"
 #import "ios/chrome/browser/price_insights/ui/price_insights_cell.h"
@@ -26,17 +25,6 @@
 
 namespace {
 
-NSString* getFormattedCurrentPrice(int64_t amount_micro,
-                                   std::string currency_code,
-                                   std::string country_code) {
-  float price = static_cast<float>(amount_micro) /
-                static_cast<float>(commerce::kToMicroCurrency);
-  payments::CurrencyFormatter formatter(currency_code, country_code);
-  formatter.SetMaxFractionalDigits(2);
-  return base::SysUTF16ToNSString(
-      formatter.Format(base::NumberToString(price)));
-}
-
 NSDate* getNSDateFromString(std::string date) {
   NSDateFormatter* date_format = [[NSDateFormatter alloc] init];
   [date_format setDateFormat:@"yyyy-MM-dd"];
@@ -249,7 +237,8 @@
   item.title = base::SysUTF8ToNSString(config->product_info->title);
   item.variants =
       base::SysUTF8ToNSString(config->product_info->product_cluster_title);
-  item.currency = base::SysUTF8ToNSString(config->product_info->currency_code);
+  item.currency = config->product_info->currency_code;
+  item.country = config->product_info->country_code;
   item.canPriceTrack = config->can_price_track;
   item.isPriceTracked = config->is_subscribed;
   item.productURL =
@@ -259,20 +248,15 @@
     return item;
   }
 
-  std::string currencyCode = config->product_info->currency_code;
-  std::string countryCode = config->product_info->country_code;
+  item.currentPrice = config->product_info->amount_micros;
   if (config->price_insights_info->typical_low_price_micros.has_value()) {
-    int64_t amountMicro =
-        config->price_insights_info->typical_low_price_micros.value();
     item.lowPrice =
-        getFormattedCurrentPrice(amountMicro, currencyCode, countryCode);
+        config->price_insights_info->typical_low_price_micros.value();
   }
 
   if (config->price_insights_info->typical_high_price_micros.has_value()) {
-    int64_t amountMicro =
-        config->price_insights_info->typical_high_price_micros.value();
     item.highPrice =
-        getFormattedCurrentPrice(amountMicro, currencyCode, countryCode);
+        config->price_insights_info->typical_high_price_micros.value();
   }
 
   NSMutableDictionary* priceHistory = [[NSMutableDictionary alloc] init];
diff --git a/ios/chrome/browser/price_insights/ui/BUILD.gn b/ios/chrome/browser/price_insights/ui/BUILD.gn
index 09c9b5e01..548b5549 100644
--- a/ios/chrome/browser/price_insights/ui/BUILD.gn
+++ b/ios/chrome/browser/price_insights/ui/BUILD.gn
@@ -13,11 +13,15 @@
     "price_insights_item.h",
     "price_insights_item.mm",
     "price_insights_mutator.h",
+    "price_ranger_slider.h",
+    "price_ranger_slider.mm",
   ]
 
   deps = [
     ":price_history_swift",
     "//base",
+    "//components/commerce/core:commerce_constants",
+    "//components/payments/core",
     "//components/strings",
     "//ios/chrome/browser/shared/ui/symbols",
     "//ios/chrome/browser/shared/ui/util",
diff --git a/ios/chrome/browser/price_insights/ui/price_insights_cell.mm b/ios/chrome/browser/price_insights/ui/price_insights_cell.mm
index 0dced23..7a602d26 100644
--- a/ios/chrome/browser/price_insights/ui/price_insights_cell.mm
+++ b/ios/chrome/browser/price_insights/ui/price_insights_cell.mm
@@ -5,10 +5,13 @@
 #import "ios/chrome/browser/price_insights/ui/price_insights_cell.h"
 
 #import "base/strings/sys_string_conversions.h"
+#import "components/commerce/core/commerce_constants.h"
+#import "components/payments/core/currency_formatter.h"
 #import "components/strings/grit/components_strings.h"
 #import "ios/chrome/browser/price_insights/ui/price_history_swift.h"
 #import "ios/chrome/browser/price_insights/ui/price_insights_constants.h"
 #import "ios/chrome/browser/price_insights/ui/price_insights_mutator.h"
+#import "ios/chrome/browser/price_insights/ui/price_ranger_slider.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
@@ -42,6 +45,9 @@
 // Size of the space between the graph and the text in Price History.
 const CGFloat kPriceHistoryContentSpacing = 12.0f;
 
+// Size of the space between the graph and the text in Price Range.
+const CGFloat kPriceRangeContentSpacing = 16.0f;
+
 // Height of Price History graph.
 const CGFloat kPriceHistoryGraphHeight = 186.0f;
 
@@ -54,6 +60,18 @@
 // The vertical padding for the track button.
 const CGFloat kTrackButtonVerticalPadding = 3.0f;
 
+// Formats a price amount in micro-units into a localized string representation
+// for display.
+std::u16string getFormattedCurrentPrice(int64_t amount_micro,
+                                        std::string currency_code,
+                                        std::string country_code) {
+  float price = static_cast<float>(amount_micro) /
+                static_cast<float>(commerce::kToMicroCurrency);
+  payments::CurrencyFormatter formatter(currency_code, country_code);
+  formatter.SetMaxFractionalDigits(2);
+  return formatter.Format(base::NumberToString(price));
+}
+
 }  // namespace
 
 @interface PriceInsightsCell ()
@@ -68,6 +86,7 @@
   UIStackView* _buyingOptionsStackView;
   UIStackView* _contentStackView;
   UIStackView* _priceHistoryStackView;
+  UIStackView* _priceRangeStackView;
   UIButton* _trackButton;
   NSLayoutConstraint* _trackButtonWidthConstraint;
 }
@@ -106,7 +125,7 @@
   }
 
   // Configure Price History.
-  if ([self hasPriceHistory] && self.item.currency) {
+  if ([self hasPriceHistory] && !self.item.currency.empty()) {
     NSString* title;
     NSString* primarySubtitle;
     NSString* secondarySubtitle;
@@ -136,6 +155,20 @@
     [_contentStackView addArrangedSubview:_priceHistoryStackView];
   }
 
+  // Configure Price Range
+  if ([self hasPriceRange] && ![self hasPriceHistory]) {
+    NSString* variantTitle =
+        [self hasVariants]
+            ? l10n_util::GetNSString(
+                  IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE_VARIANT)
+            : l10n_util::GetNSString(
+                  IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE_NO_VARIANT);
+    NSString* title = self.item.canPriceTrack ? variantTitle : self.item.title;
+    NSString* subtitle = self.item.canPriceTrack ? nil : variantTitle;
+    [self configurePriceRangeWithTitle:title subtitle:subtitle];
+    [_contentStackView addArrangedSubview:_priceRangeStackView];
+  }
+
   // Configure Buying options.
   if ([self hasPriceHistory] && [self hasPriceRange] &&
       self.item.buyingOptionsURL.is_valid()) {
@@ -153,15 +186,13 @@
 
 // Returns whether or not price range is available.
 - (BOOL)hasPriceRange {
-  return self.item.lowPrice.length > 0 && self.item.highPrice.length > 0;
+  return self.item.lowPrice > 0 && self.item.highPrice > 0;
 }
 
 // Returns whether or not price has one typical price. If there is only one
 // typical price, the high and low price are equal.
 - (BOOL)hasPriceOneTypicalPrice {
-  return [self hasPriceRange]
-             ? [self.item.highPrice isEqualToString:self.item.lowPrice]
-             : NO;
+  return [self hasPriceRange] ? self.item.highPrice == self.item.lowPrice : NO;
 }
 
 // Returns whether or not there are any variants.
@@ -191,24 +222,26 @@
       CreateDynamicFont(UIFontTextStyleSubheadline, UIFontWeightRegular);
   priceTrackingSubtitle.textColor = [UIColor colorNamed:kTextSecondaryColor];
   if ([self hasPriceRange] && [self hasPriceHistory]) {
+    std::u16string lowPrice = getFormattedCurrentPrice(
+        self.item.lowPrice, self.item.currency, self.item.country);
+    std::u16string highPrice = getFormattedCurrentPrice(
+        self.item.highPrice, self.item.currency, self.item.country);
+
+    priceTrackingSubtitle.numberOfLines = 2;
     priceTrackingSubtitle.text =
         [self hasVariants]
             ? ([self hasPriceOneTypicalPrice]
                    ? l10n_util::GetNSStringF(
                          IDS_PRICE_RANGE_ALL_OPTIONS_ONE_TYPICAL_PRICE,
-                         base::SysNSStringToUTF16(self.item.lowPrice))
-                   : l10n_util::GetNSStringF(
-                         IDS_PRICE_RANGE_ALL_OPTIONS,
-                         base::SysNSStringToUTF16(self.item.lowPrice),
-                         base::SysNSStringToUTF16(self.item.highPrice)))
+                         lowPrice)
+                   : l10n_util::GetNSStringF(IDS_PRICE_RANGE_ALL_OPTIONS,
+                                             lowPrice, highPrice))
             : ([self hasPriceOneTypicalPrice]
                    ? l10n_util::GetNSStringF(
                          IDS_PRICE_RANGE_SINGLE_OPTION_ONE_TYPICAL_PRICE,
-                         base::SysNSStringToUTF16(self.item.lowPrice))
-                   : l10n_util::GetNSStringF(
-                         IDS_PRICE_RANGE_SINGLE_OPTION,
-                         base::SysNSStringToUTF16(self.item.lowPrice),
-                         base::SysNSStringToUTF16(self.item.highPrice)));
+                         lowPrice)
+                   : l10n_util::GetNSStringF(IDS_PRICE_RANGE_SINGLE_OPTION,
+                                             lowPrice, highPrice));
   } else {
     priceTrackingSubtitle.numberOfLines = 2;
     priceTrackingSubtitle.text =
@@ -307,6 +340,7 @@
   verticalStack.axis = UILayoutConstraintAxisVertical;
   verticalStack.distribution = UIStackViewDistributionFill;
   verticalStack.alignment = UIStackViewAlignmentLeading;
+  verticalStack.spacing = kPriceTrackingVerticalStackViewSpacing;
 
   UILabel* title = [self createLabel];
   [title setAccessibilityIdentifier:kPriceHistoryTitleIdentifier];
@@ -340,9 +374,10 @@
     }
   }
 
-  UIViewController* priceHistoryViewController =
-      [PriceHistoryProvider makeViewControllerWithHistory:self.item.priceHistory
-                                                 currency:self.item.currency];
+  UIViewController* priceHistoryViewController = [PriceHistoryProvider
+      makeViewControllerWithHistory:self.item.priceHistory
+                           currency:base::SysUTF8ToNSString(
+                                        self.item.currency)];
   priceHistoryViewController.view.translatesAutoresizingMaskIntoConstraints =
       NO;
   [self.viewController addChildViewController:priceHistoryViewController];
@@ -370,6 +405,65 @@
                     kContentVerticalInset, kContentHorizontalInset);
 }
 
+- (void)configurePriceRangeWithTitle:(NSString*)titleText
+                            subtitle:(NSString*)primarySubtitleText {
+  UIStackView* labelStackView = [[UIStackView alloc] init];
+  labelStackView.axis = UILayoutConstraintAxisVertical;
+  labelStackView.distribution = UIStackViewDistributionFill;
+  labelStackView.alignment = UIStackViewAlignmentLeading;
+  labelStackView.spacing = kPriceTrackingVerticalStackViewSpacing;
+
+  UILabel* title = [self createLabel];
+  [title setAccessibilityIdentifier:kPriceRangeTitleIdentifier];
+  title.font =
+      CreateDynamicFont(UIFontTextStyleSubheadline, UIFontWeightSemibold);
+  title.text = titleText;
+  title.numberOfLines = 2;
+  title.textColor = [UIColor colorNamed:kTextPrimaryColor];
+  [labelStackView addArrangedSubview:title];
+
+  if (primarySubtitleText.length) {
+    UILabel* primarySubtitle = [self createLabel];
+    [primarySubtitle setAccessibilityIdentifier:kPriceRangeSubtitleIdentifier];
+    primarySubtitle.font =
+        CreateDynamicFont(UIFontTextStyleFootnote, UIFontWeightRegular);
+    primarySubtitle.text = primarySubtitleText;
+    primarySubtitle.textColor = [UIColor colorNamed:kTextSecondaryColor];
+    [labelStackView addArrangedSubview:primarySubtitle];
+  }
+
+  std::u16string lowPriceFormatted = getFormattedCurrentPrice(
+      self.item.lowPrice, self.item.currency, self.item.country);
+  std::u16string highPriceFormatted = getFormattedCurrentPrice(
+      self.item.highPrice, self.item.currency, self.item.country);
+  CGRect contentArea = [UIScreen mainScreen].bounds;
+  CGFloat sliderViewWidth = contentArea.size.width -
+                            (kContentHorizontalInset * 2) -
+                            (kHorizontalInset * 2);
+
+  PriceRangeSliderView* sliderStackView = [[PriceRangeSliderView alloc]
+      initWithMinimumLabelText:base::SysUTF16ToNSString(lowPriceFormatted)
+              maximumLabelText:base::SysUTF16ToNSString(highPriceFormatted)
+                  minimumValue:self.item.lowPrice
+                  maximumValue:self.item.highPrice
+                  currentValue:self.item.currentPrice
+               sliderViewWidth:sliderViewWidth];
+
+  _priceRangeStackView = [[UIStackView alloc]
+      initWithArrangedSubviews:@[ labelStackView, sliderStackView ]];
+  [_priceRangeStackView
+      setAccessibilityIdentifier:kPriceRangeStackViewIdentifier];
+  _priceRangeStackView.axis = UILayoutConstraintAxisVertical;
+  _priceRangeStackView.spacing = kPriceRangeContentSpacing;
+  _priceRangeStackView.distribution = UIStackViewDistributionFill;
+  _priceRangeStackView.translatesAutoresizingMaskIntoConstraints = NO;
+  _priceRangeStackView.backgroundColor = [UIColor colorNamed:kBackgroundColor];
+  _priceRangeStackView.layoutMarginsRelativeArrangement = YES;
+  _priceRangeStackView.layoutMargins =
+      UIEdgeInsets(kContentVerticalInset, kContentHorizontalInset,
+                   kContentVerticalInset, kContentHorizontalInset);
+}
+
 // Creates and configures a UILabel with default settings.
 - (UILabel*)createLabel {
   UILabel* label = [[UILabel alloc] init];
diff --git a/ios/chrome/browser/price_insights/ui/price_insights_cell_unittest.mm b/ios/chrome/browser/price_insights/ui/price_insights_cell_unittest.mm
index a0a1be3..a455525 100644
--- a/ios/chrome/browser/price_insights/ui/price_insights_cell_unittest.mm
+++ b/ios/chrome/browser/price_insights/ui/price_insights_cell_unittest.mm
@@ -19,9 +19,12 @@
 
 NSString* kTitle = @"Product title";
 NSString* kVariant = @"Product variant";
-NSString* kLowPrice = @"$699";
-NSString* kHighPrice = @"$799";
-NSString* kCurrency = @"USD";
+int64_t kLowPrice = 699000000L;
+NSString* kLowPriceString = @"$699.00";
+int64_t kHighPrice = 799000000L;
+NSString* kHighPriceString = @"$799.00";
+std::string kCurrency = "USD";
+std::string kCountryCode = "us";
 
 // Retrieves a view of a specified class with a given accessibility identifier
 // within a given view hierarchy.
@@ -76,6 +79,7 @@
   item.canPriceTrack = has_tracking;
   item.buyingOptionsURL = has_buying_options ? GURL(kUrl) : GURL();
   item.currency = kCurrency;
+  item.country = kCountryCode;
 
   if (has_history) {
     NSDateFormatter* dateFormat = [[NSDateFormatter alloc] init];
@@ -158,8 +162,9 @@
       /*has_buying_options=*/true);
   [cell_ configureWithItem:item];
 
-  CheckNumberOfComponents(1ul);
+  CheckNumberOfComponents(2ul);
   CheckPositionOfComponent(kPriceTrackingStackViewIdentifier, 0);
+  CheckPositionOfComponent(kPriceRangeStackViewIdentifier, 1);
 }
 
 // Test the order of components in the content view when Price Range is the only
@@ -241,11 +246,12 @@
   EXPECT_TRUE([title.text isEqualToString:kTitle]);
   UILabel* subtitle = GetLabelFromIdentifier(kPriceTrackingSubtitleIdentifier,
                                              cell_.contentView);
+
   EXPECT_TRUE([subtitle.text
       isEqualToString:l10n_util::GetNSStringF(
                           IDS_PRICE_RANGE_SINGLE_OPTION,
-                          base::SysNSStringToUTF16(item.lowPrice),
-                          base::SysNSStringToUTF16(item.highPrice))]);
+                          base::SysNSStringToUTF16(kLowPriceString),
+                          base::SysNSStringToUTF16(kHighPriceString))]);
 }
 
 // Tests the presence of UI elements in the Price Tracking components when all
@@ -268,8 +274,8 @@
   EXPECT_TRUE([subtitle.text
       isEqualToString:l10n_util::GetNSStringF(
                           IDS_PRICE_RANGE_ALL_OPTIONS,
-                          base::SysNSStringToUTF16(item.lowPrice),
-                          base::SysNSStringToUTF16(item.highPrice))]);
+                          base::SysNSStringToUTF16(kLowPriceString),
+                          base::SysNSStringToUTF16(kHighPriceString))]);
 }
 
 // Tests the presence of UI elements in the Price Tracking components when all
@@ -292,7 +298,7 @@
   EXPECT_TRUE([subtitle.text
       isEqualToString:l10n_util::GetNSStringF(
                           IDS_PRICE_RANGE_ALL_OPTIONS_ONE_TYPICAL_PRICE,
-                          base::SysNSStringToUTF16(item.lowPrice))]);
+                          base::SysNSStringToUTF16(kLowPriceString))]);
 }
 
 // Tests the presence of UI elements in the Price Tracking components when all
@@ -316,7 +322,7 @@
   EXPECT_TRUE([subtitle.text
       isEqualToString:l10n_util::GetNSStringF(
                           IDS_PRICE_RANGE_SINGLE_OPTION_ONE_TYPICAL_PRICE,
-                          base::SysNSStringToUTF16(item.lowPrice))]);
+                          base::SysNSStringToUTF16(kLowPriceString))]);
 }
 
 // Tests the presence of UI elements in the Price Tracking components when Price
@@ -497,3 +503,133 @@
       kPriceHistorySecondarySubtitleIdentifier, cell_.contentView);
   EXPECT_EQ(NULL, secondary_subtitle);
 }
+
+// Tests the presence of UI elements in the Price Range components when Price
+// Range and Price Tracking are available, with variants.
+TEST_F(PriceInsightsCellTest, TestPriceRangeWithTrackingAndVariant) {
+  PriceInsightsItem* item = GetPriceInsights(
+      /*has_variant=*/true,
+      /*has_tracking=*/true,
+      /*has_range=*/true,
+      /*has_single_range=*/false,
+      /*has_history=*/false,
+      /*has_buying_options=*/true);
+  [cell_ configureWithItem:item];
+
+  CheckNumberOfComponents(2ul);
+  CheckPositionOfComponent(kPriceTrackingStackViewIdentifier, 0);
+  CheckPositionOfComponent(kPriceRangeStackViewIdentifier, 1);
+
+  UILabel* title =
+      GetLabelFromIdentifier(kPriceRangeTitleIdentifier, cell_.contentView);
+  EXPECT_TRUE([title.text
+      isEqualToString:l10n_util::GetNSString(
+                          IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE_VARIANT)]);
+  UILabel* subtitle =
+      GetLabelFromIdentifier(kPriceRangeSubtitleIdentifier, cell_.contentView);
+  EXPECT_EQ(NULL, subtitle);
+
+  UILabel* lowPrice = GetLabelFromIdentifier(
+      kPriceRangeSliderLowPriceIdentifier, cell_.contentView);
+  EXPECT_TRUE([lowPrice.text isEqualToString:kLowPriceString]);
+  UILabel* highPrice = GetLabelFromIdentifier(
+      kPriceRangeSliderHighPriceIdentifier, cell_.contentView);
+  EXPECT_TRUE([highPrice.text isEqualToString:kHighPriceString]);
+}
+
+// Tests the presence of UI elements in the Price Range components when Price
+// Range and Price Tracking are available, without any variants.
+TEST_F(PriceInsightsCellTest, TestPriceRangeWithTrackingAndNoVariant) {
+  PriceInsightsItem* item = GetPriceInsights(
+      /*has_variant=*/false,
+      /*has_tracking=*/true,
+      /*has_range=*/true,
+      /*has_single_range=*/false,
+      /*has_history=*/false,
+      /*has_buying_options=*/true);
+  [cell_ configureWithItem:item];
+
+  CheckNumberOfComponents(2ul);
+  CheckPositionOfComponent(kPriceTrackingStackViewIdentifier, 0);
+  CheckPositionOfComponent(kPriceRangeStackViewIdentifier, 1);
+
+  UILabel* title =
+      GetLabelFromIdentifier(kPriceRangeTitleIdentifier, cell_.contentView);
+  EXPECT_TRUE([title.text
+      isEqualToString:l10n_util::GetNSString(
+                          IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE_NO_VARIANT)]);
+  UILabel* subtitle =
+      GetLabelFromIdentifier(kPriceRangeSubtitleIdentifier, cell_.contentView);
+  EXPECT_EQ(NULL, subtitle);
+
+  UILabel* lowPrice = GetLabelFromIdentifier(
+      kPriceRangeSliderLowPriceIdentifier, cell_.contentView);
+  EXPECT_TRUE([lowPrice.text isEqualToString:kLowPriceString]);
+  UILabel* highPrice = GetLabelFromIdentifier(
+      kPriceRangeSliderHighPriceIdentifier, cell_.contentView);
+  EXPECT_TRUE([highPrice.text isEqualToString:kHighPriceString]);
+}
+
+// Tests the presence of UI elements in the Price Range components when only
+// Price Range is available, with variants.
+TEST_F(PriceInsightsCellTest, TestPriceRangeAndWithVariant) {
+  PriceInsightsItem* item = GetPriceInsights(
+      /*has_variant=*/true,
+      /*has_tracking=*/false,
+      /*has_range=*/true,
+      /*has_single_range=*/false,
+      /*has_history=*/false,
+      /*has_buying_options=*/true);
+  [cell_ configureWithItem:item];
+
+  CheckNumberOfComponents(1ul);
+  CheckPositionOfComponent(kPriceRangeStackViewIdentifier, 0);
+
+  UILabel* title =
+      GetLabelFromIdentifier(kPriceRangeTitleIdentifier, cell_.contentView);
+  EXPECT_TRUE([title.text isEqualToString:item.title]);
+  UILabel* subtitle =
+      GetLabelFromIdentifier(kPriceRangeSubtitleIdentifier, cell_.contentView);
+  EXPECT_TRUE([subtitle.text
+      isEqualToString:l10n_util::GetNSString(
+                          IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE_VARIANT)]);
+
+  UILabel* lowPrice = GetLabelFromIdentifier(
+      kPriceRangeSliderLowPriceIdentifier, cell_.contentView);
+  EXPECT_TRUE([lowPrice.text isEqualToString:kLowPriceString]);
+  UILabel* highPrice = GetLabelFromIdentifier(
+      kPriceRangeSliderHighPriceIdentifier, cell_.contentView);
+  EXPECT_TRUE([highPrice.text isEqualToString:kHighPriceString]);
+}
+
+// Tests the presence of UI elements in the Price Range components when only
+// Price Range is available,  without any variants.
+TEST_F(PriceInsightsCellTest, TestPriceRangeAndWithNoVariant) {
+  PriceInsightsItem* item = GetPriceInsights(
+      /*has_variant=*/false,
+      /*has_tracking=*/false,
+      /*has_range=*/true,
+      /*has_single_range=*/false,
+      /*has_history=*/false,
+      /*has_buying_options=*/true);
+  [cell_ configureWithItem:item];
+
+  CheckNumberOfComponents(1ul);
+  CheckPositionOfComponent(kPriceRangeStackViewIdentifier, 0);
+
+  UILabel* title =
+      GetLabelFromIdentifier(kPriceRangeTitleIdentifier, cell_.contentView);
+  EXPECT_TRUE([title.text isEqualToString:item.title]);
+  UILabel* subtitle =
+      GetLabelFromIdentifier(kPriceRangeSubtitleIdentifier, cell_.contentView);
+  EXPECT_TRUE([subtitle.text
+      isEqualToString:l10n_util::GetNSString(
+                          IDS_PRICE_INSIGHTS_PRICE_RANGE_TITLE_NO_VARIANT)]);
+
+  UILabel* lowPrice = GetLabelFromIdentifier(
+      kPriceRangeSliderLowPriceIdentifier, cell_.contentView);
+  EXPECT_TRUE([lowPrice.text isEqualToString:kLowPriceString]);
+  UILabel* highPrice = GetLabelFromIdentifier(
+      kPriceRangeSliderHighPriceIdentifier, cell_.contentView);
+  EXPECT_TRUE([highPrice.text isEqualToString:kHighPriceString]);
+}
diff --git a/ios/chrome/browser/price_insights/ui/price_insights_constants.h b/ios/chrome/browser/price_insights/ui/price_insights_constants.h
index e549893..8b4e240 100644
--- a/ios/chrome/browser/price_insights/ui/price_insights_constants.h
+++ b/ios/chrome/browser/price_insights/ui/price_insights_constants.h
@@ -33,5 +33,19 @@
 extern NSString* const kPriceHistorySecondarySubtitleIdentifier;
 // Accessibility identifier for the graph of price history.
 extern NSString* const kPriceHistoryGraphIdentifier;
+// Accessibility identifier for the title label of price range.
+extern NSString* const kPriceRangeTitleIdentifier;
+// Accessibility identifier for the subtitle label of price range.
+extern NSString* const kPriceRangeSubtitleIdentifier;
+// Accessibility identifier for the price range stack view.
+extern NSString* const kPriceRangeStackViewIdentifier;
+// Accessibility identifier for the low label of the price range slider.
+extern NSString* const kPriceRangeSliderLowLabelIdentifier;
+// Accessibility identifier for the low price of the price range slider.
+extern NSString* const kPriceRangeSliderLowPriceIdentifier;
+// Accessibility identifier for the high label of the price range slider.
+extern NSString* const kPriceRangeSliderHighLabelIdentifier;
+// Accessibility identifier for the high price of the price range slider.
+extern NSString* const kPriceRangeSliderHighPriceIdentifier;
 
 #endif  // IOS_CHROME_BROWSER_PRICE_INSIGHTS_UI_PRICE_INSIGHTS_CONSTANTS_H_
diff --git a/ios/chrome/browser/price_insights/ui/price_insights_constants.mm b/ios/chrome/browser/price_insights/ui/price_insights_constants.mm
index d2cda115..f9a8c83 100644
--- a/ios/chrome/browser/price_insights/ui/price_insights_constants.mm
+++ b/ios/chrome/browser/price_insights/ui/price_insights_constants.mm
@@ -25,3 +25,15 @@
 NSString* const kPriceHistorySecondarySubtitleIdentifier =
     @"priceHistorySecondarySubtitleIdentifier";
 NSString* const kPriceHistoryGraphIdentifier = @"priceHistoryGraphIdentifier";
+NSString* const kPriceRangeTitleIdentifier = @"PriceRangeTitleIdentifier";
+NSString* const kPriceRangeSubtitleIdentifier = @"PriceRangeSubtitleIdentifier";
+NSString* const kPriceRangeStackViewIdentifier =
+    @"kPriceRangeStackViewIdentifier";
+NSString* const kPriceRangeSliderLowLabelIdentifier =
+    @"PriceRangeSliderLowLabelIdentifier";
+NSString* const kPriceRangeSliderLowPriceIdentifier =
+    @"PriceRangeSliderLowPriceIdentifier";
+NSString* const kPriceRangeSliderHighLabelIdentifier =
+    @"PriceRangeSliderHighLabelIdentifier";
+NSString* const kPriceRangeSliderHighPriceIdentifier =
+    @"PriceRangeSliderHighPriceIdentifier";
diff --git a/ios/chrome/browser/price_insights/ui/price_insights_item.h b/ios/chrome/browser/price_insights/ui/price_insights_item.h
index 808843e..2b96b9b6 100644
--- a/ios/chrome/browser/price_insights/ui/price_insights_item.h
+++ b/ios/chrome/browser/price_insights/ui/price_insights_item.h
@@ -7,6 +7,8 @@
 
 #import <UIKit/UIKit.h>
 
+#include <string>
+
 class GURL;
 
 // Base object for Price Insights data. This will be used to pass the data to
@@ -18,11 +20,15 @@
 // The product variants.
 @property(nonatomic, copy) NSString* variants;
 // The product typically low price.
-@property(nonatomic, copy) NSString* lowPrice;
+@property(nonatomic, assign) int64_t lowPrice;
 // The product typically high price.
-@property(nonatomic, copy) NSString* highPrice;
+@property(nonatomic, assign) int64_t highPrice;
+// The product current price.
+@property(nonatomic, assign) int64_t currentPrice;
 // The product price currency.
-@property(nonatomic, copy) NSString* currency;
+@property(nonatomic, assign) std::string currency;
+// The product country code.
+@property(nonatomic, assign) std::string country;
 // The price history.
 @property(nonatomic, copy) NSDictionary* priceHistory;
 // The product buying options URL.
diff --git a/ios/chrome/browser/price_insights/ui/price_ranger_slider.h b/ios/chrome/browser/price_insights/ui/price_ranger_slider.h
new file mode 100644
index 0000000..8b8fc23f
--- /dev/null
+++ b/ios/chrome/browser/price_insights/ui/price_ranger_slider.h
@@ -0,0 +1,33 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_PRICE_INSIGHTS_UI_PRICE_RANGER_SLIDER_H_
+#define IOS_CHROME_BROWSER_PRICE_INSIGHTS_UI_PRICE_RANGER_SLIDER_H_
+
+#import <UIKit/UIKit.h>
+
+// A custom UISlider designed for displaying and adjusting price ranges.
+@interface PriceRangeSlider : UISlider
+
+@end
+
+// A UIStackView including labels, a UISlider, and horizontal line with rounded
+// corners.
+@interface PriceRangeSliderView : UIStackView
+
+- (instancetype)initWithMinimumLabelText:(NSString*)minimumLabelText
+                        maximumLabelText:(NSString*)maximumLabelText
+                            minimumValue:(int64_t)minimumValue
+                            maximumValue:(int64_t)maximumValue
+                            currentValue:(int64_t)currentValue
+                         sliderViewWidth:(CGFloat)sliderViewWidth
+    NS_DESIGNATED_INITIALIZER;
+
+- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
+
+- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_PRICE_INSIGHTS_UI_PRICE_RANGER_SLIDER_H_
diff --git a/ios/chrome/browser/price_insights/ui/price_ranger_slider.mm b/ios/chrome/browser/price_insights/ui/price_ranger_slider.mm
new file mode 100644
index 0000000..cdd6f7d
--- /dev/null
+++ b/ios/chrome/browser/price_insights/ui/price_ranger_slider.mm
@@ -0,0 +1,238 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/price_insights/ui/price_ranger_slider.h"
+
+#import "components/strings/grit/components_strings.h"
+#import "ios/chrome/browser/price_insights/ui/price_insights_constants.h"
+#import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
+#import "ios/chrome/common/ui/colors/semantic_color_names.h"
+#import "ui/base/l10n/l10n_util_mac.h"
+
+namespace {
+
+// The height of the slider track.
+const CGFloat kTrackHeight = 4.0f;
+
+// The width of the circle stroke around the slider thumb.
+const CGFloat kCircleStroke = 2.0f;
+
+// The height of the background line behind the slider.
+const CGFloat kBackgroundLineHeight = 2.0f;
+
+// The diameter of the circle representing the slider thumb.
+const CGFloat kCircleDiameter = 12.0f;
+
+// The relative width of the slider compared to its container.
+const CGFloat kSliderWidthRatio = 0.56f;
+
+// Size of the space between the slider and the labels.
+const CGFloat kSliderViewContentSpacing = 10.0f;
+
+}  // namespace
+
+@implementation PriceRangeSlider
+
+- (instancetype)init {
+  self = [super init];
+  if (self) {
+    UIImage* thumbImage = [self createCircleImage];
+    [self setThumbImage:thumbImage forState:UIControlStateNormal];
+    self.maximumTrackTintColor = [UIColor colorNamed:kBlue600Color];
+    self.minimumTrackTintColor = [UIColor colorNamed:kBlue600Color];
+    self.userInteractionEnabled = NO;
+  }
+  return self;
+}
+
+- (CGRect)trackRectForBounds:(CGRect)bounds {
+  CGRect rect = [super trackRectForBounds:bounds];
+  rect.size.height = kTrackHeight;
+  CGFloat verticalCenter = bounds.size.height / 2;
+  //  Adjust the track's y-origin to center it vertically
+  rect.origin.y = verticalCenter - (kTrackHeight / 2);
+  return rect;
+}
+
+#pragma mark - Private
+
+// Creates a circular image with a specified diameter, stroke width, and colors.
+- (UIImage*)createCircleImage {
+  CGFloat circleDiameter = kCircleDiameter + kCircleStroke;
+  CGRect rect = CGRectMake(0.0f, 0.0f, circleDiameter, circleDiameter);
+  UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0f);
+  CGContextRef context = UIGraphicsGetCurrentContext();
+  CGContextSetLineWidth(context, kCircleStroke);
+  [[UIColor colorNamed:kBackgroundColor] setStroke];
+  [[UIColor colorNamed:kBlue600Color] setFill];
+  CGContextAddEllipseInRect(
+      context, CGRectInset(rect, kCircleStroke / 2, kCircleStroke / 2));
+  CGContextDrawPath(context, kCGPathFillStroke);
+  UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
+  UIGraphicsEndImageContext();
+
+  return image;
+}
+
+@end
+
+@implementation PriceRangeSliderView {
+  NSString* _minimumLabelText;
+  NSString* _maximumLabelText;
+  CGFloat _sliderHorizontalInset;
+  CGFloat _sliderWidth;
+  int64_t _minimumValue;
+  int64_t _maximumValue;
+  int64_t _currentValue;
+}
+
+- (instancetype)initWithMinimumLabelText:(NSString*)minimumLabelText
+                        maximumLabelText:(NSString*)maximumLabelText
+                            minimumValue:(int64_t)minimumValue
+                            maximumValue:(int64_t)maximumValue
+                            currentValue:(int64_t)currentValue
+                         sliderViewWidth:(CGFloat)sliderViewWidth {
+  self = [super initWithFrame:CGRectZero];
+  if (self) {
+    _minimumLabelText = minimumLabelText;
+    _maximumLabelText = maximumLabelText;
+    _minimumValue = minimumValue;
+    _maximumValue = maximumValue;
+    _currentValue = currentValue;
+    _sliderWidth = sliderViewWidth * kSliderWidthRatio;
+    _sliderHorizontalInset = sliderViewWidth * (1 - kSliderWidthRatio) / 2;
+
+    self.axis = UILayoutConstraintAxisVertical;
+    self.spacing = kSliderViewContentSpacing;
+    self.alignment = UIStackViewAlignmentFill;
+
+    [self createSlider];
+    [self createSliderLabels];
+  }
+  return self;
+}
+
+#pragma mark - Private
+
+// Creates and configures a price range slider view with a horizontal line
+// indicator.
+- (void)createSlider {
+  UIView* sliderContentView = [[UIView alloc] init];
+  sliderContentView.translatesAutoresizingMaskIntoConstraints = NO;
+
+  UIView* horizontalLineView = [self createHorizontalLine];
+  [sliderContentView addSubview:horizontalLineView];
+
+  PriceRangeSlider* slider = [[PriceRangeSlider alloc] init];
+  slider.minimumValue = _minimumValue;
+  slider.maximumValue = _maximumValue;
+  slider.value = _currentValue;
+  slider.translatesAutoresizingMaskIntoConstraints = NO;
+  [sliderContentView addSubview:slider];
+
+  [self addArrangedSubview:sliderContentView];
+
+  [NSLayoutConstraint activateConstraints:@[
+    [sliderContentView.leadingAnchor
+        constraintEqualToAnchor:self.leadingAnchor],
+    [sliderContentView.trailingAnchor
+        constraintEqualToAnchor:self.trailingAnchor],
+    [horizontalLineView.heightAnchor
+        constraintEqualToConstant:kBackgroundLineHeight],
+    [horizontalLineView.leadingAnchor
+        constraintEqualToAnchor:sliderContentView.leadingAnchor],
+    [horizontalLineView.trailingAnchor
+        constraintEqualToAnchor:sliderContentView.trailingAnchor],
+    [horizontalLineView.centerYAnchor
+        constraintEqualToAnchor:sliderContentView.centerYAnchor],
+    [slider.centerYAnchor
+        constraintEqualToAnchor:sliderContentView.centerYAnchor],
+    [slider.centerXAnchor
+        constraintEqualToAnchor:sliderContentView.centerXAnchor],
+    [slider.widthAnchor constraintEqualToConstant:_sliderWidth],
+  ]];
+}
+
+// Creates and arranges labels for a price range slider component.
+- (void)createSliderLabels {
+  UILabel* lowLabel =
+      [self createLabelWithText:l10n_util::GetNSString(
+                                    IDS_PRICE_INSIGHTS_RANGE_LABEL_LOW)
+          accessibilityIdentifier:kPriceRangeSliderLowLabelIdentifier];
+  UILabel* minimumLabel =
+      [self createLabelWithText:_minimumLabelText
+          accessibilityIdentifier:kPriceRangeSliderLowPriceIdentifier];
+  UILabel* maximumLabel =
+      [self createLabelWithText:_maximumLabelText
+          accessibilityIdentifier:kPriceRangeSliderHighPriceIdentifier];
+  UILabel* highLabel =
+      [self createLabelWithText:l10n_util::GetNSString(
+                                    IDS_PRICE_INSIGHTS_RANGE_LABEL_HIGH)
+          accessibilityIdentifier:kPriceRangeSliderHighLabelIdentifier];
+
+  UIStackView* leftStackView = [self createHorizontalStackView];
+  [leftStackView addArrangedSubview:lowLabel];
+  [leftStackView addArrangedSubview:minimumLabel];
+
+  UIStackView* rightStackView = [self createHorizontalStackView];
+  [rightStackView addArrangedSubview:maximumLabel];
+  [rightStackView addArrangedSubview:highLabel];
+
+  UIStackView* labelStackView = [self createHorizontalStackView];
+  [labelStackView addArrangedSubview:leftStackView];
+  [labelStackView addArrangedSubview:rightStackView];
+
+  [self addArrangedSubview:labelStackView];
+
+  [NSLayoutConstraint activateConstraints:@[
+    [minimumLabel.centerXAnchor
+        constraintGreaterThanOrEqualToAnchor:leftStackView.leadingAnchor
+                                    constant:_sliderHorizontalInset],
+    [maximumLabel.centerXAnchor
+        constraintLessThanOrEqualToAnchor:rightStackView.trailingAnchor
+                                 constant:-(_sliderHorizontalInset)],
+    [labelStackView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor],
+    [labelStackView.trailingAnchor constraintEqualToAnchor:self.trailingAnchor],
+  ]];
+}
+
+// Creates and configures a UILabels.
+- (UILabel*)createLabelWithText:(NSString*)text
+        accessibilityIdentifier:(NSString*)identifier {
+  UILabel* label = [[UILabel alloc] init];
+  label.textAlignment = NSTextAlignmentLeft;
+  label.adjustsFontForContentSizeCategory = YES;
+  label.adjustsFontSizeToFitWidth = NO;
+  label.lineBreakMode = NSLineBreakByTruncatingTail;
+  label.translatesAutoresizingMaskIntoConstraints = NO;
+  label.numberOfLines = 1;
+  label.accessibilityIdentifier = identifier;
+  label.font = CreateDynamicFont(UIFontTextStyleFootnote, UIFontWeightRegular);
+  label.text = text;
+  label.translatesAutoresizingMaskIntoConstraints = NO;
+  label.textColor = [UIColor colorNamed:kTextSecondaryColor];
+  return label;
+}
+
+// Creates a UIView configured as a horizontal line with rounded corners.
+- (UIView*)createHorizontalLine {
+  UIView* containerStackView = [[UIView alloc] init];
+  containerStackView.translatesAutoresizingMaskIntoConstraints = NO;
+  containerStackView.backgroundColor = [UIColor colorNamed:kGrey300Color];
+  containerStackView.layer.cornerRadius = kBackgroundLineHeight / 2;
+  return containerStackView;
+}
+
+// Creates and configures a horizontal UIStackView with equal spacing and center
+// alignment.
+- (UIStackView*)createHorizontalStackView {
+  UIStackView* stackView = [[UIStackView alloc] init];
+  stackView.axis = UILayoutConstraintAxisHorizontal;
+  stackView.distribution = UIStackViewDistributionEqualSpacing;
+  stackView.alignment = UIStackViewAlignmentCenter;
+  stackView.translatesAutoresizingMaskIntoConstraints = NO;
+  return stackView;
+}
+
+@end
diff --git a/ios/chrome/browser/promos_manager/model/promos_manager_impl.mm b/ios/chrome/browser/promos_manager/model/promos_manager_impl.mm
index b78625b753..d8eca1f1 100644
--- a/ios/chrome/browser/promos_manager/model/promos_manager_impl.mm
+++ b/ios/chrome/browser/promos_manager/model/promos_manager_impl.mm
@@ -32,17 +32,6 @@
 
 namespace {
 
-// Killswitch to control the hard-coded DockingPromo and
-// DockingPromoRemindMeLater sort injections in `SortPromos()`.
-BASE_FEATURE(kPromosManagerDockingPromoSortKillswitch,
-             "PromosManagerDockingPromoSortKillswitch",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
-// Killswitch to control new DockingPromo histograms.
-BASE_FEATURE(kPromosManagerDockingPromoHistogramsKillswitch,
-             "PromosManagerDockingPromoHistogramsKillswitch",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
 // Conditionally appends `promo` to the list pref `pref_path`. If `promo`
 // already exists in the list pref `pref_path`, does nothing. If `promo` doesn't
 // exist in the list pref `pref_path`, appends `promo` to the list.
@@ -230,26 +219,6 @@
                                 valid_promo_count,
                                 static_cast<int>(Promo::kMaxValue) + 1);
 
-  promos_manager::Promo promo = first_promo_opt.value();
-
-  // TODO(crbug.com/330387623): Cleanup Docking Promo histograms.
-  if (base::FeatureList::IsEnabled(
-          kPromosManagerDockingPromoHistogramsKillswitch)) {
-    if (active_promos_with_context.contains(Promo::DockingPromo) &&
-        promo != Promo::DockingPromo &&
-        CanShowPromoWithoutTrigger(Promo::DockingPromo)) {
-      base::UmaHistogramEnumeration("IOS.DockingPromo.LostToCompetingPromo",
-                                    promo);
-    }
-
-    if (active_promos_with_context.contains(Promo::DockingPromoRemindMeLater) &&
-        promo != Promo::DockingPromoRemindMeLater &&
-        CanShowPromoWithoutTrigger(Promo::DockingPromoRemindMeLater)) {
-      base::UmaHistogramEnumeration(
-          "IOS.DockingPromoRemindMeLater.LostToCompetingPromo", promo);
-    }
-  }
-
   return first_promo_opt;
 }
 
@@ -366,24 +335,6 @@
     if (rhs.first == Promo::PostDefaultAbandonment) {
       return false;
     }
-    // TODO(crbug.com/330387623): Cleanup hard-coded Docking Promo sort logic.
-    if (base::FeatureList::IsEnabled(
-            kPromosManagerDockingPromoSortKillswitch)) {
-      // Docking Promo comes next.
-      if (lhs.first == Promo::DockingPromo) {
-        return true;
-      }
-      if (rhs.first == Promo::DockingPromo) {
-        return false;
-      }
-      // Docking Promo (Remind Me Later) comes next.
-      if (lhs.first == Promo::DockingPromoRemindMeLater) {
-        return true;
-      }
-      if (rhs.first == Promo::DockingPromoRemindMeLater) {
-        return false;
-      }
-    }
     // prefer the promo with pending state to the other without.
     if (lhs.second.was_pending && !rhs.second.was_pending) {
       return true;
diff --git a/ios/chrome/browser/promos_manager/model/promos_manager_impl_unittest.mm b/ios/chrome/browser/promos_manager/model/promos_manager_impl_unittest.mm
index 992e8b7f1..6cfd5e7 100644
--- a/ios/chrome/browser/promos_manager/model/promos_manager_impl_unittest.mm
+++ b/ios/chrome/browser/promos_manager/model/promos_manager_impl_unittest.mm
@@ -418,46 +418,6 @@
   EXPECT_EQ(sorted[3], promos_manager::Promo::Test);
 }
 
-// Tests `SortPromos` sorts `DockingPromo` promos before others.
-TEST_F(PromosManagerImplTest, SortsPromosPreferDockingPromoType) {
-  CreatePromosManager();
-
-  const std::map<promos_manager::Promo, PromoContext> active_promos = {
-      {promos_manager::Promo::Test, PromoContext{false}},
-      {promos_manager::Promo::AllTabsDefaultBrowser, PromoContext{true}},
-      {promos_manager::Promo::DockingPromo, PromoContext{false}},
-  };
-
-  std::vector<promos_manager::Promo> sorted =
-      promos_manager_->SortPromos(active_promos);
-  EXPECT_EQ(sorted.size(), (size_t)3);
-  // tied for the type.
-  EXPECT_TRUE(sorted[0] == promos_manager::Promo::DockingPromo);
-  // with pending state, before the less recently shown promo (Test).
-  EXPECT_EQ(sorted[1], promos_manager::Promo::AllTabsDefaultBrowser);
-  EXPECT_EQ(sorted[2], promos_manager::Promo::Test);
-}
-
-// Tests `SortPromos` sorts `DockingPromoRemindMeLater` promos before others.
-TEST_F(PromosManagerImplTest, SortsPromosPreferDockingPromoRemindMeLaterType) {
-  CreatePromosManager();
-
-  const std::map<promos_manager::Promo, PromoContext> active_promos = {
-      {promos_manager::Promo::Test, PromoContext{false}},
-      {promos_manager::Promo::AllTabsDefaultBrowser, PromoContext{true}},
-      {promos_manager::Promo::DockingPromoRemindMeLater, PromoContext{false}},
-  };
-
-  std::vector<promos_manager::Promo> sorted =
-      promos_manager_->SortPromos(active_promos);
-  EXPECT_EQ(sorted.size(), (size_t)3);
-  // tied for the type.
-  EXPECT_TRUE(sorted[0] == promos_manager::Promo::DockingPromoRemindMeLater);
-  // with pending state, before the less recently shown promo (Test).
-  EXPECT_EQ(sorted[1], promos_manager::Promo::AllTabsDefaultBrowser);
-  EXPECT_EQ(sorted[2], promos_manager::Promo::Test);
-}
-
 // Tests `SortPromos` sorts promos with pending state before others without.
 TEST_F(PromosManagerImplTest, SortsPromosPreferPendingToNonPending) {
   CreatePromosManager();
diff --git a/ios/chrome/browser/sessions/proto/tab_group.proto b/ios/chrome/browser/sessions/proto/tab_group.proto
index b74ce880..2593179 100644
--- a/ios/chrome/browser/sessions/proto/tab_group.proto
+++ b/ios/chrome/browser/sessions/proto/tab_group.proto
@@ -30,6 +30,14 @@
   int32 count = 2;
 }
 
+// Represents the unique identifier of a tab group.
+//
+// All fields are required.
+message TabGroupId {
+  uint64 low = 1;
+  uint64 high = 2;
+}
+
 // Represents the information about a tab group stored in a WebStateList.
 //
 // The tab group information is stored inline.
@@ -38,4 +46,5 @@
   string title = 2;
   TabGroupColorId color = 3;
   bool collapsed = 4;
+  TabGroupId tab_group_id = 5;
 }
diff --git a/ios/chrome/browser/sessions/session_migration.mm b/ios/chrome/browser/sessions/session_migration.mm
index 02538c3..9e3df8b 100644
--- a/ios/chrome/browser/sessions/session_migration.mm
+++ b/ios/chrome/browser/sessions/session_migration.mm
@@ -22,6 +22,7 @@
 #import "ios/chrome/browser/sessions/session_ios.h"
 #import "ios/chrome/browser/sessions/session_tab_group.h"
 #import "ios/chrome/browser/sessions/session_window_ios.h"
+#import "ios/chrome/browser/sessions/tab_group_util.h"
 #import "ios/web/public/session/crw_session_storage.h"
 #import "ios/web/public/session/crw_session_user_data.h"
 #import "ios/web/public/session/proto/storage.pb.h"
@@ -228,7 +229,9 @@
                 rangeCount:group_storage.range().count()
                      title:base::SysUTF8ToNSString(group_storage.title())
                    colorId:static_cast<NSInteger>(group_storage.color())
-            collapsedState:group_storage.collapsed()];
+            collapsedState:group_storage.collapsed()
+                tabGroupId:tab_group_util::TabGroupIdFromStorage(
+                               group_storage.tab_group_id())];
     [groups addObject:session_tab_group];
   }
 
@@ -306,6 +309,8 @@
   group_storage.set_color(
       static_cast<ios::proto::TabGroupColorId>(legacy_tab_group.colorId));
   group_storage.set_collapsed(legacy_tab_group.collapsedState);
+  tab_group_util::TabGroupIdForStorage(legacy_tab_group.tabGroupId,
+                                       *group_storage.mutable_tab_group_id());
 }
 
 void OptimizedSession::AddItem(CRWSessionStorage* legacy_item) {
diff --git a/ios/chrome/browser/sessions/session_migration_unittest.mm b/ios/chrome/browser/sessions/session_migration_unittest.mm
index cb98dea..5a9b74f 100644
--- a/ios/chrome/browser/sessions/session_migration_unittest.mm
+++ b/ios/chrome/browser/sessions/session_migration_unittest.mm
@@ -11,6 +11,7 @@
 #import "base/strings/sys_string_conversions.h"
 #import "base/strings/utf_string_conversions.h"
 #import "base/time/time.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "ios/chrome/browser/sessions/fake_tab_restore_service.h"
 #import "ios/chrome/browser/sessions/proto/storage.pb.h"
 #import "ios/chrome/browser/sessions/session_constants.h"
@@ -32,6 +33,8 @@
 
 using SessionMigrationTest = PlatformTest;
 
+using tab_groups::TabGroupId;
+
 namespace {
 
 // Information about a single tab.
@@ -48,6 +51,7 @@
   const std::u16string title = u"";
   const tab_groups::TabGroupColorId color = tab_groups::TabGroupColorId::kGrey;
   const bool collapsed_state = false;
+  const TabGroupId tab_group_id = TabGroupId::GenerateNew();
 };
 
 // Information about a session.
@@ -94,7 +98,7 @@
     TabInfo{},
 };
 
-constexpr TabGroupInfo kTabGroups1[] = {
+const TabGroupInfo kTabGroups1[] = {
     TabGroupInfo{
         .range_start = 0,
         .range_count = 1,
@@ -227,7 +231,8 @@
                 rangeCount:group_info.range_count
                      title:base::SysUTF16ToNSString(group_info.title)
                    colorId:static_cast<NSInteger>(group_info.color)
-            collapsedState:group_info.collapsed_state];
+            collapsedState:group_info.collapsed_state
+                tabGroupId:group_info.tab_group_id];
     [groups addObject:session_tab_group];
   }
 
@@ -384,6 +389,8 @@
     group_storage.set_title(base::UTF16ToUTF8(group_info.title));
     group_storage.set_color(tab_group_util::ColorForStorage(group_info.color));
     group_storage.set_collapsed(group_info.collapsed_state);
+    tab_group_util::TabGroupIdForStorage(group_info.tab_group_id,
+                                         *group_storage.mutable_tab_group_id());
   }
 
   // Write the session metadata file.
@@ -529,6 +536,9 @@
     EXPECT_EQ(group_storage.color(),
               tab_group_util::ColorForStorage(group_info.color));
     EXPECT_EQ(group_storage.collapsed(), group_info.collapsed_state);
+    EXPECT_EQ(
+        tab_group_util::TabGroupIdFromStorage(group_storage.tab_group_id()),
+        group_info.tab_group_id);
   }
 }
 
@@ -605,6 +615,8 @@
     EXPECT_EQ(group_session.rangeCount, group_info.range_count);
     EXPECT_EQ(base::SysNSStringToUTF16(group_session.title), group_info.title);
     EXPECT_EQ(group_session.colorId, static_cast<int>(group_info.color));
+    EXPECT_EQ(group_session.collapsedState, group_info.collapsed_state);
+    EXPECT_EQ(group_session.tabGroupId, group_info.tab_group_id);
   }
 }
 
diff --git a/ios/chrome/browser/sessions/session_restoration_browser_agent_unittest.mm b/ios/chrome/browser/sessions/session_restoration_browser_agent_unittest.mm
index 5adb1669..a71e9ce 100644
--- a/ios/chrome/browser/sessions/session_restoration_browser_agent_unittest.mm
+++ b/ios/chrome/browser/sessions/session_restoration_browser_agent_unittest.mm
@@ -14,6 +14,7 @@
 #import "base/test/ios/wait_util.h"
 #import "base/test/metrics/histogram_tester.h"
 #import "components/sessions/core/session_id.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "ios/chrome/browser/main/model/browser_web_state_list_delegate.h"
 #import "ios/chrome/browser/ntp/model/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/ntp/model/new_tab_page_tab_helper_delegate.h"
@@ -47,6 +48,8 @@
 #import "third_party/ocmock/OCMock/OCMock.h"
 #import "third_party/ocmock/gtest_support.h"
 
+using tab_groups::TabGroupId;
+
 namespace {
 
 // Information about a single tab that needs to be restored.
@@ -634,28 +637,32 @@
                    title:@"group with duplicate at the end"
                  colorId:static_cast<NSInteger>(
                              tab_groups::TabGroupColorId::kGrey)
-          collapsedState:NO];
+          collapsedState:NO
+              tabGroupId:TabGroupId::GenerateNew()];
   SessionTabGroup* session_tab_group_2 = [[SessionTabGroup alloc]
       initWithRangeStart:4
               rangeCount:2
                    title:@"group with no duplicate"
                  colorId:static_cast<NSInteger>(
                              tab_groups::TabGroupColorId::kPink)
-          collapsedState:NO];
+          collapsedState:NO
+              tabGroupId:TabGroupId::GenerateNew()];
   SessionTabGroup* session_tab_group_3 = [[SessionTabGroup alloc]
       initWithRangeStart:7
               rangeCount:1
                    title:@"group with only duplicate"
                  colorId:static_cast<NSInteger>(
                              tab_groups::TabGroupColorId::kYellow)
-          collapsedState:NO];
+          collapsedState:NO
+              tabGroupId:TabGroupId::GenerateNew()];
   SessionTabGroup* session_tab_group_4 = [[SessionTabGroup alloc]
       initWithRangeStart:7
               rangeCount:2
                    title:@"group with duplicate at the beginning"
                  colorId:static_cast<NSInteger>(
                              tab_groups::TabGroupColorId::kOrange)
-          collapsedState:NO];
+          collapsedState:NO
+              tabGroupId:TabGroupId::GenerateNew()];
   SessionWindowIOS* window = CreateSessionWindow(
       SessionInfo<9>{
           .active_index = 0,
diff --git a/ios/chrome/browser/sessions/session_restoration_service_impl.mm b/ios/chrome/browser/sessions/session_restoration_service_impl.mm
index 8e44f27..0e104df2 100644
--- a/ios/chrome/browser/sessions/session_restoration_service_impl.mm
+++ b/ios/chrome/browser/sessions/session_restoration_service_impl.mm
@@ -601,10 +601,21 @@
     const std::set<std::string>& identifiers,
     base::OnceClosure closure) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(!HasIntersection(identifiers, identifiers_));
+  std::set<std::string> filtered_identifiers = identifiers;
+  if (@available(iOS 18, *)) {
+    // TODO(crbug.com/347443965): Something is broken here on iOS18.
+    for (const std::string& identifier : identifiers) {
+      if (identifiers_.contains(identifier)) {
+        filtered_identifiers.erase(identifier);
+      }
+    }
+  } else {
+    DCHECK(!HasIntersection(identifiers, identifiers_));
+  }
   task_runner_->PostTaskAndReply(
       FROM_HERE,
-      base::BindOnce(&DeleteDataForSessions, storage_path_, identifiers),
+      base::BindOnce(&DeleteDataForSessions, storage_path_,
+                     filtered_identifiers),
       std::move(closure));
 }
 
diff --git a/ios/chrome/browser/sessions/session_tab_group.h b/ios/chrome/browser/sessions/session_tab_group.h
index a3584a6..fd1aa94 100644
--- a/ios/chrome/browser/sessions/session_tab_group.h
+++ b/ios/chrome/browser/sessions/session_tab_group.h
@@ -7,6 +7,10 @@
 
 #import <Foundation/Foundation.h>
 
+namespace tab_groups {
+class TabGroupId;
+}  // namespace tab_groups
+
 // NSCoding-compliant class used to serialize tab groups.
 @interface SessionTabGroup : NSObject <NSCoding>
 
@@ -15,6 +19,7 @@
                              title:(NSString*)title
                            colorId:(NSInteger)colorId
                     collapsedState:(BOOL)collapsedState
+                        tabGroupId:(tab_groups::TabGroupId)tabGroupId
     NS_DESIGNATED_INITIALIZER;
 - (instancetype)init NS_UNAVAILABLE;
 
@@ -23,6 +28,7 @@
 @property(nonatomic, copy) NSString* title;
 @property(nonatomic, assign) NSInteger colorId;
 @property(nonatomic, assign) BOOL collapsedState;
+@property(nonatomic, readonly) tab_groups::TabGroupId tabGroupId;
 
 @end
 
diff --git a/ios/chrome/browser/sessions/session_tab_group.mm b/ios/chrome/browser/sessions/session_tab_group.mm
index 7ae846e..c2704c22 100644
--- a/ios/chrome/browser/sessions/session_tab_group.mm
+++ b/ios/chrome/browser/sessions/session_tab_group.mm
@@ -4,6 +4,11 @@
 
 #import "ios/chrome/browser/sessions/session_tab_group.h"
 
+#import "base/strings/sys_string_conversions.h"
+#import "components/tab_groups/tab_group_id.h"
+
+using tab_groups::TabGroupId;
+
 namespace {
 
 // Keys used to serialize properties.
@@ -12,16 +17,20 @@
 NSString* const kTitleKey = @"kTitleKey";
 NSString* const kColorIdKey = @"kColorIdKey";
 NSString* const kcollapsedStateKey = @"kcollapsedStateKey";
+NSString* const kTabGroupIdKey = @"kTabGroupIdKey";
 
 }  // namespace
 
-@implementation SessionTabGroup
+@implementation SessionTabGroup {
+  std::optional<TabGroupId> tabGroupId_;
+}
 
 - (instancetype)initWithRangeStart:(NSInteger)rangeStart
                         rangeCount:(NSInteger)rangeCount
                              title:(NSString*)title
                            colorId:(NSInteger)colorId
-                    collapsedState:(BOOL)collapsedState {
+                    collapsedState:(BOOL)collapsedState
+                        tabGroupId:(TabGroupId)tabGroupId {
   self = [super init];
   if (self) {
     _rangeStart = rangeStart;
@@ -29,10 +38,20 @@
     _title = title ?: @"";
     _colorId = colorId;
     _collapsedState = collapsedState;
+    tabGroupId_ = tabGroupId;
   }
   return self;
 }
 
+#pragma mark - Getters
+
+- (TabGroupId)tabGroupId {
+  if (!tabGroupId_.has_value()) {
+    tabGroupId_ = TabGroupId::CreateEmpty();
+  }
+  return tabGroupId_.value();
+}
+
 #pragma mark - NSCoding
 
 - (void)encodeWithCoder:(NSCoder*)coder {
@@ -41,6 +60,9 @@
   [coder encodeObject:_title forKey:kTitleKey];
   [coder encodeInt:_colorId forKey:kColorIdKey];
   [coder encodeBool:_collapsedState forKey:kcollapsedStateKey];
+  [coder
+      encodeObject:base::SysUTF8ToNSString(self.tabGroupId.token().ToString())
+            forKey:kTabGroupIdKey];
 }
 
 - (instancetype)initWithCoder:(NSCoder*)coder {
@@ -48,7 +70,22 @@
                        rangeCount:[coder decodeIntForKey:kRangeCountKey]
                             title:[coder decodeObjectForKey:kTitleKey]
                           colorId:[coder decodeIntForKey:kColorIdKey]
-                   collapsedState:[coder decodeBoolForKey:kcollapsedStateKey]];
+                   collapsedState:[coder decodeBoolForKey:kcollapsedStateKey]
+                       tabGroupId:[self decodeTabGroupId:coder]];
+}
+
+#pragma mark - Private
+
+// Decodes the tabGroupId object.
+- (TabGroupId)decodeTabGroupId:(NSCoder*)coder {
+  if (NSString* tabGroupIdString = [coder decodeObjectForKey:kTabGroupIdKey]) {
+    std::optional<base::Token> token =
+        base::Token::FromString(base::SysNSStringToUTF8(tabGroupIdString));
+    if (token.has_value()) {
+      return TabGroupId::FromRawToken(*token);
+    }
+  }
+  return TabGroupId::GenerateNew();
 }
 
 @end
diff --git a/ios/chrome/browser/sessions/tab_group_util.h b/ios/chrome/browser/sessions/tab_group_util.h
index 40a3c3d..39795d00 100644
--- a/ios/chrome/browser/sessions/tab_group_util.h
+++ b/ios/chrome/browser/sessions/tab_group_util.h
@@ -6,6 +6,7 @@
 #define IOS_CHROME_BROWSER_SESSIONS_TAB_GROUP_UTIL_H_
 
 #import "components/tab_groups/tab_group_color.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "components/tab_groups/tab_group_visual_data.h"
 #import "ios/chrome/browser/sessions/proto/tab_group.pb.h"
 
@@ -19,6 +20,7 @@
   int range_start = -1;
   int range_count = 0;
   tab_groups::TabGroupVisualData visual_data;
+  tab_groups::TabGroupId tab_group_id = tab_groups::TabGroupId::CreateEmpty();
 };
 
 // Returns the `DeserializedGroup` for the given serialized `group`.
@@ -29,10 +31,16 @@
 // Returns the corresponding serialized `color_id`.
 ios::proto::TabGroupColorId ColorForStorage(
     tab_groups::TabGroupColorId color_id);
+// Returns the corresponding serialized `tab_group_id`.
+void TabGroupIdForStorage(tab_groups::TabGroupId tab_group_id,
+                          ios::proto::TabGroupId& storage);
 
 // Returns the corresponding deserialized `color_id`.
 tab_groups::TabGroupColorId ColorFromStorage(
     ios::proto::TabGroupColorId color_id);
+// Returns the corresponding deserialized `tab_group_id`.
+tab_groups::TabGroupId TabGroupIdFromStorage(
+    ios::proto::TabGroupId tab_group_id);
 
 }  // namespace tab_group_util
 
diff --git a/ios/chrome/browser/sessions/tab_group_util.mm b/ios/chrome/browser/sessions/tab_group_util.mm
index 311a9a2..58bd3e52 100644
--- a/ios/chrome/browser/sessions/tab_group_util.mm
+++ b/ios/chrome/browser/sessions/tab_group_util.mm
@@ -7,8 +7,10 @@
 #import "base/notreached.h"
 #import "base/strings/sys_string_conversions.h"
 #import "base/strings/utf_string_conversions.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "ios/chrome/browser/sessions/session_tab_group.h"
 
+using tab_groups::TabGroupId;
 using tab_groups::TabGroupVisualData;
 
 namespace tab_group_util {
@@ -22,18 +24,18 @@
       .range_start = group.range().start(),
       .range_count = group.range().count(),
       .visual_data = visual_data,
-  };
+      .tab_group_id =
+          tab_group_util::TabGroupIdFromStorage(group.tab_group_id())};
 }
 
 DeserializedGroup FromSerializedValue(SessionTabGroup* group) {
   TabGroupVisualData visual_data =
       tab_groups::TabGroupVisualData(base::SysNSStringToUTF16(group.title),
                                      group.colorId, group.collapsedState);
-  return DeserializedGroup{
-      .range_start = static_cast<int>(group.rangeStart),
-      .range_count = static_cast<int>(group.rangeCount),
-      .visual_data = visual_data,
-  };
+  return DeserializedGroup{.range_start = static_cast<int>(group.rangeStart),
+                           .range_count = static_cast<int>(group.rangeCount),
+                           .visual_data = visual_data,
+                           .tab_group_id = group.tabGroupId};
 }
 
 ios::proto::TabGroupColorId ColorForStorage(
@@ -62,6 +64,14 @@
   }
 }
 
+void TabGroupIdForStorage(TabGroupId tab_group_id,
+                          ios::proto::TabGroupId& storage) {
+  const base::Token token = tab_group_id.token();
+  CHECK(!token.is_zero());
+  storage.set_high(token.high());
+  storage.set_low(token.low());
+}
+
 tab_groups::TabGroupColorId ColorFromStorage(
     ios::proto::TabGroupColorId color_id) {
   switch (color_id) {
@@ -88,4 +98,9 @@
   }
 }
 
+TabGroupId TabGroupIdFromStorage(ios::proto::TabGroupId tab_group_id) {
+  return TabGroupId::FromRawToken(
+      base::Token(tab_group_id.high(), tab_group_id.low()));
+}
+
 }  // namespace tab_group_util
diff --git a/ios/chrome/browser/sessions/tab_group_util_unittest.mm b/ios/chrome/browser/sessions/tab_group_util_unittest.mm
index c6c0a763..33371491 100644
--- a/ios/chrome/browser/sessions/tab_group_util_unittest.mm
+++ b/ios/chrome/browser/sessions/tab_group_util_unittest.mm
@@ -4,7 +4,9 @@
 
 #import "ios/chrome/browser/sessions/tab_group_util.h"
 
+#import "base/strings/sys_string_conversions.h"
 #import "components/tab_groups/tab_group_color.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "components/tab_groups/tab_group_visual_data.h"
 #import "ios/chrome/browser/sessions/proto/tab_group.pb.h"
 #import "ios/chrome/browser/sessions/session_tab_group.h"
@@ -17,10 +19,13 @@
 using tab_group_util::ColorForStorage;
 using tab_group_util::ColorFromStorage;
 using tab_group_util::DeserializedGroup;
+using tab_groups::TabGroupId;
 using tab_groups::TabGroupVisualData;
 
 // Tests the `FromSerializedValue:` method.
 TEST_F(TabSessionGroupUtil, FromSerializedValue) {
+  TabGroupId tab_group_id = TabGroupId::GenerateNew();
+
   ios::proto::TabGroupStorage group_storage;
   ios::proto::RangeIndex& range = *group_storage.mutable_range();
   range.set_start(2);
@@ -29,6 +34,8 @@
   group_storage.set_color(
       tab_group_util::ColorForStorage(tab_groups::TabGroupColorId::kGrey));
   group_storage.set_collapsed(true);
+  tab_group_util::TabGroupIdForStorage(tab_group_id,
+                                       *group_storage.mutable_tab_group_id());
 
   DeserializedGroup group_deserialized =
       tab_group_util::FromSerializedValue(group_storage);
@@ -38,17 +45,21 @@
   EXPECT_EQ(group_deserialized.visual_data.color(),
             tab_groups::TabGroupColorId::kGrey);
   EXPECT_TRUE(group_deserialized.visual_data.is_collapsed());
+  EXPECT_EQ(group_deserialized.tab_group_id, tab_group_id);
 }
 
 // Tests the legacy `FromSerializedValue:` method.
 TEST_F(TabSessionGroupUtil, FromSerializedValueLegacy) {
+  TabGroupId tab_group_id = TabGroupId::GenerateNew();
+
   SessionTabGroup* session_tab_group = [[SessionTabGroup alloc]
       initWithRangeStart:2
               rangeCount:3
                    title:@"title"
                  colorId:static_cast<NSInteger>(
                              tab_groups::TabGroupColorId::kGrey)
-          collapsedState:YES];
+          collapsedState:YES
+              tabGroupId:tab_group_id];
 
   SessionWindowIOS* session_window =
       [[SessionWindowIOS alloc] initWithSessions:@[]
@@ -63,6 +74,7 @@
   EXPECT_EQ(group_deserialized.visual_data.color(),
             tab_groups::TabGroupColorId::kGrey);
   EXPECT_TRUE(group_deserialized.visual_data.is_collapsed());
+  EXPECT_EQ(group_deserialized.tab_group_id, tab_group_id);
 }
 
 // Tests the `ColorForStorage:` method.
diff --git a/ios/chrome/browser/sessions/web_state_list_serialization.mm b/ios/chrome/browser/sessions/web_state_list_serialization.mm
index 1f89e22..71bd9a6 100644
--- a/ios/chrome/browser/sessions/web_state_list_serialization.mm
+++ b/ios/chrome/browser/sessions/web_state_list_serialization.mm
@@ -18,6 +18,7 @@
 #import "base/strings/utf_string_conversions.h"
 #import "components/sessions/core/session_id.h"
 #import "components/sessions/core/session_id_generator.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "ios/chrome/browser/sessions/features.h"
 #import "ios/chrome/browser/sessions/proto/storage.pb.h"
 #import "ios/chrome/browser/sessions/proto/tab_group.pb.h"
@@ -402,6 +403,7 @@
   // Deserialize and create tab groups.
   if (enable_tab_groups) {
     const int tab_group_count = deserializer.GetTabGroupsCount();
+    std::set<tab_groups::TabGroupId> tab_group_ids;
     for (int i = 0; i < tab_group_count; ++i) {
       DeserializedGroup group = deserializer.GetDeserializedGroupAt(i);
       if (group.range_start < restored_pinned_tabs_count ||
@@ -412,9 +414,23 @@
           group.range_start + group.range_count > restored_tabs_count) {
         continue;
       }
+
+      tab_groups::TabGroupId tab_group_id = group.tab_group_id;
+      if (!tab_group_id.is_empty()) {
+        // Check that there is no duplicate  of `tab_group_id`.
+        // It is improbable, but not impossible, for this to occur.
+        if (tab_group_ids.contains(tab_group_id)) {
+          base::debug::DumpWithoutCrashing();
+          continue;
+        }
+        tab_group_ids.insert(tab_group_id);
+      } else {
+        tab_group_id = tab_groups::TabGroupId::GenerateNew();
+      }
+
       web_state_list->CreateGroup(
           TabGroupRange(group.range_start, group.range_count).AsSet(),
-          group.visual_data);
+          group.visual_data, tab_group_id);
     }
   }
 
@@ -498,7 +514,8 @@
                                  group->visual_data().title())
                      colorId:static_cast<NSInteger>(
                                  group->visual_data().color())
-              collapsedState:group->visual_data().is_collapsed()];
+              collapsedState:group->visual_data().is_collapsed()
+                  tabGroupId:group->tab_group_id()];
       [serialized_groups addObject:serialized_group];
     }
   }
@@ -572,6 +589,8 @@
       group_storage.set_color(
           tab_group_util::ColorForStorage(group->visual_data().color()));
       group_storage.set_collapsed(group->visual_data().is_collapsed());
+      tab_group_util::TabGroupIdForStorage(
+          group->tab_group_id(), *group_storage.mutable_tab_group_id());
     }
   }
 
diff --git a/ios/chrome/browser/sessions/web_state_list_serialization_unittest.mm b/ios/chrome/browser/sessions/web_state_list_serialization_unittest.mm
index 6f5d510..5399bd4 100644
--- a/ios/chrome/browser/sessions/web_state_list_serialization_unittest.mm
+++ b/ios/chrome/browser/sessions/web_state_list_serialization_unittest.mm
@@ -12,12 +12,14 @@
 #import "base/test/metrics/histogram_tester.h"
 #import "base/test/scoped_feature_list.h"
 #import "components/tab_groups/tab_group_color.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "components/tab_groups/tab_group_visual_data.h"
 #import "ios/chrome/browser/sessions/features.h"
 #import "ios/chrome/browser/sessions/proto/storage.pb.h"
 #import "ios/chrome/browser/sessions/session_constants.h"
 #import "ios/chrome/browser/sessions/session_tab_group.h"
 #import "ios/chrome/browser/sessions/session_window_ios.h"
+#import "ios/chrome/browser/sessions/tab_group_util.h"
 #import "ios/chrome/browser/shared/model/url/chrome_url_constants.h"
 #import "ios/chrome/browser/shared/model/web_state_list/tab_group.h"
 #import "ios/chrome/browser/shared/model/web_state_list/tab_group_range.h"
@@ -36,6 +38,8 @@
 #import "testing/gtest_mac.h"
 #import "testing/platform_test.h"
 
+using tab_groups::TabGroupId;
+
 namespace {
 
 // Creates a fake WebState with `navigation_count` navigation items (all
@@ -381,10 +385,10 @@
   web_state_list.InsertWebState(
       CreateWebStateWithWebStateID(web::WebStateID::FromSerializedValue(1113)),
       WebStateList::InsertionParams::AtIndex(10));
-  web_state_list.CreateGroup({2, 3}, {});
-  web_state_list.CreateGroup({6, 7}, {});
-  web_state_list.CreateGroup({8}, {});
-  web_state_list.CreateGroup({9, 10}, {});
+  web_state_list.CreateGroup({2, 3}, {}, TabGroupId::GenerateNew());
+  web_state_list.CreateGroup({6, 7}, {}, TabGroupId::GenerateNew());
+  web_state_list.CreateGroup({8}, {}, TabGroupId::GenerateNew());
+  web_state_list.CreateGroup({9, 10}, {}, TabGroupId::GenerateNew());
   builder.GenerateIdentifiersForWebStateList();
   EXPECT_EQ("a b | [ 0 c d* ] e f [ 1 g h ] [ 2 i ] [ 3 j k ]",
             builder.GetWebStateListDescription());
@@ -653,10 +657,10 @@
   web_state_list.InsertWebState(
       CreateWebStateWithWebStateID(web::WebStateID::FromSerializedValue(1113)),
       WebStateList::InsertionParams::AtIndex(10));
-  web_state_list.CreateGroup({2, 3}, {});
-  web_state_list.CreateGroup({6, 7}, {});
-  web_state_list.CreateGroup({8}, {});
-  web_state_list.CreateGroup({9, 10}, {});
+  web_state_list.CreateGroup({2, 3}, {}, TabGroupId::GenerateNew());
+  web_state_list.CreateGroup({6, 7}, {}, TabGroupId::GenerateNew());
+  web_state_list.CreateGroup({8}, {}, TabGroupId::GenerateNew());
+  web_state_list.CreateGroup({9, 10}, {}, TabGroupId::GenerateNew());
   builder.GenerateIdentifiersForWebStateList();
   EXPECT_EQ("a b | [ 0 c d* ] e f [ 1 g h ] [ 2 i ] [ 3 j k ]",
             builder.GetWebStateListDescription());
@@ -1287,6 +1291,8 @@
   group_storage.set_title("Invalid");
   group_storage.set_color(ios::proto::TabGroupColorId::GREY);
   group_storage.set_collapsed(false);
+  tab_group_util::TabGroupIdForStorage(TabGroupId::GenerateNew(),
+                                       *group_storage.mutable_tab_group_id());
 
   EXPECT_EQ(storage.items_size(), 4);
   EXPECT_EQ(storage.active_index(), 1);
@@ -1334,7 +1340,8 @@
                                        rangeCount:4
                                             title:@"Invalid"
                                           colorId:0
-                                   collapsedState:NO];
+                                   collapsedState:NO
+                                       tabGroupId:TabGroupId::GenerateNew()];
   NSArray<SessionTabGroup*>* session_groups = [session_window.tabGroups
       arrayByAddingObjectsFromArray:@[ invalid_tab_group ]];
   session_window =
diff --git a/ios/chrome/browser/shared/coordinator/default_browser_promo/BUILD.gn b/ios/chrome/browser/shared/coordinator/default_browser_promo/BUILD.gn
index 0dc894f..c37d343 100644
--- a/ios/chrome/browser/shared/coordinator/default_browser_promo/BUILD.gn
+++ b/ios/chrome/browser/shared/coordinator/default_browser_promo/BUILD.gn
@@ -10,6 +10,7 @@
   deps = [
     "//base",
     "//ios/chrome/browser/default_browser/model:utils",
+    "//ios/chrome/browser/default_promo/ui_bundled:coordinator",
     "//ios/chrome/browser/overlays/model",
     "//ios/chrome/browser/shared/coordinator/scene:observing_scene_agent",
     "//ios/chrome/browser/shared/coordinator/scene:scene_state_header",
@@ -18,7 +19,6 @@
     "//ios/chrome/browser/shared/model/web_state_list",
     "//ios/chrome/browser/shared/public/commands",
     "//ios/chrome/browser/shared/public/features",
-    "//ios/chrome/browser/ui/default_promo",
     "//ios/web/public",
   ]
 }
@@ -37,6 +37,7 @@
     "//ios/chrome/app/application_delegate:test_support",
     "//ios/chrome/browser/default_browser/model:test_support",
     "//ios/chrome/browser/default_browser/model:utils",
+    "//ios/chrome/browser/default_promo/ui_bundled:coordinator",
     "//ios/chrome/browser/infobars/model",
     "//ios/chrome/browser/infobars/model/test",
     "//ios/chrome/browser/overlays/model",
@@ -48,7 +49,6 @@
     "//ios/chrome/browser/shared/model/browser_state:test_support",
     "//ios/chrome/browser/shared/model/web_state_list",
     "//ios/chrome/browser/shared/public/commands",
-    "//ios/chrome/browser/ui/default_promo",
     "//ios/chrome/test:test_support",
     "//ios/web/public/test/fakes",
     "//testing/gtest",
diff --git a/ios/chrome/browser/shared/coordinator/default_browser_promo/DEPS b/ios/chrome/browser/shared/coordinator/default_browser_promo/DEPS
index 9a07c16..2e1c09b 100644
--- a/ios/chrome/browser/shared/coordinator/default_browser_promo/DEPS
+++ b/ios/chrome/browser/shared/coordinator/default_browser_promo/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
   "+ios/chrome/browser/default_browser/model",
+  "+ios/chrome/browser/default_promo/ui_bundled",
   "+ios/chrome/browser/overlays/model/public",
 ]
diff --git a/ios/chrome/browser/shared/coordinator/default_browser_promo/non_modal_default_browser_promo_scheduler_scene_agent.mm b/ios/chrome/browser/shared/coordinator/default_browser_promo/non_modal_default_browser_promo_scheduler_scene_agent.mm
index 9f6eeb46..3f30274b 100644
--- a/ios/chrome/browser/shared/coordinator/default_browser_promo/non_modal_default_browser_promo_scheduler_scene_agent.mm
+++ b/ios/chrome/browser/shared/coordinator/default_browser_promo/non_modal_default_browser_promo_scheduler_scene_agent.mm
@@ -7,6 +7,8 @@
 #import "base/notreached.h"
 #import "base/timer/timer.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_commands.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_metrics_util.h"
 #import "ios/chrome/browser/overlays/model/public/overlay_presenter.h"
 #import "ios/chrome/browser/overlays/model/public/overlay_presenter_observer_bridge.h"
 #import "ios/chrome/browser/shared/coordinator/scene/scene_state.h"
@@ -19,8 +21,6 @@
 #import "ios/chrome/browser/shared/public/commands/application_commands.h"
 #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
-#import "ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_commands.h"
-#import "ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_metrics_util.h"
 #import "ios/web/public/web_state.h"
 #import "ios/web/public/web_state_observer_bridge.h"
 
diff --git a/ios/chrome/browser/shared/coordinator/default_browser_promo/non_modal_default_browser_promo_scheduler_scene_agent_unittest.mm b/ios/chrome/browser/shared/coordinator/default_browser_promo/non_modal_default_browser_promo_scheduler_scene_agent_unittest.mm
index 3d62f4bd..34188420 100644
--- a/ios/chrome/browser/shared/coordinator/default_browser_promo/non_modal_default_browser_promo_scheduler_scene_agent_unittest.mm
+++ b/ios/chrome/browser/shared/coordinator/default_browser_promo/non_modal_default_browser_promo_scheduler_scene_agent_unittest.mm
@@ -14,6 +14,8 @@
 #import "ios/chrome/app/application_delegate/fake_startup_information.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
 #import "ios/chrome/browser/default_browser/model/utils_test_support.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_commands.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_metrics_util.h"
 #import "ios/chrome/browser/infobars/model/infobar_ios.h"
 #import "ios/chrome/browser/infobars/model/infobar_manager_impl.h"
 #import "ios/chrome/browser/infobars/model/test/fake_infobar_ios.h"
@@ -32,8 +34,6 @@
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_opener.h"
 #import "ios/chrome/browser/shared/public/commands/application_commands.h"
 #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
-#import "ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_commands.h"
-#import "ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_metrics_util.h"
 #import "ios/chrome/test/ios_chrome_scoped_testing_local_state.h"
 #import "ios/web/public/test/fakes/fake_navigation_manager.h"
 #import "ios/web/public/test/fakes/fake_web_state.h"
diff --git a/ios/chrome/browser/shared/coordinator/scene/BUILD.gn b/ios/chrome/browser/shared/coordinator/scene/BUILD.gn
index 43f91f7c..84f2421 100644
--- a/ios/chrome/browser/shared/coordinator/scene/BUILD.gn
+++ b/ios/chrome/browser/shared/coordinator/scene/BUILD.gn
@@ -87,6 +87,7 @@
     "//ios/chrome/browser/app_store_rating/ui_bundled:features",
     "//ios/chrome/browser/appearance/ui_bundled",
     "//ios/chrome/browser/blocking_overlay/ui_bundled",
+    "//ios/chrome/browser/browser_view/ui_bundled",
     "//ios/chrome/browser/browsing_data/model",
     "//ios/chrome/browser/crash_report/model",
     "//ios/chrome/browser/crash_report/model:model_internal",
@@ -95,6 +96,7 @@
     "//ios/chrome/browser/default_browser/model",
     "//ios/chrome/browser/default_browser/model:default_browser_interest_signals",
     "//ios/chrome/browser/default_browser/model:utils",
+    "//ios/chrome/browser/default_promo/ui_bundled:coordinator",
     "//ios/chrome/browser/enterprise/model/idle",
     "//ios/chrome/browser/feature_engagement/model",
     "//ios/chrome/browser/first_run/model",
@@ -138,8 +140,6 @@
     "//ios/chrome/browser/ui/authentication",
     "//ios/chrome/browser/ui/authentication/enterprise:enterprise_utils",
     "//ios/chrome/browser/ui/authentication/signin",
-    "//ios/chrome/browser/ui/browser_view",
-    "//ios/chrome/browser/ui/default_promo",
     "//ios/chrome/browser/ui/first_run",
     "//ios/chrome/browser/ui/first_run/omnibox_position/promo",
     "//ios/chrome/browser/ui/history",
diff --git a/ios/chrome/browser/shared/coordinator/scene/DEPS b/ios/chrome/browser/shared/coordinator/scene/DEPS
index cf98c3d8..547b69bf 100644
--- a/ios/chrome/browser/shared/coordinator/scene/DEPS
+++ b/ios/chrome/browser/shared/coordinator/scene/DEPS
@@ -1,6 +1,7 @@
 include_rules = [
   "+ios/chrome/browser/app_store_rating/ui_bundled",
   "+ios/chrome/browser/appearance/ui_bundled/appearance_customization.h",
+  "+ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.h",
   "+ios/chrome/browser/browsing_data/model",
   "+ios/chrome/browser/crash_report/model",
   "+ios/chrome/browser/credential_provider_promo/ui_bundled/credential_provider_promo_scene_agent.h",
diff --git a/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm b/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm
index af71aa1..e78460d5 100644
--- a/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm
+++ b/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm
@@ -47,6 +47,7 @@
 #import "ios/chrome/browser/app_store_rating/ui_bundled/app_store_rating_scene_agent.h"
 #import "ios/chrome/browser/app_store_rating/ui_bundled/features.h"
 #import "ios/chrome/browser/appearance/ui_bundled/appearance_customization.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.h"
 #import "ios/chrome/browser/browsing_data/model/browsing_data_remove_mask.h"
 #import "ios/chrome/browser/browsing_data/model/browsing_data_remover.h"
 #import "ios/chrome/browser/browsing_data/model/browsing_data_remover_factory.h"
@@ -130,7 +131,6 @@
 #import "ios/chrome/browser/ui/authentication/signin/signin_coordinator.h"
 #import "ios/chrome/browser/ui/authentication/signin/signin_utils.h"
 #import "ios/chrome/browser/ui/authentication/signin_notification_infobar_delegate.h"
-#import "ios/chrome/browser/ui/browser_view/browser_view_controller.h"
 #import "ios/chrome/browser/ui/first_run/omnibox_position/promo/omnibox_position_choice_scene_agent.h"
 #import "ios/chrome/browser/ui/first_run/orientation_limiting_navigation_controller.h"
 #import "ios/chrome/browser/ui/history/history_coordinator.h"
diff --git a/ios/chrome/browser/shared/model/url/url_util.h b/ios/chrome/browser/shared/model/url/url_util.h
index d69a06b0..c5d7946 100644
--- a/ios/chrome/browser/shared/model/url/url_util.h
+++ b/ios/chrome/browser/shared/model/url/url_util.h
@@ -15,6 +15,9 @@
 // Returns whether `url` is an external file reference.
 bool UrlIsExternalFileReference(const GURL& url);
 
+// Returns YES if `url` matches the format `chrome://downloads/fileName`
+bool UrlIsDownloadedFile(const GURL& url);
+
 // Returns true if the scheme has a chrome scheme.
 bool UrlHasChromeScheme(const GURL& url);
 bool UrlHasChromeScheme(NSURL* url);
diff --git a/ios/chrome/browser/shared/model/url/url_util.mm b/ios/chrome/browser/shared/model/url/url_util.mm
index 0137e3fc..229a77a3 100644
--- a/ios/chrome/browser/shared/model/url/url_util.mm
+++ b/ios/chrome/browser/shared/model/url/url_util.mm
@@ -25,6 +25,11 @@
                                           kChromeUIExternalFileHost);
 }
 
+bool UrlIsDownloadedFile(const GURL& url) {
+  return url.SchemeIs(kChromeUIScheme) &&
+         base::EqualsCaseInsensitiveASCII(url.host(), kChromeUIDownloadsHost);
+}
+
 bool UrlHasChromeScheme(const GURL& url) {
   return url.SchemeIs(kChromeUIScheme);
 }
diff --git a/ios/chrome/browser/shared/model/web_state_list/browser_util.mm b/ios/chrome/browser/shared/model/web_state_list/browser_util.mm
index a57d5b8..66eb4a6f 100644
--- a/ios/chrome/browser/shared/model/web_state_list/browser_util.mm
+++ b/ios/chrome/browser/shared/model/web_state_list/browser_util.mm
@@ -171,6 +171,10 @@
   const tab_groups::TabGroupVisualData destination_visual_data(
       source_tab_group->visual_data());
 
+  // Duplicate the `TabGroupId` for the new group.
+  const tab_groups::TabGroupId destination_local_id =
+      source_tab_group->tab_group_id();
+
   // Move tabs to the new browser.
   int moved_tab_count = 0;
   size_t source_group_count =
@@ -199,7 +203,7 @@
   const TabGroup* destination_tab_group =
       destination_browser->GetWebStateList()->CreateGroup(
           TabGroupRange(destination_tab_group_index, moved_tab_count).AsSet(),
-          destination_visual_data);
+          destination_visual_data, destination_local_id);
   CHECK(destination_browser->GetWebStateList()->ContainsGroup(
       destination_tab_group));
   // Check that the source browser has one less group.
diff --git a/ios/chrome/browser/shared/model/web_state_list/browser_util_unittest.mm b/ios/chrome/browser/shared/model/web_state_list/browser_util_unittest.mm
index ddae709..f1da6fed 100644
--- a/ios/chrome/browser/shared/model/web_state_list/browser_util_unittest.mm
+++ b/ios/chrome/browser/shared/model/web_state_list/browser_util_unittest.mm
@@ -7,6 +7,7 @@
 #import <memory>
 
 #import "base/memory/raw_ptr.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "ios/chrome/browser/sessions/fake_tab_restore_service.h"
 #import "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h"
 #import "ios/chrome/browser/shared/model/browser/browser_list.h"
@@ -26,6 +27,7 @@
 #import "testing/platform_test.h"
 #import "ui/base/test/ios/ui_image_test_utils.h"
 
+using tab_groups::TabGroupId;
 using tab_groups::TabGroupVisualData;
 using ui::test::uiimage_utils::UIImagesAreEqual;
 using ui::test::uiimage_utils::UIImageWithSizeAndSolidColor;
@@ -239,10 +241,11 @@
   WebStateList* other_web_state_list = other_browser_->GetWebStateList();
 
   // Create a group of two tabs.
+  TabGroupId tab_group_id = TabGroupId::GenerateNew();
   TabGroupVisualData visual_data =
       TabGroupVisualData(u"Group", tab_groups::TabGroupColorId::kGrey);
-  const TabGroup* tab_group =
-      web_state_list->CreateGroup({2}, TabGroupVisualData(visual_data));
+  const TabGroup* tab_group = web_state_list->CreateGroup(
+      {2}, TabGroupVisualData(visual_data), tab_group_id);
 
   web::WebStateID tab_id = GetTabIDForWebStateAt(2, browser_.get());
   ASSERT_EQ(3, web_state_list->count());
@@ -254,6 +257,7 @@
   const TabGroup* other_group = other_web_state_list->GetGroupOfWebStateAt(0);
   ASSERT_TRUE(other_group);
   EXPECT_EQ(1, other_group->range().count());
+  EXPECT_EQ(tab_group_id, other_group->tab_group_id());
   EXPECT_EQ(visual_data, other_group->visual_data());
   EXPECT_EQ(2, web_state_list->count());
   EXPECT_EQ(1, other_web_state_list->count());
@@ -268,10 +272,11 @@
   WebStateList* other_web_state_list = other_browser_->GetWebStateList();
 
   // Create a group of two tabs.
+  TabGroupId tab_group_id = TabGroupId::GenerateNew();
   TabGroupVisualData visual_data =
       TabGroupVisualData(u"Group", tab_groups::TabGroupColorId::kGrey);
-  const TabGroup* tab_group =
-      web_state_list->CreateGroup({0, 1}, TabGroupVisualData(visual_data));
+  const TabGroup* tab_group = web_state_list->CreateGroup(
+      {0, 1}, TabGroupVisualData(visual_data), tab_group_id);
   web::WebStateID tab_id_0 = GetTabIDForWebStateAt(0, browser_.get());
   web::WebStateID tab_id_1 = GetTabIDForWebStateAt(1, browser_.get());
   ASSERT_EQ(3, web_state_list->count());
@@ -283,6 +288,7 @@
   const TabGroup* other_group = other_web_state_list->GetGroupOfWebStateAt(0);
   ASSERT_TRUE(other_group);
   EXPECT_EQ(2, other_group->range().count());
+  EXPECT_EQ(tab_group_id, other_group->tab_group_id());
   EXPECT_EQ(visual_data, other_group->visual_data());
   EXPECT_EQ(1, web_state_list->count());
   EXPECT_EQ(2, other_web_state_list->count());
@@ -297,12 +303,14 @@
   WebStateList* other_web_state_list = other_browser_->GetWebStateList();
 
   // Create 2 groups.
+  TabGroupId tab_group_id_0 = TabGroupId::GenerateNew();
+  TabGroupId tab_group_id_1 = TabGroupId::GenerateNew();
   TabGroupVisualData visual_data =
       TabGroupVisualData(u"Group", tab_groups::TabGroupColorId::kGrey);
-  const TabGroup* tab_group_0 =
-      web_state_list->CreateGroup({0}, TabGroupVisualData(visual_data));
-  const TabGroup* tab_group_1 =
-      web_state_list->CreateGroup({1}, TabGroupVisualData(visual_data));
+  const TabGroup* tab_group_0 = web_state_list->CreateGroup(
+      {0}, TabGroupVisualData(visual_data), tab_group_id_0);
+  const TabGroup* tab_group_1 = web_state_list->CreateGroup(
+      {1}, TabGroupVisualData(visual_data), tab_group_id_1);
   web::WebStateID tab_id_0 = GetTabIDForWebStateAt(0, browser_.get());
   web::WebStateID tab_id_1 = GetTabIDForWebStateAt(1, browser_.get());
   ASSERT_EQ(3, web_state_list->count());
@@ -319,6 +327,8 @@
   ASSERT_TRUE(other_group_1);
   EXPECT_EQ(1, other_group_0->range().count());
   EXPECT_EQ(1, other_group_1->range().count());
+  EXPECT_EQ(tab_group_id_0, other_group_0->tab_group_id());
+  EXPECT_EQ(tab_group_id_1, other_group_1->tab_group_id());
   EXPECT_EQ(visual_data, other_group_0->visual_data());
   EXPECT_EQ(visual_data, other_group_1->visual_data());
   EXPECT_EQ(1, web_state_list->count());
@@ -333,10 +343,11 @@
   WebStateList* web_state_list = browser_->GetWebStateList();
 
   // Create a group of two tabs.
+  TabGroupId tab_group_id = TabGroupId::GenerateNew();
   TabGroupVisualData visual_data =
       TabGroupVisualData(u"Group", tab_groups::TabGroupColorId::kGrey);
-  const TabGroup* tab_group =
-      web_state_list->CreateGroup({0, 1}, TabGroupVisualData(visual_data));
+  const TabGroup* tab_group = web_state_list->CreateGroup(
+      {0, 1}, TabGroupVisualData(visual_data), tab_group_id);
   web::WebStateID tab_id_0 = GetTabIDForWebStateAt(0, browser_.get());
   web::WebStateID tab_id_1 = GetTabIDForWebStateAt(1, browser_.get());
   ASSERT_EQ(3, web_state_list->count());
@@ -349,6 +360,7 @@
   EXPECT_EQ(tab_group, web_state_list->GetGroupOfWebStateAt(1));
   EXPECT_EQ(nullptr, web_state_list->GetGroupOfWebStateAt(2));
   EXPECT_EQ(2, tab_group->range().count());
+  EXPECT_EQ(tab_group_id, tab_group->tab_group_id());
   EXPECT_EQ(visual_data, tab_group->visual_data());
   EXPECT_EQ(3, web_state_list->count());
   EXPECT_EQ(tab_id_0, GetTabIDForWebStateAt(0, browser_.get()));
@@ -361,10 +373,11 @@
   WebStateList* web_state_list = browser_->GetWebStateList();
 
   // Create a group of two tabs.
+  TabGroupId tab_group_id = TabGroupId::GenerateNew();
   TabGroupVisualData visual_data =
       TabGroupVisualData(u"Group", tab_groups::TabGroupColorId::kGrey);
-  const TabGroup* tab_group =
-      web_state_list->CreateGroup({0, 1}, TabGroupVisualData(visual_data));
+  const TabGroup* tab_group = web_state_list->CreateGroup(
+      {0, 1}, TabGroupVisualData(visual_data), tab_group_id);
   web::WebStateID tab_id_0 = GetTabIDForWebStateAt(0, browser_.get());
   web::WebStateID tab_id_1 = GetTabIDForWebStateAt(1, browser_.get());
   ASSERT_EQ(3, web_state_list->count());
@@ -377,6 +390,7 @@
   EXPECT_EQ(tab_group, web_state_list->GetGroupOfWebStateAt(1));
   EXPECT_EQ(tab_group, web_state_list->GetGroupOfWebStateAt(2));
   EXPECT_EQ(2, tab_group->range().count());
+  EXPECT_EQ(tab_group_id, tab_group->tab_group_id());
   EXPECT_EQ(visual_data, tab_group->visual_data());
   EXPECT_EQ(3, web_state_list->count());
   EXPECT_EQ(tab_id_0, GetTabIDForWebStateAt(1, browser_.get()));
@@ -389,10 +403,11 @@
   WebStateList* web_state_list = browser_->GetWebStateList();
 
   // Create a group of two tabs.
+  TabGroupId tab_group_id = TabGroupId::GenerateNew();
   TabGroupVisualData visual_data =
       TabGroupVisualData(u"Group", tab_groups::TabGroupColorId::kGrey);
-  const TabGroup* tab_group =
-      web_state_list->CreateGroup({1, 2}, TabGroupVisualData(visual_data));
+  const TabGroup* tab_group = web_state_list->CreateGroup(
+      {1, 2}, TabGroupVisualData(visual_data), tab_group_id);
   web::WebStateID tab_id_1 = GetTabIDForWebStateAt(1, browser_.get());
   web::WebStateID tab_id_2 = GetTabIDForWebStateAt(2, browser_.get());
   ASSERT_EQ(3, web_state_list->count());
@@ -406,6 +421,7 @@
   EXPECT_EQ(tab_group, web_state_list->GetGroupOfWebStateAt(0));
   EXPECT_EQ(tab_group, web_state_list->GetGroupOfWebStateAt(1));
   EXPECT_EQ(2, tab_group->range().count());
+  EXPECT_EQ(tab_group_id, tab_group->tab_group_id());
   EXPECT_EQ(visual_data, tab_group->visual_data());
   EXPECT_EQ(3, web_state_list->count());
   EXPECT_EQ(tab_id_1, GetTabIDForWebStateAt(0, browser_.get()));
diff --git a/ios/chrome/browser/shared/model/web_state_list/tab_group.h b/ios/chrome/browser/shared/model/web_state_list/tab_group.h
index 9975865..7d1624b 100644
--- a/ios/chrome/browser/shared/model/web_state_list/tab_group.h
+++ b/ios/chrome/browser/shared/model/web_state_list/tab_group.h
@@ -11,6 +11,7 @@
 
 #import "base/memory/weak_ptr.h"
 #import "base/sequence_checker.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "components/tab_groups/tab_group_visual_data.h"
 #import "ios/chrome/browser/shared/model/web_state_list/tab_group_range.h"
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
@@ -24,7 +25,21 @@
 // state change, as well as any group state change.
 class TabGroup {
  public:
-  TabGroup(const tab_groups::TabGroupVisualData& visual_data,
+  // Parameters:
+  //   - tab_group_id: A unique identifier used by TabGroupSync for
+  //   synchronization purposes.
+  //   - visual_data: Encapsulates visual information for displaying the tab
+  //   group (name, color, etc.).
+  //   - range: The range of indices defining the position of this group within
+  //   the WebStateList (default is invalid, indicating the range hasn't been
+  //   set yet).
+  //
+  // Ownership:
+  //   - This object is created and owned by WebStateList. WebStateList manages
+  //   the association of tabs to groups, and it notifies observers of any
+  //   changes in group state.
+  TabGroup(tab_groups::TabGroupId tab_group_id,
+           const tab_groups::TabGroupVisualData& visual_data,
            TabGroupRange range = TabGroupRange::InvalidRange());
 
   TabGroup(const TabGroup&) = delete;
@@ -62,6 +77,12 @@
     return range_;
   }
 
+  // The local tab group identifier.
+  tab_groups::TabGroupId tab_group_id() const {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    return tab_group_id_;
+  }
+
   // Returns all the colors a TabGroup can have.
   static std::vector<tab_groups::TabGroupColorId> AllPossibleTabGroupColors();
 
@@ -80,6 +101,7 @@
 
  private:
   SEQUENCE_CHECKER(sequence_checker_);
+  tab_groups::TabGroupId tab_group_id_;
   tab_groups::TabGroupVisualData visual_data_;
   TabGroupRange range_;
 
diff --git a/ios/chrome/browser/shared/model/web_state_list/tab_group.mm b/ios/chrome/browser/shared/model/web_state_list/tab_group.mm
index bb3a826..cfa8c54 100644
--- a/ios/chrome/browser/shared/model/web_state_list/tab_group.mm
+++ b/ios/chrome/browser/shared/model/web_state_list/tab_group.mm
@@ -10,9 +10,10 @@
 #import "ios/chrome/grit/ios_strings.h"
 #import "ui/base/l10n/l10n_util_mac.h"
 
-TabGroup::TabGroup(const tab_groups::TabGroupVisualData& visual_data,
+TabGroup::TabGroup(tab_groups::TabGroupId tab_group_id,
+                   const tab_groups::TabGroupVisualData& visual_data,
                    TabGroupRange range)
-    : visual_data_(visual_data), range_(range) {}
+    : tab_group_id_(tab_group_id), visual_data_(visual_data), range_(range) {}
 
 TabGroup::~TabGroup() = default;
 
diff --git a/ios/chrome/browser/shared/model/web_state_list/tab_group_unittest.mm b/ios/chrome/browser/shared/model/web_state_list/tab_group_unittest.mm
index e94424e6..54fa800 100644
--- a/ios/chrome/browser/shared/model/web_state_list/tab_group_unittest.mm
+++ b/ios/chrome/browser/shared/model/web_state_list/tab_group_unittest.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/shared/model/web_state_list/tab_group.h"
 
+#import "components/tab_groups/tab_group_id.h"
 #import "ios/chrome/grit/ios_strings.h"
 #import "testing/gtest_mac.h"
 #import "testing/platform_test.h"
@@ -11,11 +12,13 @@
 
 using TabGroupTest = PlatformTest;
 
+using tab_groups::TabGroupId;
+
 // Checks that visual data are correctly set up.
 TEST_F(TabGroupTest, VisualData) {
   auto visual_data = tab_groups::TabGroupVisualData(
       u"Group", tab_groups::TabGroupColorId::kGrey);
-  TabGroup group(visual_data);
+  TabGroup group(TabGroupId::GenerateNew(), visual_data);
 
   EXPECT_EQ(visual_data, group.visual_data());
 }
@@ -24,7 +27,7 @@
 TEST_F(TabGroupTest, VisualDataUpdate) {
   auto visual_data = tab_groups::TabGroupVisualData(
       u"Group", tab_groups::TabGroupColorId::kGrey);
-  TabGroup group(visual_data);
+  TabGroup group(TabGroupId::GenerateNew(), visual_data);
 
   visual_data.SetTitle(u"Other title");
   EXPECT_NE(visual_data, group.visual_data());
@@ -35,15 +38,17 @@
 
 // Checks that the default range is the InvalidRange.
 TEST_F(TabGroupTest, DefaultsToInvalidRange) {
-  TabGroup group(tab_groups::TabGroupVisualData(
-      u"Group", tab_groups::TabGroupColorId::kGrey));
+  TabGroup group(TabGroupId::GenerateNew(),
+                 tab_groups::TabGroupVisualData(
+                     u"Group", tab_groups::TabGroupColorId::kGrey));
 
   EXPECT_EQ(TabGroupRange::InvalidRange(), group.range());
 }
 
 // Checks that the range at construction is correctly set up.
 TEST_F(TabGroupTest, RangeAtConstruction) {
-  TabGroup group(tab_groups::TabGroupVisualData(
+  TabGroup group(TabGroupId::GenerateNew(),
+                 tab_groups::TabGroupVisualData(
                      u"Group", tab_groups::TabGroupColorId::kGrey),
                  TabGroupRange(2, 3));
 
@@ -53,7 +58,8 @@
 // Checks that the range is correctly update via the setter on TabGroup.
 TEST_F(TabGroupTest, RangeUpdate) {
   auto range = TabGroupRange(2, 3);
-  TabGroup group(tab_groups::TabGroupVisualData(
+  TabGroup group(TabGroupId::GenerateNew(),
+                 tab_groups::TabGroupVisualData(
                      u"Group", tab_groups::TabGroupColorId::kGrey),
                  range);
 
@@ -66,11 +72,12 @@
   EXPECT_EQ(range, group.range());
 }
 
+// Checks that the title is correctly set up.
 TEST_F(TabGroupTest, GetTitle) {
   auto range = TabGroupRange(2, 3);
   tab_groups::TabGroupVisualData visual_data = tab_groups::TabGroupVisualData(
       u"A Group", tab_groups::TabGroupColorId::kGrey);
-  TabGroup group(visual_data, range);
+  TabGroup group(TabGroupId::GenerateNew(), visual_data, range);
   EXPECT_NSEQ(group.GetTitle(), @"A Group");
 
   visual_data.SetTitle(u"A New Name");
@@ -84,3 +91,14 @@
   EXPECT_NSEQ(group.GetTitle(),
               l10n_util::GetPluralNSStringF(IDS_IOS_TAB_GROUP_TABS_NUMBER, 3));
 }
+
+// Checks that the tab group id is correctly set up.
+TEST_F(TabGroupTest, GetTabGroupId) {
+  TabGroupId tab_group_id = TabGroupId::GenerateNew();
+  TabGroup group(tab_group_id,
+                 tab_groups::TabGroupVisualData(
+                     u"Group", tab_groups::TabGroupColorId::kGrey),
+                 TabGroupRange(2, 3));
+
+  EXPECT_EQ(tab_group_id, group.tab_group_id());
+}
diff --git a/ios/chrome/browser/shared/model/web_state_list/tab_group_utils_unittest.mm b/ios/chrome/browser/shared/model/web_state_list/tab_group_utils_unittest.mm
index 8d179c4..9268706 100644
--- a/ios/chrome/browser/shared/model/web_state_list/tab_group_utils_unittest.mm
+++ b/ios/chrome/browser/shared/model/web_state_list/tab_group_utils_unittest.mm
@@ -8,6 +8,7 @@
 #import "components/favicon/core/favicon_url.h"
 #import "components/favicon/ios/web_favicon_driver.h"
 #import "components/keyed_service/core/service_access_type.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "components/tab_groups/tab_group_visual_data.h"
 #import "ios/chrome/browser/favicon/model/favicon_service_factory.h"
 #import "ios/chrome/browser/history/model/history_service_factory.h"
@@ -27,6 +28,8 @@
 #import "testing/gtest/include/gtest/gtest.h"
 #import "testing/platform_test.h"
 
+using tab_groups::TabGroupId;
+
 class GroupUtilsTest : public PlatformTest {
  public:
   GroupUtilsTest() {
@@ -105,7 +108,8 @@
   // web state at `web_state_index` with a default title and a `color`.
   void CreateGroup(int web_state_index, tab_groups::TabGroupColorId color) {
     tab_groups::TabGroupVisualData visual_data(u"Test title", color);
-    web_state_list_->CreateGroup({web_state_index}, visual_data);
+    web_state_list_->CreateGroup({web_state_index}, visual_data,
+                                 TabGroupId::GenerateNew());
   }
 
   // Returns the default color for the regular web state list.
@@ -170,17 +174,20 @@
 TEST_F(GroupUtilsTest, AllGroupsSingleWindow) {
   AddDefaultWebStates();
 
+  TabGroupId tab_group_id_1 = TabGroupId::GenerateNew();
   tab_groups::TabGroupVisualData visual_data1(
       u"First title", tab_groups::TabGroupColorId::kGreen);
-  web_state_list_->CreateGroup({0}, visual_data1);
+  web_state_list_->CreateGroup({0}, visual_data1, tab_group_id_1);
 
+  TabGroupId tab_group_id_2 = TabGroupId::GenerateNew();
   tab_groups::TabGroupVisualData visual_data2(
       u"Second title", tab_groups::TabGroupColorId::kPink);
-  web_state_list_->CreateGroup({1}, visual_data2);
+  web_state_list_->CreateGroup({1}, visual_data2, tab_group_id_2);
 
+  TabGroupId tab_group_id_3 = TabGroupId::GenerateNew();
   tab_groups::TabGroupVisualData visual_data3(
       u"Third title", tab_groups::TabGroupColorId::kCyan);
-  incognito_web_state_list_->CreateGroup({3}, visual_data3);
+  incognito_web_state_list_->CreateGroup({3}, visual_data3, tab_group_id_3);
 
   BrowserList* browser_list =
       BrowserListFactory::GetForBrowserState(browser_state_.get());
@@ -189,8 +196,10 @@
       GetAllGroupsForBrowserList(browser_list, incognito);
   EXPECT_EQ(groups, GetAllGroupsForBrowserState(browser_state_.get()));
 
+  std::vector<TabGroupId> tab_group_ids;
   std::vector<tab_groups::TabGroupVisualData> visual_data;
   for (const TabGroup* group : groups) {
+    tab_group_ids.push_back(group->tab_group_id());
     visual_data.push_back(group->visual_data());
   }
 
@@ -199,6 +208,10 @@
               visual_data.end());
   EXPECT_TRUE(std::find(visual_data.begin(), visual_data.end(), visual_data2) !=
               visual_data.end());
+  EXPECT_TRUE(std::find(tab_group_ids.begin(), tab_group_ids.end(),
+                        tab_group_id_1) != tab_group_ids.end());
+  EXPECT_TRUE(std::find(tab_group_ids.begin(), tab_group_ids.end(),
+                        tab_group_id_2) != tab_group_ids.end());
 
   ChromeBrowserState* otr_browser_state =
       browser_state_->GetOffTheRecordChromeBrowserState();
@@ -210,6 +223,7 @@
 
   EXPECT_EQ(1u, incognito_groups.size());
   for (const TabGroup* group : incognito_groups) {
+    EXPECT_EQ(tab_group_id_3, group->tab_group_id());
     EXPECT_EQ(visual_data3, group->visual_data());
   }
 }
@@ -219,25 +233,30 @@
   AddOtherBrowsers();
   AddDefaultWebStates();
 
+  TabGroupId tab_group_id_1 = TabGroupId::GenerateNew();
   tab_groups::TabGroupVisualData visual_data1(
       u"First title", tab_groups::TabGroupColorId::kGreen);
-  web_state_list_->CreateGroup({0}, visual_data1);
+  web_state_list_->CreateGroup({0}, visual_data1, tab_group_id_1);
 
+  TabGroupId tab_group_id_2 = TabGroupId::GenerateNew();
   tab_groups::TabGroupVisualData visual_data2(
       u"Second title", tab_groups::TabGroupColorId::kPink);
-  web_state_list_->CreateGroup({1}, visual_data2);
+  web_state_list_->CreateGroup({1}, visual_data2, tab_group_id_2);
 
+  TabGroupId tab_group_id_3 = TabGroupId::GenerateNew();
   tab_groups::TabGroupVisualData visual_data3(
       u"Third title", tab_groups::TabGroupColorId::kCyan);
-  incognito_web_state_list_->CreateGroup({3}, visual_data3);
+  incognito_web_state_list_->CreateGroup({3}, visual_data3, tab_group_id_3);
 
+  TabGroupId tab_group_id_4 = TabGroupId::GenerateNew();
   tab_groups::TabGroupVisualData visual_data4(
       u"Fourth title", tab_groups::TabGroupColorId::kPurple);
-  other_web_state_list_->CreateGroup({1}, visual_data4);
+  other_web_state_list_->CreateGroup({1}, visual_data4, tab_group_id_4);
 
+  TabGroupId tab_group_id_5 = TabGroupId::GenerateNew();
   tab_groups::TabGroupVisualData visual_data5(
       u"Fifth title", tab_groups::TabGroupColorId::kYellow);
-  other_web_state_list_->CreateGroup({0}, visual_data5);
+  other_web_state_list_->CreateGroup({0}, visual_data5, tab_group_id_5);
 
   BrowserList* browser_list =
       BrowserListFactory::GetForBrowserState(browser_state_.get());
@@ -245,8 +264,11 @@
   std::set<const TabGroup*> groups =
       GetAllGroupsForBrowserList(browser_list, incognito);
   EXPECT_EQ(groups, GetAllGroupsForBrowserState(browser_state_.get()));
+
+  std::vector<TabGroupId> tab_group_ids;
   std::vector<tab_groups::TabGroupVisualData> visual_data;
   for (const TabGroup* group : groups) {
+    tab_group_ids.push_back(group->tab_group_id());
     visual_data.push_back(group->visual_data());
   }
 
@@ -259,6 +281,14 @@
               visual_data.end());
   EXPECT_TRUE(std::find(visual_data.begin(), visual_data.end(), visual_data5) !=
               visual_data.end());
+  EXPECT_TRUE(std::find(tab_group_ids.begin(), tab_group_ids.end(),
+                        tab_group_id_1) != tab_group_ids.end());
+  EXPECT_TRUE(std::find(tab_group_ids.begin(), tab_group_ids.end(),
+                        tab_group_id_2) != tab_group_ids.end());
+  EXPECT_TRUE(std::find(tab_group_ids.begin(), tab_group_ids.end(),
+                        tab_group_id_4) != tab_group_ids.end());
+  EXPECT_TRUE(std::find(tab_group_ids.begin(), tab_group_ids.end(),
+                        tab_group_id_5) != tab_group_ids.end());
 
   ChromeBrowserState* otr_browser_state =
       browser_state_->GetOffTheRecordChromeBrowserState();
@@ -270,6 +300,7 @@
 
   EXPECT_EQ(1u, incognito_groups.size());
   for (const TabGroup* group : incognito_groups) {
+    EXPECT_EQ(tab_group_id_3, group->tab_group_id());
     EXPECT_EQ(visual_data3, group->visual_data());
   }
 }
@@ -280,7 +311,7 @@
 
   tab_groups::TabGroupVisualData visual_data(
       u"First title", tab_groups::TabGroupColorId::kGreen);
-  web_state_list_->CreateGroup({1}, visual_data);
+  web_state_list_->CreateGroup({1}, visual_data, TabGroupId::GenerateNew());
 
   web::WebStateID web_state_id =
       web_state_list_->GetWebStateAt(0)->GetUniqueIdentifier();
@@ -318,7 +349,8 @@
 
   tab_groups::TabGroupVisualData visual_data(
       u"First title", tab_groups::TabGroupColorId::kGreen);
-  other_web_state_list_->CreateGroup({0}, visual_data);
+  other_web_state_list_->CreateGroup({0}, visual_data,
+                                     TabGroupId::GenerateNew());
 
   web::WebStateID web_state_id =
       web_state_list_->GetWebStateAt(1)->GetUniqueIdentifier();
@@ -354,16 +386,18 @@
 
   tab_groups::TabGroupVisualData visual_data1(
       u"First title", tab_groups::TabGroupColorId::kGreen);
-  const TabGroup* group1 = web_state_list_->CreateGroup({0}, visual_data1);
+  const TabGroup* group1 = web_state_list_->CreateGroup(
+      {0}, visual_data1, TabGroupId::GenerateNew());
 
   tab_groups::TabGroupVisualData visual_data2(
       u"Second title", tab_groups::TabGroupColorId::kPink);
-  const TabGroup* group2 = web_state_list_->CreateGroup({1}, visual_data2);
+  const TabGroup* group2 = web_state_list_->CreateGroup(
+      {1}, visual_data2, TabGroupId::GenerateNew());
 
   tab_groups::TabGroupVisualData visual_data3(
       u"Third title", tab_groups::TabGroupColorId::kCyan);
-  const TabGroup* incognito_group3 =
-      incognito_web_state_list_->CreateGroup({3}, visual_data3);
+  const TabGroup* incognito_group3 = incognito_web_state_list_->CreateGroup(
+      {3}, visual_data3, TabGroupId::GenerateNew());
 
   BrowserList* browser_list =
       BrowserListFactory::GetForBrowserState(browser_state_.get());
@@ -389,26 +423,28 @@
 
   tab_groups::TabGroupVisualData visual_data1(
       u"First title", tab_groups::TabGroupColorId::kGreen);
-  const TabGroup* group1 = web_state_list_->CreateGroup({0}, visual_data1);
+  const TabGroup* group1 = web_state_list_->CreateGroup(
+      {0}, visual_data1, TabGroupId::GenerateNew());
 
   tab_groups::TabGroupVisualData visual_data2(
       u"Second title", tab_groups::TabGroupColorId::kPink);
-  const TabGroup* group2 = web_state_list_->CreateGroup({1}, visual_data2);
+  const TabGroup* group2 = web_state_list_->CreateGroup(
+      {1}, visual_data2, TabGroupId::GenerateNew());
 
   tab_groups::TabGroupVisualData visual_data3(
       u"Third title", tab_groups::TabGroupColorId::kCyan);
-  const TabGroup* incognito_group3 =
-      incognito_web_state_list_->CreateGroup({3}, visual_data3);
+  const TabGroup* incognito_group3 = incognito_web_state_list_->CreateGroup(
+      {3}, visual_data3, TabGroupId::GenerateNew());
 
   tab_groups::TabGroupVisualData visual_data4(
       u"Fourth title", tab_groups::TabGroupColorId::kPurple);
-  const TabGroup* other_group4 =
-      other_web_state_list_->CreateGroup({1}, visual_data4);
+  const TabGroup* other_group4 = other_web_state_list_->CreateGroup(
+      {1}, visual_data4, TabGroupId::GenerateNew());
 
   tab_groups::TabGroupVisualData visual_data5(
       u"Fifth title", tab_groups::TabGroupColorId::kYellow);
-  const TabGroup* other_group5 =
-      other_web_state_list_->CreateGroup({0}, visual_data5);
+  const TabGroup* other_group5 = other_web_state_list_->CreateGroup(
+      {0}, visual_data5, TabGroupId::GenerateNew());
 
   BrowserList* browser_list =
       BrowserListFactory::GetForBrowserState(browser_state_.get());
diff --git a/ios/chrome/browser/shared/model/web_state_list/test/web_state_list_builder_from_description.mm b/ios/chrome/browser/shared/model/web_state_list/test/web_state_list_builder_from_description.mm
index c08c8316..8de180c1 100644
--- a/ios/chrome/browser/shared/model/web_state_list/test/web_state_list_builder_from_description.mm
+++ b/ios/chrome/browser/shared/model/web_state_list/test/web_state_list_builder_from_description.mm
@@ -10,6 +10,7 @@
 
 #import "base/strings/string_split.h"
 #import "base/strings/string_util.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "components/tab_groups/tab_group_visual_data.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/shared/model/url/chrome_url_constants.h"
@@ -203,7 +204,8 @@
         }
         const TabGroup* created_group = web_state_list_->CreateGroup(
             std::move(indices_for_current_tab_group),
-            tab_groups::TabGroupVisualData());
+            tab_groups::TabGroupVisualData(),
+            tab_groups::TabGroupId::GenerateNew());
         SetTabGroupIdentifier(created_group, identifier_for_current_tab_group);
         identifier_for_current_tab_group = 0;
         break;
diff --git a/ios/chrome/browser/shared/model/web_state_list/test/web_state_list_builder_from_description_unittest.mm b/ios/chrome/browser/shared/model/web_state_list/test/web_state_list_builder_from_description_unittest.mm
index 89b43af..0a6022c 100644
--- a/ios/chrome/browser/shared/model/web_state_list/test/web_state_list_builder_from_description_unittest.mm
+++ b/ios/chrome/browser/shared/model/web_state_list/test/web_state_list_builder_from_description_unittest.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/shared/model/web_state_list/test/web_state_list_builder_from_description.h"
 
+#import "components/tab_groups/tab_group_id.h"
 #import "components/tab_groups/tab_group_visual_data.h"
 #import "ios/chrome/browser/shared/model/web_state_list/removing_indexes.h"
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
@@ -11,6 +12,8 @@
 #import "ios/web/public/test/fakes/fake_web_state.h"
 #import "testing/platform_test.h"
 
+using tab_groups::TabGroupId;
+
 // Tests for `WebStateListBuilderFromDescription`.
 class WebStateListBuilderFromDescriptionTest : public PlatformTest,
                                                public WebStateListDelegate {
@@ -101,8 +104,8 @@
   InsertWebState(InsertionParams::AtIndex(5));
   InsertWebState(InsertionParams::AtIndex(6));
   InsertWebState(InsertionParams::AtIndex(7));
-  web_state_list_.CreateGroup({2, 3}, {});
-  web_state_list_.CreateGroup({6, 7}, {});
+  web_state_list_.CreateGroup({2, 3}, {}, TabGroupId::GenerateNew());
+  web_state_list_.CreateGroup({6, 7}, {}, TabGroupId::GenerateNew());
   EXPECT_EQ("_ _ | [ _ _ _* ] _ _ [ _ _ _ ]", GetDescription());
   builder_.GenerateIdentifiersForWebStateList();
   EXPECT_EQ("a b | [ 0 c d* ] e f [ 1 g h ]", GetDescription());
@@ -192,7 +195,8 @@
   builder_.SetWebStateIdentifier(web_state_2_ptr, 'c');
   EXPECT_EQ("| b c", GetDescription());
 
-  const TabGroup* tab_group = web_state_list_.CreateGroup({0, 1}, {});
+  const TabGroup* tab_group =
+      web_state_list_.CreateGroup({0, 1}, {}, TabGroupId::GenerateNew());
   EXPECT_EQ("| [ _ b c ]", GetDescription());
   builder_.SetTabGroupIdentifier(tab_group, '0');
   EXPECT_EQ("| [ 0 b c ]", GetDescription());
@@ -292,11 +296,11 @@
   web_state_list_.ActivateWebStateAt(4);
   EXPECT_EQ("a b | c d e*", GetDescription());
 
-  web_state_list_.CreateGroup({2}, {});
+  web_state_list_.CreateGroup({2}, {}, TabGroupId::GenerateNew());
   EXPECT_EQ("a b | [ _ c ] d e*", GetDescription());
-  web_state_list_.CreateGroup({3}, {});
+  web_state_list_.CreateGroup({3}, {}, TabGroupId::GenerateNew());
   EXPECT_EQ("a b | [ _ c ] [ _ d ] e*", GetDescription());
-  web_state_list_.CreateGroup({4}, {});
+  web_state_list_.CreateGroup({4}, {}, TabGroupId::GenerateNew());
   EXPECT_EQ("a b | [ _ c ] [ _ d ] [ _ e* ]", GetDescription());
   builder_.GenerateIdentifiersForWebStateList();
   EXPECT_EQ("a b | [ 0 c ] [ 1 d ] [ 2 e* ]", GetDescription());
@@ -333,7 +337,7 @@
 
   const auto visual_data = tab_groups::TabGroupVisualData(
       u"New Group", tab_groups::TabGroupColorId::kGrey);
-  web_state_list_.CreateGroup({0}, visual_data);
+  web_state_list_.CreateGroup({0}, visual_data, TabGroupId::GenerateNew());
 
   EXPECT_EQ("| [ _ a ]", GetDescription());
 }
diff --git a/ios/chrome/browser/shared/model/web_state_list/web_state_list.h b/ios/chrome/browser/shared/model/web_state_list/web_state_list.h
index 708a603..9a66386 100644
--- a/ios/chrome/browser/shared/model/web_state_list/web_state_list.h
+++ b/ios/chrome/browser/shared/model/web_state_list/web_state_list.h
@@ -32,6 +32,7 @@
 class WebStateListTest;
 
 namespace tab_groups {
+class TabGroupId;
 class TabGroupVisualData;
 }  // namespace tab_groups
 
@@ -309,9 +310,9 @@
   // The returned TabGroup is valid as long as the WebStateList is not mutated.
   // To get its exact lifecycle, Listen to the group deletion notification,
   // after-which the pointer should not be used.
-  const TabGroup* CreateGroup(
-      const std::set<int>& indices,
-      const tab_groups::TabGroupVisualData& visual_data);
+  const TabGroup* CreateGroup(const std::set<int>& indices,
+                              const tab_groups::TabGroupVisualData& visual_data,
+                              tab_groups::TabGroupId tab_group_id);
 
   // Returns true if the specified group is contained by the model.
   bool ContainsGroup(const TabGroup* group) const;
@@ -425,7 +426,8 @@
   // Assumes that the WebStateList is locked.
   const TabGroup* CreateGroupImpl(
       const std::set<int>& indices,
-      const tab_groups::TabGroupVisualData& visual_data);
+      const tab_groups::TabGroupVisualData& visual_data,
+      tab_groups::TabGroupId tab_group_id);
 
   // Moves the set of WebStates at `indices` at the end of the given tab group.
   //
diff --git a/ios/chrome/browser/shared/model/web_state_list/web_state_list.mm b/ios/chrome/browser/shared/model/web_state_list/web_state_list.mm
index cf5718f6..bd1577d 100644
--- a/ios/chrome/browser/shared/model/web_state_list/web_state_list.mm
+++ b/ios/chrome/browser/shared/model/web_state_list/web_state_list.mm
@@ -13,6 +13,7 @@
 #import "base/containers/contains.h"
 #import "base/debug/alias.h"
 #import "base/memory/raw_ptr.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "ios/chrome/browser/shared/model/web_state_list/order_controller.h"
 #import "ios/chrome/browser/shared/model/web_state_list/order_controller_source_from_web_state_list.h"
 #import "ios/chrome/browser/shared/model/web_state_list/removing_indexes.h"
@@ -385,10 +386,11 @@
 
 const TabGroup* WebStateList::CreateGroup(
     const std::set<int>& indices,
-    const tab_groups::TabGroupVisualData& visual_data) {
+    const tab_groups::TabGroupVisualData& visual_data,
+    tab_groups::TabGroupId tab_group_id) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   auto lock = LockForMutation();
-  return CreateGroupImpl(indices, visual_data);
+  return CreateGroupImpl(indices, visual_data, tab_group_id);
 }
 
 bool WebStateList::ContainsGroup(const TabGroup* group) const {
@@ -802,7 +804,8 @@
 
 const TabGroup* WebStateList::CreateGroupImpl(
     const std::set<int>& indices,
-    const tab_groups::TabGroupVisualData& visual_data) {
+    const tab_groups::TabGroupVisualData& visual_data,
+    tab_groups::TabGroupId tab_group_id) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(locked_);
   DCHECK(!indices.empty());
@@ -828,8 +831,8 @@
   DCHECK_NE(pivot_index, kInvalidIndex);
 
   // Create the group.
-  auto group =
-      std::make_unique<TabGroup>(visual_data, TabGroupRange(pivot_index, 0));
+  auto group = std::make_unique<TabGroup>(tab_group_id, visual_data,
+                                          TabGroupRange(pivot_index, 0));
   const TabGroup* new_group = group.get();
   groups_.insert(std::move(group));
 
diff --git a/ios/chrome/browser/shared/model/web_state_list/web_state_list_unittest.mm b/ios/chrome/browser/shared/model/web_state_list/web_state_list_unittest.mm
index 0dd92248..537070613 100644
--- a/ios/chrome/browser/shared/model/web_state_list/web_state_list_unittest.mm
+++ b/ios/chrome/browser/shared/model/web_state_list/web_state_list_unittest.mm
@@ -9,6 +9,7 @@
 #import "base/scoped_observation.h"
 #import "base/supports_user_data.h"
 #import "components/tab_groups/tab_group_color.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "ios/chrome/browser/shared/model/web_state_list/removing_indexes.h"
 #import "ios/chrome/browser/shared/model/web_state_list/tab_group.h"
 #import "ios/chrome/browser/shared/model/web_state_list/test/fake_web_state_list_delegate.h"
@@ -22,6 +23,7 @@
 #import "testing/platform_test.h"
 #import "url/gurl.h"
 
+using tab_groups::TabGroupId;
 using tab_groups::TabGroupVisualData;
 
 namespace {
@@ -2599,7 +2601,8 @@
 
   TabGroupVisualData visual_data =
       TabGroupVisualData(u"Group", tab_groups::TabGroupColorId::kPink);
-  const TabGroup* group_1 = web_state_list_.CreateGroup({2}, visual_data);
+  const TabGroup* group_1 =
+      web_state_list_.CreateGroup({2}, visual_data, TabGroupId::GenerateNew());
   builder.SetTabGroupIdentifier(group_1, '1');
 
   EXPECT_EQ("| [ 0 a b ] [ 1 c ] d* e", builder.GetWebStateListDescription());
@@ -2618,15 +2621,18 @@
 TEST_F(WebStateListTest, CreateGroup_OneTab_NotMoving) {
   WebStateListBuilderFromDescription builder(&web_state_list_);
   ASSERT_TRUE(builder.BuildWebStateListFromDescription("| a*"));
+  TabGroupId tab_group_id = TabGroupId::GenerateNew();
   TabGroupVisualData visual_data =
       TabGroupVisualData(u"Group", tab_groups::TabGroupColorId::kGrey);
 
   observer_.ResetStatistics();
-  const TabGroup* group = web_state_list_.CreateGroup({0}, visual_data);
+  const TabGroup* group =
+      web_state_list_.CreateGroup({0}, visual_data, tab_group_id);
 
   builder.SetTabGroupIdentifier(group, '0');
   EXPECT_EQ("| [ 0 a* ]", builder.GetWebStateListDescription());
   EXPECT_EQ(TabGroupRange(0, 1), group->range());
+  EXPECT_EQ(tab_group_id, group->tab_group_id());
   EXPECT_EQ(visual_data, group->visual_data());
   EXPECT_EQ(0, observer_.web_state_activated_count());
   EXPECT_EQ(0, observer_.web_state_moved_count());
@@ -2640,15 +2646,18 @@
 TEST_F(WebStateListTest, CreateGroup_OneTab_Moving) {
   WebStateListBuilderFromDescription builder(&web_state_list_);
   ASSERT_TRUE(builder.BuildWebStateListFromDescription("a* b |"));
+  TabGroupId tab_group_id = TabGroupId::GenerateNew();
   TabGroupVisualData visual_data =
       TabGroupVisualData(u"Group", tab_groups::TabGroupColorId::kGrey);
 
   observer_.ResetStatistics();
-  const TabGroup* group = web_state_list_.CreateGroup({0}, visual_data);
+  const TabGroup* group =
+      web_state_list_.CreateGroup({0}, visual_data, tab_group_id);
 
   builder.SetTabGroupIdentifier(group, '0');
   EXPECT_EQ("b | [ 0 a* ]", builder.GetWebStateListDescription());
   EXPECT_EQ(TabGroupRange(1, 1), group->range());
+  EXPECT_EQ(tab_group_id, group->tab_group_id());
   EXPECT_EQ(visual_data, group->visual_data());
   EXPECT_EQ(0, observer_.web_state_activated_count());
   EXPECT_EQ(1, observer_.web_state_moved_count());
@@ -2662,15 +2671,18 @@
 TEST_F(WebStateListTest, CreateGroup_SeveralTabs) {
   WebStateListBuilderFromDescription builder(&web_state_list_);
   ASSERT_TRUE(builder.BuildWebStateListFromDescription("| a b* c d e"));
+  TabGroupId tab_group_id = TabGroupId::GenerateNew();
   TabGroupVisualData visual_data =
       TabGroupVisualData(u"Group", tab_groups::TabGroupColorId::kGrey);
 
   observer_.ResetStatistics();
-  const TabGroup* group = web_state_list_.CreateGroup({0, 2, 4}, visual_data);
+  const TabGroup* group =
+      web_state_list_.CreateGroup({0, 2, 4}, visual_data, tab_group_id);
 
   builder.SetTabGroupIdentifier(group, '0');
   EXPECT_EQ("| [ 0 a c e ] b* d", builder.GetWebStateListDescription());
   EXPECT_EQ(TabGroupRange(0, 3), group->range());
+  EXPECT_EQ(tab_group_id, group->tab_group_id());
   EXPECT_EQ(visual_data, group->visual_data());
   EXPECT_EQ(0, observer_.web_state_activated_count());
   EXPECT_EQ(2, observer_.web_state_moved_count());
@@ -2684,15 +2696,18 @@
 TEST_F(WebStateListTest, CreateGroup_SeveralTabs_SomePinned) {
   WebStateListBuilderFromDescription builder(&web_state_list_);
   ASSERT_TRUE(builder.BuildWebStateListFromDescription("a b* c | d e"));
+  TabGroupId tab_group_id = TabGroupId::GenerateNew();
   TabGroupVisualData visual_data =
       TabGroupVisualData(u"Group", tab_groups::TabGroupColorId::kGrey);
 
   observer_.ResetStatistics();
-  const TabGroup* group = web_state_list_.CreateGroup({1, 3}, visual_data);
+  const TabGroup* group =
+      web_state_list_.CreateGroup({1, 3}, visual_data, tab_group_id);
 
   builder.SetTabGroupIdentifier(group, '0');
   EXPECT_EQ("a c | [ 0 b* d ] e", builder.GetWebStateListDescription());
   EXPECT_EQ(TabGroupRange(2, 2), group->range());
+  EXPECT_EQ(tab_group_id, group->tab_group_id());
   EXPECT_EQ(visual_data, group->visual_data());
   EXPECT_EQ(0, observer_.web_state_activated_count());
   EXPECT_EQ(1, observer_.web_state_moved_count());
@@ -2711,7 +2726,8 @@
       TabGroupVisualData(u"Group", tab_groups::TabGroupColorId::kBlue);
 
   observer_.ResetStatistics();
-  const TabGroup* group_1 = web_state_list_.CreateGroup({1, 3}, visual_data_1);
+  const TabGroup* group_1 = web_state_list_.CreateGroup(
+      {1, 3}, visual_data_1, TabGroupId::GenerateNew());
 
   builder.SetTabGroupIdentifier(group_1, '1');
   EXPECT_EQ("| [ 0 a c ] [ 1 b d* ] e", builder.GetWebStateListDescription());
@@ -2736,8 +2752,8 @@
       TabGroupVisualData(u"Group", tab_groups::TabGroupColorId::kBlue);
 
   observer_.ResetStatistics();
-  const TabGroup* group_1 =
-      web_state_list_.CreateGroup({0, 1, 2, 3, 7, 8, 9}, visual_data_1);
+  const TabGroup* group_1 = web_state_list_.CreateGroup(
+      {0, 1, 2, 3, 7, 8, 9}, visual_data_1, TabGroupId::GenerateNew());
 
   builder.SetTabGroupIdentifier(group_1, '1');
   EXPECT_EQ("e f | [ 1 a b c d h i j ] g [ 0 k ] l",
@@ -2759,8 +2775,8 @@
       TabGroupVisualData(u"Group", tab_groups::TabGroupColorId::kOrange);
 
   observer_.ResetStatistics();
-  const TabGroup* group_2 =
-      web_state_list_.CreateGroup({1, 4, 7, 8}, visual_data_2);
+  const TabGroup* group_2 = web_state_list_.CreateGroup(
+      {1, 4, 7, 8}, visual_data_2, TabGroupId::GenerateNew());
 
   builder.SetTabGroupIdentifier(group_2, '2');
   EXPECT_EQ("| [ 0 a c ] [ 2 b e h i ] d f [ 1 g j ] k l",
@@ -3399,7 +3415,8 @@
   ASSERT_TRUE(builder.BuildWebStateListFromDescription("| [0 a* b] [ 1 c ] d"));
   const TabGroup* group_0 = builder.GetTabGroupForIdentifier('0');
   const TabGroup* group_1 = builder.GetTabGroupForIdentifier('1');
-  TabGroup outside_group{tab_groups::TabGroupVisualData()};
+  TabGroup outside_group{TabGroupId::GenerateNew(),
+                         tab_groups::TabGroupVisualData()};
 
   EXPECT_TRUE(web_state_list_.ContainsGroup(group_0));
   EXPECT_TRUE(web_state_list_.ContainsGroup(group_1));
diff --git a/ios/chrome/browser/shared/public/commands/BUILD.gn b/ios/chrome/browser/shared/public/commands/BUILD.gn
index 7c3f3e5..90d7178 100644
--- a/ios/chrome/browser/shared/public/commands/BUILD.gn
+++ b/ios/chrome/browser/shared/public/commands/BUILD.gn
@@ -27,6 +27,7 @@
     "generate_qr_code_command.mm",
     "help_commands.h",
     "lens_commands.h",
+    "lens_overlay_commands.h",
     "load_query_commands.h",
     "manage_storage_alert_commands.h",
     "mini_map_commands.h",
diff --git a/ios/chrome/browser/shared/public/commands/lens_overlay_commands.h b/ios/chrome/browser/shared/public/commands/lens_overlay_commands.h
new file mode 100644
index 0000000..3ec3a70
--- /dev/null
+++ b/ios/chrome/browser/shared/public/commands/lens_overlay_commands.h
@@ -0,0 +1,26 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_LENS_OVERLAY_COMMANDS_H_
+#define IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_LENS_OVERLAY_COMMANDS_H_
+
+/// Commands related to Lens Overlay.
+@protocol LensOverlayCommands
+
+/// Creates a new Lens UI. Automatically destroys any existing Lens UI as only
+/// one instance of it per BVC is supported.
+- (void)createAndShowLensUI:(BOOL)animated;
+
+/// Display the lens overlay, if it exists.
+- (void)showLensUI:(BOOL)animated;
+
+/// Hide lens overlay if it exists.
+- (void)hideLensUI:(BOOL)animated;
+
+/// Destroy lens overlay (called e.g. in response to memory pressure).
+- (void)destroyLensUI:(BOOL)animated;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_LENS_OVERLAY_COMMANDS_H_
diff --git a/ios/chrome/browser/shared/public/features/features.h b/ios/chrome/browser/shared/public/features/features.h
index 0a96ee0e..89a8311a 100644
--- a/ios/chrome/browser/shared/public/features/features.h
+++ b/ios/chrome/browser/shared/public/features/features.h
@@ -657,4 +657,7 @@
 // Feature flag for default browser promo experimental string for iPad.
 BASE_DECLARE_FEATURE(kDefaultBrowserPromoIPadExperimentalString);
 
+// Returns `YES` if the title and subtitle should be tailored for iPad.
+BOOL UseIPadTailoredStringForDefaultBrowserPromo();
+
 #endif  // IOS_CHROME_BROWSER_SHARED_PUBLIC_FEATURES_FEATURES_H_
diff --git a/ios/chrome/browser/shared/public/features/features.mm b/ios/chrome/browser/shared/public/features/features.mm
index 1e77983..19296ec 100644
--- a/ios/chrome/browser/shared/public/features/features.mm
+++ b/ios/chrome/browser/shared/public/features/features.mm
@@ -831,3 +831,9 @@
 BASE_FEATURE(kDefaultBrowserPromoIPadExperimentalString,
              "DefaultBrowserPromoIPadExperimentalString",
              base::FEATURE_DISABLED_BY_DEFAULT);
+
+BOOL UseIPadTailoredStringForDefaultBrowserPromo() {
+  return ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET &&
+         base::FeatureList::IsEnabled(
+             kDefaultBrowserPromoIPadExperimentalString);
+}
diff --git a/ios/chrome/browser/signin/model/BUILD.gn b/ios/chrome/browser/signin/model/BUILD.gn
index 0c4c050c..72a5a6c57 100644
--- a/ios/chrome/browser/signin/model/BUILD.gn
+++ b/ios/chrome/browser/signin/model/BUILD.gn
@@ -69,6 +69,7 @@
     "//components/keyed_service/core",
     "//components/keyed_service/ios",
     "//components/metrics",
+    "//components/policy/core/common:common_constants",
     "//components/pref_registry",
     "//components/prefs",
     "//components/signin/core/browser",
@@ -353,6 +354,7 @@
     ":system_identity_manager",
     ":test_support",
     "//base",
+    "//components/policy/core/common:common_constants",
     "//components/pref_registry",
     "//components/prefs",
     "//components/prefs:test_support",
diff --git a/ios/chrome/browser/signin/model/authentication_service.h b/ios/chrome/browser/signin/model/authentication_service.h
index 9a79d3ac..ab747fa 100644
--- a/ios/chrome/browser/signin/model/authentication_service.h
+++ b/ios/chrome/browser/signin/model/authentication_service.h
@@ -105,6 +105,9 @@
   virtual bool HasPrimaryIdentityManaged(
       signin::ConsentLevel consent_level) const;
 
+  // Returns true if data should be cleared on sign-out.
+  virtual bool ShouldClearDataOnSignOut() const;
+
   // Retrieves the identity of the currently authenticated user or `nil` if
   // either the user is not authenticated, or is authenticated through
   // ClientLogin.
diff --git a/ios/chrome/browser/signin/model/authentication_service.mm b/ios/chrome/browser/signin/model/authentication_service.mm
index 8d183c8..4785c47 100644
--- a/ios/chrome/browser/signin/model/authentication_service.mm
+++ b/ios/chrome/browser/signin/model/authentication_service.mm
@@ -13,6 +13,7 @@
 #import "base/strings/sys_string_conversions.h"
 #import "base/task/single_thread_task_runner.h"
 #import "components/browser_sync/sync_to_signin_migration.h"
+#import "components/policy/core/common/policy_loader_ios_constants.h"
 #import "components/pref_registry/pref_registry_syncable.h"
 #import "components/prefs/pref_service.h"
 #import "components/signin/ios/browser/features.h"
@@ -62,6 +63,13 @@
   return identity_manager->PickAccountIdForAccount(gaia_id, email);
 }
 
+// Returns whether the application is managed through MDM. This
+// checks the key sets in the NSUserDefaults by iOS.
+bool IsApplicationManagedByMDM() {
+  return [[NSUserDefaults standardUserDefaults]
+             dictionaryForKey:kPolicyLoaderIOSConfigurationKey] != nil;
+}
+
 }  // namespace
 
 AuthenticationService::AuthenticationService(
@@ -258,6 +266,18 @@
       .IsManaged();
 }
 
+bool AuthenticationService::ShouldClearDataOnSignOut() const {
+  // Data on the device should be cleared on signout when all conditions are
+  // met:
+  // 1. `kClearDeviceDataOnSignOutForManagedUsers` feaature is enabled).
+  // 2. The user is signed in with a managed account.
+  // 3. The app management configuration key is present.
+  return base::FeatureList::IsEnabled(
+             kClearDeviceDataOnSignOutForManagedUsers) &&
+         HasPrimaryIdentityManaged(signin::ConsentLevel::kSignin) &&
+         !IsApplicationManagedByMDM();
+}
+
 id<SystemIdentity> AuthenticationService::GetPrimaryIdentity(
     signin::ConsentLevel consent_level) const {
   // There is no authenticated identity if there is no signed in user or if the
@@ -402,8 +422,7 @@
   // Get first setup complete value before stopping the sync service.
   const bool is_initial_sync_feature_setup_complete =
       sync_service_->GetUserSettings()->IsInitialSyncFeatureSetupComplete();
-  const bool is_clear_data_feature_for_managed_users_enabled =
-      base::FeatureList::IsEnabled(kClearDeviceDataOnSignOutForManagedUsers);
+  const bool should_clear_data = ShouldClearDataOnSignOut();
 
   auto* account_mutator = identity_manager_->GetPrimaryAccountMutator();
   // GetPrimaryAccountMutator() returns nullptr on ChromeOS only.
@@ -416,7 +435,7 @@
   base::OnceClosure callback_closure =
       completion ? base::BindOnce(completion) : base::DoNothing();
 
-  if (is_managed && is_clear_data_feature_for_managed_users_enabled) {
+  if (should_clear_data) {
     delegate_->ClearBrowsingDataForSignedinPeriod(std::move(callback_closure));
   } else if (force_clear_browsing_data ||
              (is_managed && is_initial_sync_feature_setup_complete) ||
diff --git a/ios/chrome/browser/signin/model/authentication_service_unittest.mm b/ios/chrome/browser/signin/model/authentication_service_unittest.mm
index 25d1ea5e..2a08030 100644
--- a/ios/chrome/browser/signin/model/authentication_service_unittest.mm
+++ b/ios/chrome/browser/signin/model/authentication_service_unittest.mm
@@ -16,6 +16,7 @@
 #import "base/test/metrics/histogram_tester.h"
 #import "base/test/scoped_feature_list.h"
 #import "components/keyed_service/core/service_access_type.h"
+#import "components/policy/core/common/policy_loader_ios_constants.h"
 #import "components/pref_registry/pref_registry_syncable.h"
 #import "components/prefs/pref_registry_simple.h"
 #import "components/signin/ios/browser/features.h"
@@ -497,8 +498,9 @@
 
 // Tests that local data is cleared on signout when
 // `kClearDeviceDataOnSignOutForManagedUsers` is enabled for a managed account.
-TEST_F(AuthenticationServiceTest,
-       SignedInManagedAccountSignOutWithClearDataFeatureEnabled) {
+TEST_F(
+    AuthenticationServiceTest,
+    SignedInManagedAccountSignOutWithClearDataFeatureEnabled_UnmanagedBrowser) {
   scoped_feature_list_.InitWithFeatures(
       {kClearDeviceDataOnSignOutForManagedUsers}, {});
   fake_system_identity_manager()->AddManagedIdentities(@[ @"foo3" ]);
@@ -515,13 +517,45 @@
   // passed. This is intended because signout is not always triggered from UI
   // sources that set this value to true.
   authentication_service()->SignOut(
-      signin_metrics::ProfileSignout::kAbortSignin,
+      signin_metrics::ProfileSignout::kUserClickedSignoutSettings,
       /*force_clear_browsing_data=*/false, nil);
   EXPECT_FALSE(HasCachedMDMInfo(identity(2)));
   EXPECT_EQ(identity_manager()->GetAccountsWithRefreshTokens().size(), 0UL);
   EXPECT_EQ(ClearBrowsingDataCount(), 1);
 }
 
+// Tests that local data is not cleared on managed user's signout when
+// `kClearDeviceDataOnSignOutForManagedUsers` is enabled for a managed account
+// and the browser is managed.
+TEST_F(
+    AuthenticationServiceTest,
+    SignedInManagedAccountSignOutWithClearDataFeatureEnabled_ManagedBrowser) {
+  scoped_feature_list_.InitWithFeatures(
+      {kClearDeviceDataOnSignOutForManagedUsers}, {});
+  // Add managed configuration so the browser is managed.
+  NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
+  NSDictionary* dict = @{@"key" : @"value"};
+  [userDefaults setObject:dict forKey:kPolicyLoaderIOSConfigurationKey];
+  fake_system_identity_manager()->AddManagedIdentities(@[ @"foo3" ]);
+
+  authentication_service()->SignIn(
+      identity(2), signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN);
+  ASSERT_EQ(identity_manager()->GetAccountsWithRefreshTokens().size(), 3UL);
+  ASSERT_TRUE(authentication_service()->HasPrimaryIdentityManaged(
+      signin::ConsentLevel::kSignin));
+  VerifyLastSigninTimestamp();
+
+  SetCachedMDMInfo(identity(2), CreateRefreshAccessTokenError(identity(0)));
+  // Data should not be cleared if the browser is managed.
+  authentication_service()->SignOut(
+      signin_metrics::ProfileSignout::kAbortSignin,
+      /*force_clear_browsing_data=*/false, nil);
+  ASSERT_FALSE(HasCachedMDMInfo(identity(2)));
+  ASSERT_EQ(identity_manager()->GetAccountsWithRefreshTokens().size(), 0UL);
+  EXPECT_EQ(ClearBrowsingDataCount(), 0);
+  [userDefaults removeObjectForKey:kPolicyLoaderIOSConfigurationKey];
+}
+
 // Tests that MDM errors do not lead to seeding empty account ids.
 //
 // Regression test for root cause of crbug/1482236
diff --git a/ios/chrome/browser/supervised_user/model/child_account_service_factory_unittest.mm b/ios/chrome/browser/supervised_user/model/child_account_service_factory_unittest.mm
index 0d49ee6a0..924523b9 100644
--- a/ios/chrome/browser/supervised_user/model/child_account_service_factory_unittest.mm
+++ b/ios/chrome/browser/supervised_user/model/child_account_service_factory_unittest.mm
@@ -32,7 +32,7 @@
 // with an off-the-record ChromeBrowserState.
 TEST_F(ChildAccountServiceFactoryTest, ReturnsNullOnOffTheRecordBrowserState) {
   ChromeBrowserState* otr_browser_state =
-      browser_state_->CreateOffTheRecordBrowserStateWithTestingFactories({});
+      browser_state_->CreateOffTheRecordBrowserStateWithTestingFactories();
   CHECK(otr_browser_state);
   supervised_user::ChildAccountService* service =
       ChildAccountServiceFactory::GetForBrowserState(otr_browser_state);
diff --git a/ios/chrome/browser/supervised_user/model/list_family_members_service_factory_unittest.mm b/ios/chrome/browser/supervised_user/model/list_family_members_service_factory_unittest.mm
index f231c3f..52afce1d 100644
--- a/ios/chrome/browser/supervised_user/model/list_family_members_service_factory_unittest.mm
+++ b/ios/chrome/browser/supervised_user/model/list_family_members_service_factory_unittest.mm
@@ -31,7 +31,7 @@
 TEST_F(ListFamilyMembersServiceFactoryTest,
        ReturnsNullOnOffTheRecordBrowserState) {
   ChromeBrowserState* otr_browser_state =
-      browser_state_->CreateOffTheRecordBrowserStateWithTestingFactories({});
+      browser_state_->CreateOffTheRecordBrowserStateWithTestingFactories();
   CHECK(otr_browser_state);
   supervised_user::ListFamilyMembersService* service =
       ListFamilyMembersServiceFactory::GetForBrowserState(otr_browser_state);
diff --git a/ios/chrome/browser/supervised_user/model/supervised_user_metrics_service_factory_unittest.mm b/ios/chrome/browser/supervised_user/model/supervised_user_metrics_service_factory_unittest.mm
index 099fb433..f88701eb 100644
--- a/ios/chrome/browser/supervised_user/model/supervised_user_metrics_service_factory_unittest.mm
+++ b/ios/chrome/browser/supervised_user/model/supervised_user_metrics_service_factory_unittest.mm
@@ -34,7 +34,7 @@
 TEST_F(SupervisedUserMetricsServiceFactoryTest,
        ReturnsNullOnOffTheRecordBrowserState) {
   ChromeBrowserState* otr_browser_state =
-      browser_state_->CreateOffTheRecordBrowserStateWithTestingFactories({});
+      browser_state_->CreateOffTheRecordBrowserStateWithTestingFactories();
   CHECK(otr_browser_state);
   supervised_user::SupervisedUserMetricsService* service =
       SupervisedUserMetricsServiceFactory::GetForBrowserState(
diff --git a/ios/chrome/browser/supervised_user/model/supervised_user_service_factory_unittest.mm b/ios/chrome/browser/supervised_user/model/supervised_user_service_factory_unittest.mm
index 21adc474..c8569636 100644
--- a/ios/chrome/browser/supervised_user/model/supervised_user_service_factory_unittest.mm
+++ b/ios/chrome/browser/supervised_user/model/supervised_user_service_factory_unittest.mm
@@ -71,7 +71,7 @@
 TEST_F(SupervisedUserServiceFactoryTest,
        ReturnsNullOnOffTheRecordBrowserState) {
   ChromeBrowserState* otr_browser_state =
-      browser_state_->CreateOffTheRecordBrowserStateWithTestingFactories({});
+      browser_state_->CreateOffTheRecordBrowserStateWithTestingFactories();
   CHECK(otr_browser_state);
   supervised_user::SupervisedUserService* service =
       SupervisedUserServiceFactory::GetForBrowserState(otr_browser_state);
diff --git a/ios/chrome/browser/tab_insertion/model/BUILD.gn b/ios/chrome/browser/tab_insertion/model/BUILD.gn
index cf40f8b..1a86f0e 100644
--- a/ios/chrome/browser/tab_insertion/model/BUILD.gn
+++ b/ios/chrome/browser/tab_insertion/model/BUILD.gn
@@ -9,6 +9,7 @@
   ]
   deps = [
     "//build:blink_buildflags",
+    "//components/tab_groups",
     "//ios/chrome/browser/ntp/model",
     "//ios/chrome/browser/sessions:session_restoration_service",
     "//ios/chrome/browser/sessions:session_restoration_service_factory",
diff --git a/ios/chrome/browser/tab_insertion/model/tab_insertion_browser_agent.mm b/ios/chrome/browser/tab_insertion/model/tab_insertion_browser_agent.mm
index b081104..0653dcf 100644
--- a/ios/chrome/browser/tab_insertion/model/tab_insertion_browser_agent.mm
+++ b/ios/chrome/browser/tab_insertion/model/tab_insertion_browser_agent.mm
@@ -5,6 +5,7 @@
 #import "ios/chrome/browser/tab_insertion/model/tab_insertion_browser_agent.h"
 
 #import "build/blink_buildflags.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "ios/chrome/browser/ntp/model/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/sessions/session_restoration_service.h"
 #import "ios/chrome/browser/sessions/session_restoration_service_factory.h"
@@ -120,7 +121,8 @@
       web_state_list->CreateGroup(
           {web_state_list->GetIndexOfWebState(web_state_ptr)},
           tab_groups::TabGroupVisualData{
-              u"", TabGroup::DefaultColorForNewTabGroup(web_state_list)});
+              u"", TabGroup::DefaultColorForNewTabGroup(web_state_list)},
+          tab_groups::TabGroupId::GenerateNew());
     }
   }
   return web_state_ptr;
diff --git a/ios/chrome/browser/tabs/model/BUILD.gn b/ios/chrome/browser/tabs/model/BUILD.gn
index 118cbfa8..6e1d2a8 100644
--- a/ios/chrome/browser/tabs/model/BUILD.gn
+++ b/ios/chrome/browser/tabs/model/BUILD.gn
@@ -83,6 +83,7 @@
     "//ios/chrome/browser/itunes_urls/model",
     "//ios/chrome/browser/language/model",
     "//ios/chrome/browser/lens/model",
+    "//ios/chrome/browser/lens_overlay/model",
     "//ios/chrome/browser/link_to_text/model",
     "//ios/chrome/browser/main/model",
     "//ios/chrome/browser/metrics/model",
diff --git a/ios/chrome/browser/tabs/model/inactive_tabs/BUILD.gn b/ios/chrome/browser/tabs/model/inactive_tabs/BUILD.gn
index b6de90b7..dc80ae2e5 100644
--- a/ios/chrome/browser/tabs/model/inactive_tabs/BUILD.gn
+++ b/ios/chrome/browser/tabs/model/inactive_tabs/BUILD.gn
@@ -41,6 +41,7 @@
     ":features",
     ":inactive_tabs",
     "//base/test:test_support",
+    "//components/tab_groups",
     "//ios/chrome/browser/ntp/model",
     "//ios/chrome/browser/shared/model/browser/test:test_support",
     "//ios/chrome/browser/shared/model/browser_state:test_support",
diff --git a/ios/chrome/browser/tabs/model/inactive_tabs/utils_unittest.mm b/ios/chrome/browser/tabs/model/inactive_tabs/utils_unittest.mm
index 2a7d7bef..08cffbd6 100644
--- a/ios/chrome/browser/tabs/model/inactive_tabs/utils_unittest.mm
+++ b/ios/chrome/browser/tabs/model/inactive_tabs/utils_unittest.mm
@@ -7,6 +7,7 @@
 #import "base/test/metrics/histogram_tester.h"
 #import "base/test/scoped_feature_list.h"
 #import "base/test/task_environment.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "ios/chrome/browser/ntp/model/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/ntp/model/new_tab_page_tab_helper_delegate.h"
 #import "ios/chrome/browser/shared/model/browser/test/test_browser.h"
@@ -29,6 +30,8 @@
 #import "third_party/ocmock/OCMock/OCMock.h"
 #import "ui/base/device_form_factor.h"
 
+using tab_groups::TabGroupId;
+
 // Fake WebStateList delegate that attaches the required tab helper.
 class InactiveTabsFakeWebStateListDelegate : public FakeWebStateListDelegate {
  public:
@@ -664,7 +667,7 @@
   EXPECT_EQ(active_web_state_list->count(), 3);
   EXPECT_EQ(inactive_web_state_list->count(), 0);
 
-  active_web_state_list->CreateGroup({0}, {});
+  active_web_state_list->CreateGroup({0}, {}, TabGroupId::GenerateNew());
 
   EXPECT_EQ(active_web_state_list->count(), 3);
   EXPECT_EQ(inactive_web_state_list->count(), 0);
diff --git a/ios/chrome/browser/tabs/model/tab_helper_util.mm b/ios/chrome/browser/tabs/model/tab_helper_util.mm
index 5b048ccc..91fb734 100644
--- a/ios/chrome/browser/tabs/model/tab_helper_util.mm
+++ b/ios/chrome/browser/tabs/model/tab_helper_util.mm
@@ -59,6 +59,7 @@
 #import "ios/chrome/browser/infobars/model/overlays/translate_overlay_tab_helper.h"
 #import "ios/chrome/browser/itunes_urls/model/itunes_urls_handler_tab_helper.h"
 #import "ios/chrome/browser/lens/model/lens_tab_helper.h"
+#import "ios/chrome/browser/lens_overlay/model/lens_overlay_tab_helper.h"
 #import "ios/chrome/browser/link_to_text/model/link_to_text_tab_helper.h"
 #import "ios/chrome/browser/metrics/model/pageload_foreground_duration_tab_helper.h"
 #import "ios/chrome/browser/ntp/model/new_tab_page_tab_helper.h"
@@ -162,6 +163,9 @@
     // created before AppLauncherTabHelper, which will filter out
     // unhandled schemes.
     LensTabHelper::CreateForWebState(web_state);
+    if (base::FeatureList::IsEnabled(kEnableLensOverlay)) {
+      LensOverlayTabHelper::CreateForWebState(web_state);
+    }
     AppLauncherTabHelper::CreateForWebState(
         web_state, [[AppLauncherAbuseDetector alloc] init], is_off_the_record);
   }
diff --git a/ios/chrome/browser/tabs/model/tabs_closer.mm b/ios/chrome/browser/tabs/model/tabs_closer.mm
index 9534560..9bff830 100644
--- a/ios/chrome/browser/tabs/model/tabs_closer.mm
+++ b/ios/chrome/browser/tabs/model/tabs_closer.mm
@@ -24,6 +24,13 @@
 
 namespace {
 
+// Information about a tab group.
+struct TabGroupInfo {
+  const TabGroupRange group_range;
+  const tab_groups::TabGroupId tab_group_id;
+  const tab_groups::TabGroupVisualData visual_data;
+};
+
 // Moves WebStates in range [start; start+count) from `source` to `target`.
 void MoveWebStatesInRangeBetweenLists(WebStateList* source,
                                       WebStateList* target,
@@ -46,7 +53,7 @@
       old_active_index, RemovingIndexes({.start = start, .count = count})));
 
   // Store the groups info.
-  std::vector<std::pair<TabGroupRange, tab_groups::TabGroupVisualData>> groups;
+  std::vector<TabGroupInfo> groups;
   for (const TabGroup* group : source->GetGroups()) {
     TabGroupRange range = group->range();
     // The group is not in the range of moving items, ignore it.
@@ -59,7 +66,11 @@
     // range of closed items.
     CHECK(start <= range.range_begin() && range.range_end() <= end);
     range.Move(offset - start);
-    groups.push_back({range, group->visual_data()});
+    groups.push_back(TabGroupInfo{
+        .group_range = range,
+        .tab_group_id = group->tab_group_id(),
+        .visual_data = group->visual_data(),
+    });
   }
 
   for (int n = 0; n < count; ++n) {
@@ -77,8 +88,9 @@
   }
 
   // Restore the groups info.
-  for (const auto& [range, visual_data] : groups) {
-    target->CreateGroup(range.AsSet(), visual_data);
+  for (const auto& group : groups) {
+    target->CreateGroup(group.group_range.AsSet(), group.visual_data,
+                        group.tab_group_id);
   }
 }
 
diff --git a/ios/chrome/browser/ui/authentication/account_switching/BUILD.gn b/ios/chrome/browser/ui/authentication/account_switching/BUILD.gn
index 910d31bfe..f80a708c 100644
--- a/ios/chrome/browser/ui/authentication/account_switching/BUILD.gn
+++ b/ios/chrome/browser/ui/authentication/account_switching/BUILD.gn
@@ -11,6 +11,7 @@
   ]
   deps = [
     ":account_switching_ui",
+    ":constants",
     "//base",
     "//ios/chrome/browser/shared/coordinator/chrome_coordinator",
     "//ios/chrome/browser/shared/ui/table_view:utils",
@@ -49,3 +50,20 @@
     "//base",
   ]
 }
+
+source_set("eg2_tests") {
+  configs += [ "//build/config/ios:xctest_config" ]
+  testonly = true
+  sources = [ "account_switching_egtest.mm" ]
+  deps = [
+    ":constants",
+    "//base/test:test_support",
+    "//ios/chrome/browser/signin/model:fake_system_identity",
+    "//ios/chrome/browser/ui/authentication:eg_test_support+eg2",
+    "//ios/chrome/browser/ui/ntp:constants",
+    "//ios/chrome/browser/ui/ntp:feature_flags",
+    "//ios/chrome/test/earl_grey:eg_test_support+eg2",
+    "//ios/testing/earl_grey:eg_test_support+eg2",
+  ]
+  frameworks = [ "UIKit.framework" ]
+}
diff --git a/ios/chrome/browser/ui/authentication/account_switching/account_switcher_coordinator.mm b/ios/chrome/browser/ui/authentication/account_switching/account_switcher_coordinator.mm
index a917426..c711730d 100644
--- a/ios/chrome/browser/ui/authentication/account_switching/account_switcher_coordinator.mm
+++ b/ios/chrome/browser/ui/authentication/account_switching/account_switcher_coordinator.mm
@@ -7,6 +7,7 @@
 #import "base/check.h"
 #import "ios/chrome/browser/shared/ui/table_view/table_view_utils.h"
 #import "ios/chrome/browser/ui/authentication/account_switching/account_switcher_view_controller.h"
+#import "ios/chrome/browser/ui/authentication/account_switching/account_switching_constants.h"
 
 @implementation AccountSwitcherCoordinator {
   AccountSwitcherViewController* _viewController;
@@ -32,6 +33,7 @@
         initWithBarButtonSystemItem:UIBarButtonSystemItemClose
                              target:self
                              action:@selector(didTapClose)];
+    closeButton.accessibilityIdentifier = kAccountSwitchingCloseButtonId;
     _viewController.navigationItem.rightBarButtonItem = closeButton;
   }
 
@@ -41,7 +43,12 @@
 }
 
 - (void)stop {
-  DCHECK(_viewController);
+  // TODO(crbug.com/336719423): Change condition to CHECK(_viewController). But
+  // firt inform the parent coordinator at didTapClose that this view was
+  // dismissed.
+  if (!_viewController) {
+    return;
+  }
   [_viewController dismissViewControllerAnimated:YES completion:nil];
   _viewController = nil;
   [super stop];
diff --git a/ios/chrome/browser/ui/authentication/account_switching/account_switching_constants.h b/ios/chrome/browser/ui/authentication/account_switching/account_switching_constants.h
index 358803a4..e23c5e7 100644
--- a/ios/chrome/browser/ui/authentication/account_switching/account_switching_constants.h
+++ b/ios/chrome/browser/ui/authentication/account_switching/account_switching_constants.h
@@ -9,5 +9,7 @@
 
 // The accessibility identifier of the view controller's view.
 extern NSString* const kAccountSwitchingTableViewId;
+// The accessibility identifier of the view controlle's close button.
+extern NSString* const kAccountSwitchingCloseButtonId;
 
 #endif  // IOS_CHROME_BROWSER_UI_AUTHENTICATION_ACCOUNT_SWITCHING_ACCOUNT_SWITCHING_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/authentication/account_switching/account_switching_constants.mm b/ios/chrome/browser/ui/authentication/account_switching/account_switching_constants.mm
index 26a8cad..4b474c13 100644
--- a/ios/chrome/browser/ui/authentication/account_switching/account_switching_constants.mm
+++ b/ios/chrome/browser/ui/authentication/account_switching/account_switching_constants.mm
@@ -5,3 +5,5 @@
 #import "ios/chrome/browser/ui/authentication/account_switching/account_switching_constants.h"
 
 NSString* const kAccountSwitchingTableViewId = @"AccountSwitchingTableViewId";
+NSString* const kAccountSwitchingCloseButtonId =
+    @"AccountSwitchingCloseButtonId";
diff --git a/ios/chrome/browser/ui/authentication/account_switching/account_switching_egtest.mm b/ios/chrome/browser/ui/authentication/account_switching/account_switching_egtest.mm
new file mode 100644
index 0000000..af26359
--- /dev/null
+++ b/ios/chrome/browser/ui/authentication/account_switching/account_switching_egtest.mm
@@ -0,0 +1,86 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <UIKit/UIKit.h>
+
+#import "ios/chrome/browser/signin/model/fake_system_identity.h"
+#import "ios/chrome/browser/ui/authentication/account_switching/account_switching_constants.h"
+#import "ios/chrome/browser/ui/authentication/signin_earl_grey.h"
+#import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.h"
+#import "ios/chrome/browser/ui/ntp/new_tab_page_constants.h"
+#import "ios/chrome/browser/ui/ntp/new_tab_page_feature.h"
+#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
+#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
+#import "ios/chrome/test/earl_grey/chrome_matchers.h"
+#import "ios/chrome/test/earl_grey/chrome_matchers_app_interface.h"
+#import "ios/chrome/test/earl_grey/web_http_server_chrome_test_case.h"
+#import "ios/testing/earl_grey/earl_grey_test.h"
+
+// Integration tests using the Account Switching menu.
+@interface AccountSwitchingTestCase : WebHttpServerChromeTestCase
+@end
+
+@implementation AccountSwitchingTestCase
+
+- (AppLaunchConfiguration)appConfigurationForTestCase {
+  AppLaunchConfiguration config = [super appConfigurationForTestCase];
+
+  config.features_enabled.push_back(kIdentityDiscAccountSwitch);
+
+  return config;
+}
+
+- (void)testViewAccountSwitchingMenu {
+  // Sign in.
+  FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1];
+  [SigninEarlGrey signinWithFakeIdentity:fakeIdentity];
+
+  // Select the identity disc particle.
+  [[EarlGrey
+      selectElementWithMatcher:grey_accessibilityID(kNTPFeedHeaderIdentityDisc)]
+      performAction:grey_tap()];
+
+  // Ensure the Account Switching menu is displayed.
+  [[EarlGrey
+      selectElementWithMatcher:grey_allOf(grey_accessibilityID(
+                                              kAccountSwitchingTableViewId),
+                                          grey_sufficientlyVisible(), nil)]
+      assertWithMatcher:grey_sufficientlyVisible()];
+}
+
+- (void)testCloseButtonAccountSwitchingMenu {
+  if ([ChromeEarlGrey isIPadIdiom]) {
+    EARL_GREY_TEST_DISABLED(@"The close button exists only on iPhones.");
+  }
+
+  // Sign in.
+  FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1];
+  [SigninEarlGrey signinWithFakeIdentity:fakeIdentity];
+
+  // Select the identity disc particle.
+  [[EarlGrey
+      selectElementWithMatcher:grey_accessibilityID(kNTPFeedHeaderIdentityDisc)]
+      performAction:grey_tap()];
+
+  // Ensure the Account Switching menu is displayed.
+  [[EarlGrey
+      selectElementWithMatcher:grey_allOf(grey_accessibilityID(
+                                              kAccountSwitchingTableViewId),
+                                          grey_sufficientlyVisible(), nil)]
+      assertWithMatcher:grey_sufficientlyVisible()];
+
+  // Tap on the Close button.
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
+                                          kAccountSwitchingCloseButtonId)]
+      performAction:grey_tap()];
+
+  // Verify the Account Switching menu is dismissed.
+  [[EarlGrey
+      selectElementWithMatcher:grey_allOf(grey_accessibilityID(
+                                              kAccountSwitchingTableViewId),
+                                          grey_sufficientlyVisible(), nil)]
+      assertWithMatcher:grey_notVisible()];
+}
+
+@end
diff --git a/ios/chrome/browser/ui/authentication/signout_action_sheet/BUILD.gn b/ios/chrome/browser/ui/authentication/signout_action_sheet/BUILD.gn
index 422c2502..905abee 100644
--- a/ios/chrome/browser/ui/authentication/signout_action_sheet/BUILD.gn
+++ b/ios/chrome/browser/ui/authentication/signout_action_sheet/BUILD.gn
@@ -68,6 +68,7 @@
     "//base",
     "//base/test:test_support",
     "//build:branding_buildflags",
+    "//components/policy/core/common:common_constants",
     "//components/sync/base:features",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/shared/public/features",
diff --git a/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_coordinator.mm b/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_coordinator.mm
index 3773259d..1dc963a 100644
--- a/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_coordinator.mm
+++ b/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_coordinator.mm
@@ -162,9 +162,7 @@
   DCHECK(self.browser);
   syncer::SyncService* syncService =
       SyncServiceFactory::GetForBrowserState(self.browser->GetBrowserState());
-  if (self.authenticationService->HasPrimaryIdentityManaged(
-          signin::ConsentLevel::kSignin) &&
-      base::FeatureList::IsEnabled(kClearDeviceDataOnSignOutForManagedUsers)) {
+  if (self.authenticationService->ShouldClearDataOnSignOut()) {
     return SignedInUserStateWithManagedAccountClearsDataOnSignout;
   }
   // TODO(crbug.com/40066949): Simplify once ConsentLevel::kSync and
diff --git a/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_egtest.mm b/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_egtest.mm
index 244689fc..7cff408 100644
--- a/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_egtest.mm
+++ b/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_egtest.mm
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#import "base/strings/strcat.h"
 #import "base/strings/sys_string_conversions.h"
+#import "components/policy/core/common/policy_loader_ios_constants.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/model/fake_system_identity.h"
 #import "ios/chrome/browser/ui/authentication/signin_earl_grey.h"
@@ -16,6 +18,7 @@
 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
 #import "ios/chrome/test/earl_grey/chrome_test_case.h"
 #import "ios/testing/earl_grey/app_launch_configuration.h"
+#import "ios/testing/earl_grey/app_launch_manager.h"
 #import "ios/testing/earl_grey/earl_grey_test.h"
 #import "ui/base/l10n/l10n_util_mac.h"
 
@@ -72,6 +75,14 @@
   return config;
 }
 
+- (AppLaunchConfiguration)managedAppConfigurationForTestCase {
+  AppLaunchConfiguration config = self.appConfigurationForTestCase;
+  config.additional_args.push_back(base::StrCat(
+      {"-", base::SysNSStringToUTF8(kPolicyLoaderIOSConfigurationKey)}));
+  config.additional_args.push_back(std::string("<dict></dict>"));
+  return config;
+}
+
 // Tests the sign-out flow from the accounts table view. This test
 // also makes sure the settings are not blocked after the sign-out.
 // Related to crbug.com/1471942.
@@ -171,4 +182,22 @@
   [SigninEarlGrey verifySignedInWithFakeIdentity:fakeManagedIdentity];
 }
 
+// Tests the signout flow for managed users in a managed browser does not show
+// the dialog for clearing data on sign-out.
+- (void)testNoSignoutConfirmationForManagedIdentityInManagedBrowser {
+  // Relaunch the app with managed config to take the configuration into
+  // account.
+  [[AppLaunchManager sharedManager]
+      ensureAppLaunchedWithConfiguration:
+          [self managedAppConfigurationForTestCase]];
+  // Sign in with managed account.
+  FakeSystemIdentity* fakeManagedIdentity =
+      [FakeSystemIdentity fakeManagedIdentity];
+  [SigninEarlGreyUI signinWithFakeIdentity:fakeManagedIdentity];
+
+  // The sign out button should directly sign out the user.
+  ClickSignOutInAccountSettings();
+  [SigninEarlGrey verifySignedOut];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/autofill/bottom_sheet/payments_suggestion_bottom_sheet_mediator.mm b/ios/chrome/browser/ui/autofill/bottom_sheet/payments_suggestion_bottom_sheet_mediator.mm
index ce9bec60..4542fdf 100644
--- a/ios/chrome/browser/ui/autofill/bottom_sheet/payments_suggestion_bottom_sheet_mediator.mm
+++ b/ios/chrome/browser/ui/autofill/bottom_sheet/payments_suggestion_bottom_sheet_mediator.mm
@@ -242,15 +242,16 @@
                       minorValue:nil
               displayDescription:nil
                             icon:nil
-                     popupItemId:
-                         ((base::FeatureList::IsEnabled(
-                               autofill::features::
-                                   kAutofillEnableVirtualCards) &&
-                           ([creditCardData recordType] ==
-                            autofill::CreditCard::RecordType::kVirtualCard))
-                              ? autofill::SuggestionType::
-                                    kVirtualCreditCardEntry
-                              : autofill::SuggestionType::kCreditCardEntry)
+                            type:((base::FeatureList::IsEnabled(
+                                       autofill::features::
+                                           kAutofillEnableVirtualCards) &&
+                                   ([creditCardData recordType] ==
+                                    autofill::CreditCard::RecordType::
+                                        kVirtualCard))
+                                      ? autofill::SuggestionType::
+                                            kVirtualCreditCardEntry
+                                      : autofill::SuggestionType::
+                                            kCreditCardEntry)
                backendIdentifier:[creditCardData backendIdentifier]
                   requiresReauth:NO
       acceptanceA11yAnnouncement:
diff --git a/ios/chrome/browser/ui/autofill/bottom_sheet/payments_suggestion_bottom_sheet_view_controller.mm b/ios/chrome/browser/ui/autofill/bottom_sheet/payments_suggestion_bottom_sheet_view_controller.mm
index 471a9f6..e45305e 100644
--- a/ios/chrome/browser/ui/autofill/bottom_sheet/payments_suggestion_bottom_sheet_view_controller.mm
+++ b/ios/chrome/browser/ui/autofill/bottom_sheet/payments_suggestion_bottom_sheet_view_controller.mm
@@ -40,7 +40,7 @@
 CGFloat const kSpacingAfterImage = 4;
 
 // Height of the logo used as the title of the bottom sheet.
-CGFloat const kTitleLogoHeight = 24;
+CGFloat const kTitleLogoHeight = 50;
 
 }  // namespace
 
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.mm b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.mm
index 130c1fd..106bfb5 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.mm
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.mm
@@ -722,12 +722,12 @@
 
 // Logs information about what type of suggestion the user selected.
 - (void)logReauthenticationEvent:(ReauthenticationEvent)reauthenticationEvent
-                     popupItemId:(autofill::SuggestionType)popupItemId {
+                            type:(autofill::SuggestionType)type {
   std::string histogramName;
   if (self.currentProvider.type == SuggestionProviderTypePassword) {
     histogramName = "IOS.Reauth.Password.Autofill";
   } else if (self.currentProvider.type == SuggestionProviderTypeAutofill) {
-    switch (popupItemId) {
+    switch (type) {
       case autofill::SuggestionType::kCreditCardEntry:
       case autofill::SuggestionType::kVirtualCreditCardEntry:
         histogramName = "IOS.Reauth.CreditCard.Autofill";
@@ -772,11 +772,11 @@
 
 - (void)didSelectSuggestion:(FormSuggestion*)formSuggestion {
   [self logReauthenticationEvent:ReauthenticationEvent::kAttempt
-                     popupItemId:formSuggestion.popupItemId];
+                            type:formSuggestion.type];
 
   if (!formSuggestion.requiresReauth) {
     [self logReauthenticationEvent:ReauthenticationEvent::kSuccess
-                       popupItemId:formSuggestion.popupItemId];
+                              type:formSuggestion.type];
     [self handleSuggestion:formSuggestion];
     return;
   }
@@ -785,11 +785,11 @@
     auto completionHandler = ^(ReauthenticationResult result) {
       if (result != ReauthenticationResult::kFailure) {
         [self logReauthenticationEvent:ReauthenticationEvent::kSuccess
-                           popupItemId:formSuggestion.popupItemId];
+                                  type:formSuggestion.type];
         [self handleSuggestion:formSuggestion];
       } else {
         [self logReauthenticationEvent:ReauthenticationEvent::kFailure
-                           popupItemId:formSuggestion.popupItemId];
+                                  type:formSuggestion.type];
       }
     };
 
@@ -799,7 +799,7 @@
                                  handler:completionHandler];
   } else {
     [self logReauthenticationEvent:ReauthenticationEvent::kMissingPasscode
-                       popupItemId:formSuggestion.popupItemId];
+                              type:formSuggestion.type];
     [self handleSuggestion:formSuggestion];
   }
 }
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator_unittest.mm b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator_unittest.mm
index d736249b..e2f3461 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator_unittest.mm
@@ -160,7 +160,7 @@
       suggestionWithValue:@"value"
        displayDescription:@"display-description"
                      icon:nil
-              popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                     type:autofill::SuggestionType::kAutocompleteEntry
         backendIdentifier:nil
            requiresReauth:NO];
   NSArray<FormSuggestion*>* suggestions = [NSArray arrayWithObject:suggestion];
@@ -210,7 +210,7 @@
       suggestionWithValue:@"value"
        displayDescription:@"display-description"
                      icon:nil
-              popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                     type:autofill::SuggestionType::kAutocompleteEntry
         backendIdentifier:nil
            requiresReauth:NO];
   NSArray<FormSuggestion*>* suggestions_from_first_query =
@@ -220,7 +220,7 @@
       suggestionWithValue:@"value2"
        displayDescription:@"display-description"
                      icon:nil
-              popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                     type:autofill::SuggestionType::kAutocompleteEntry
         backendIdentifier:nil
            requiresReauth:NO];
   NSArray<FormSuggestion*>* suggestions_from_second_query =
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_suggestion_label.mm b/ios/chrome/browser/ui/autofill/form_input_accessory/form_suggestion_label.mm
index 507d49f..348c5f96 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_suggestion_label.mm
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_suggestion_label.mm
@@ -273,9 +273,8 @@
 
 // Returns whether this label is for a credit card suggestion.
 - (BOOL)isCreditCardSuggestion {
-  return (_suggestion.popupItemId ==
-          autofill::SuggestionType::kCreditCardEntry) ||
-         (_suggestion.popupItemId ==
+  return (_suggestion.type == autofill::SuggestionType::kCreditCardEntry) ||
+         (_suggestion.type ==
           autofill::SuggestionType::kVirtualCreditCardEntry);
 }
 
@@ -301,7 +300,7 @@
   // moment of setting up the label's width anchor.
   CGSize windowSize = [[UIScreen mainScreen] bounds].size;
   CGFloat portraitScreenWidth = MIN(windowSize.width, windowSize.height);
-  switch (_suggestion.popupItemId) {
+  switch (_suggestion.type) {
     case autofill::SuggestionType::kCreditCardEntry:
     case autofill::SuggestionType::kVirtualCreditCardEntry: {
       // Max width is just enough to show half of the credit card icon on the
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_address_cell.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_address_cell.mm
index 3467733..289e92c 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_address_cell.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_address_cell.mm
@@ -664,7 +664,7 @@
                       minorValue:nil
               displayDescription:nil
                             icon:nil
-                     popupItemId:autofill::SuggestionType::kAddressEntry
+                            type:autofill::SuggestionType::kAddressEntry
                backendIdentifier:[self.address GUID]
                   requiresReauth:NO
       acceptanceA11yAnnouncement:
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_card_cell.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_card_cell.mm
index d5785b5..27891e4a 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_card_cell.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_card_cell.mm
@@ -713,7 +713,7 @@
 // Called when the "Autofill Form" button is tapped. Fills the current form with
 // the card's data.
 - (void)onAutofillFormButtonTapped {
-  autofill::SuggestionType popupItemId =
+  autofill::SuggestionType type =
       autofill::VirtualCardFeatureEnabled() &&
               [self.card recordType] == kVirtualCard
           ? autofill::SuggestionType::kVirtualCreditCardEntry
@@ -723,7 +723,7 @@
                                minorValue:nil
                        displayDescription:nil
                                      icon:nil
-                              popupItemId:popupItemId
+                                     type:type
                         backendIdentifier:[self.card GUID]
                            requiresReauth:NO
                acceptanceA11yAnnouncement:
diff --git a/ios/chrome/browser/ui/browser_view/DEPS b/ios/chrome/browser/ui/browser_view/DEPS
deleted file mode 100644
index 8f4128c..0000000
--- a/ios/chrome/browser/ui/browser_view/DEPS
+++ /dev/null
@@ -1,14 +0,0 @@
-include_rules = [
-  "+ios/chrome/browser/ui/browser_view",
-  "+ios/chrome/browser/ui",
-  # Use ios/chrome/browser/ui/authentication/signin_earl_grey.h instead
-  "-ios/chrome/browser/ui/authentication/signin_earl_grey_app_interface.h",
-  # use ios/chrome/browser/bookmarks/ui_bundled/bookmark_earl_grey.h instead
-  "-ios/chrome/browser/bookmarks/ui_bundled/bookmark_earl_grey_app_interface.h",
-]
-
-specific_include_rules = {
-  "key_commands_provider_unittest\.mm": [
-    "+ios/web/find_in_page/java_script_find_in_page_manager_impl.h",
-  ],
-}
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_visibility_consumer.h b/ios/chrome/browser/ui/browser_view/browser_view_visibility_consumer.h
deleted file mode 100644
index 7b6f1b2..0000000
--- a/ios/chrome/browser/ui/browser_view/browser_view_visibility_consumer.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2024 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_UI_BROWSER_VIEW_BROWSER_VIEW_VISIBILITY_CONSUMER_H_
-#define IOS_CHROME_BROWSER_UI_BROWSER_VIEW_BROWSER_VIEW_VISIBILITY_CONSUMER_H_
-
-/// Consumer protocol that gets notified when the browser view's visibility has
-/// changed.
-@protocol BrowserViewVisibilityConsumer
-
-/// Method that responds to browser view visibility changes.
-- (void)browserViewDidChangeVisibility;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_BROWSER_VIEW_BROWSER_VIEW_VISIBILITY_CONSUMER_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
index 4a90002..53014825 100644
--- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn
+++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -347,6 +347,7 @@
     "//components/segmentation_platform/public",
     "//components/signin/internal/identity_manager",
     "//components/strings",
+    "//components/supervised_user/core/common:features",
     "//components/sync/base:features",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/flags:system_flags",
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/shortcuts_mediator_unittest.mm b/ios/chrome/browser/ui/content_suggestions/cells/shortcuts_mediator_unittest.mm
index 29d76e60..5d8a4dca 100644
--- a/ios/chrome/browser/ui/content_suggestions/cells/shortcuts_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/cells/shortcuts_mediator_unittest.mm
@@ -45,7 +45,7 @@
                             std::vector<scoped_refptr<ReadingListEntry>>()));
     test_cbs_builder.AddTestingFactory(
         AuthenticationServiceFactory::GetInstance(),
-        base::BindRepeating(AuthenticationServiceFactory::GetDefaultFactory()));
+        AuthenticationServiceFactory::GetDefaultFactory());
     test_cbs_builder.AddTestingFactory(
         feature_engagement::TrackerFactory::GetInstance(),
         base::BindRepeating(&BuildFeatureEngagementMockTracker));
diff --git a/ios/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_ranking_model_unittest.mm b/ios/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_ranking_model_unittest.mm
index e12ef61..364da462 100644
--- a/ios/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_ranking_model_unittest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_ranking_model_unittest.mm
@@ -205,7 +205,7 @@
     TestChromeBrowserState::Builder test_cbs_builder;
     test_cbs_builder.AddTestingFactory(
         AuthenticationServiceFactory::GetInstance(),
-        base::BindRepeating(AuthenticationServiceFactory::GetDefaultFactory()));
+        AuthenticationServiceFactory::GetDefaultFactory());
     test_cbs_builder.AddTestingFactory(
         segmentation_platform::SegmentationPlatformServiceFactory::
             GetInstance(),
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
index b201bcfd..c128c17e 100644
--- a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
@@ -13,6 +13,7 @@
 #import "components/search_engines/prepopulated_engines.h"
 #import "components/search_engines/search_engines_switches.h"
 #import "components/strings/grit/components_strings.h"
+#import "components/supervised_user/core/common/features.h"
 #import "ios/chrome/browser/flags/chrome_switches.h"
 #import "ios/chrome/browser/search_engines/model/search_engines_app_interface.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
@@ -1485,12 +1486,6 @@
 // Tests that content suggestions are hidden for supervised users on sign-in.
 // When the supervised user signs out the active policy should apply to the NTP.
 - (void)testFeedHiddenForSupervisedUser {
-  // TODO(crbug.com/40907845): Re-enable the test on iPad once the test is
-  // fixed.
-  if ([ChromeEarlGrey isIPadIdiom]) {
-    EARL_GREY_TEST_DISABLED(@"Disabled for iPad as the test fails.");
-  }
-
   // Disable trending queries experiment to ensure that the Discover feed is
   // visible when first opening the NTP.
   // TODO(crbug.com/40856730): Adapt the test with launch of trending queries.
@@ -1498,8 +1493,9 @@
   config.relaunch_policy = ForceRelaunchByCleanShutdown;
   config.additional_args.push_back(std::string("--") +
                                    switches::kDisableSearchEngineChoiceScreen);
-  // TODO(crbug.com/40251409): Reenable the discover feed sync promo feature
-  config.features_disabled.push_back(kEnableDiscoverFeedTopSyncPromo);
+  config.features_enabled.push_back(
+      supervised_user::
+          kReplaceSupervisionSystemCapabilitiesWithAccountCapabilitiesOnIOS);
   [[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config];
 
   [self
@@ -1521,7 +1517,65 @@
 
   [SigninEarlGrey signinWithFakeIdentity:identity];
 
-  // Check feed label and if NTP is scrollable.
+  // Check that the feed label is not visible and if NTP is scrollable.
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::DiscoverHeaderLabel()]
+      assertWithMatcher:grey_not(grey_sufficientlyVisible())];
+  [self checkIfNTPIsScrollable];
+
+  // Check that the fake omnibox is visible.
+  [ChromeEarlGrey waitForSufficientlyVisibleElementWithMatcher:
+                      chrome_test_util::FakeOmnibox()];
+
+  // Opens settings menu and ensures that Discover setting is not present.
+  [self checkDiscoverSettingsToggleVisible:NO];
+
+  [SigninEarlGreyUI signOut];
+
+  // The feed label should be visible on sign-out.
+  [self checkFeedLabelForFeedVisible:YES];
+  [self checkIfNTPIsScrollable];
+
+  // Opens settings menu and ensures that Discover setting is present.
+  [self checkDiscoverSettingsToggleVisible:YES];
+}
+
+// Tests that content suggestions are hidden for supervised users on sign-in,
+// with supervision status based on system capabilities.
+// TODO(crbug.com/346756363): Remove this test when supervision status system
+// capabilities are deprecated.
+- (void)testFeedHiddenForSupervisedUserViaSystemCapabilities {
+  // Disable trending queries experiment to ensure that the Discover feed is
+  // visible when first opening the NTP.
+  // TODO(crbug.com/40856730): Adapt the test with launch of trending queries.
+  AppLaunchConfiguration config = [self appConfigurationForTestCase];
+  config.relaunch_policy = ForceRelaunchByCleanShutdown;
+  config.additional_args.push_back(std::string("--") +
+                                   switches::kDisableSearchEngineChoiceScreen);
+  config.features_disabled.push_back(
+      supervised_user::
+          kReplaceSupervisionSystemCapabilitiesWithAccountCapabilitiesOnIOS);
+  [[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config];
+
+  [self
+      testNTPInitialPositionAndContent:[NewTabPageAppInterface collectionView]];
+
+  // Ensure that label is visible with correct text for enabled feed, and that
+  // the NTP is scrollable.
+  [self checkFeedLabelForFeedVisible:YES];
+  [self checkIfNTPIsScrollable];
+
+  // Opens settings menu and ensures that Discover setting is present.
+  [self checkDiscoverSettingsToggleVisible:YES];
+
+  // The identity must exist in the test storage to be able to set capabilities
+  // through the fake identity service.
+  FakeSystemIdentity* identity = [FakeSystemIdentity fakeIdentity1];
+  [SigninEarlGrey addFakeIdentity:identity];
+  [SigninEarlGrey setIsSubjectToParentalControls:YES forIdentity:identity];
+
+  [SigninEarlGrey signinWithFakeIdentity:identity];
+
+  // Check that the feed label is not visible and if NTP is scrollable.
   [[EarlGrey selectElementWithMatcher:chrome_test_util::DiscoverHeaderLabel()]
       assertWithMatcher:grey_not(grey_sufficientlyVisible())];
   [self checkIfNTPIsScrollable];
diff --git a/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view.mm b/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view.mm
index 8386629..c13080a 100644
--- a/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view.mm
+++ b/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view.mm
@@ -3,8 +3,8 @@
 // found in the LICENSE file.
 
 #import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view.h"
-#import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view+Testing.h"
 
+#import "base/feature_list.h"
 #import "base/notreached.h"
 #import "base/task/sequenced_task_runner.h"
 #import "base/time/time.h"
@@ -18,6 +18,7 @@
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller_audience.h"
 #import "ios/chrome/browser/ui/content_suggestions/set_up_list/constants.h"
 #import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_icon.h"
+#import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view+Testing.h"
 #import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view_data.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
@@ -348,7 +349,10 @@
       return l10n_util::GetNSString(
           IDS_IOS_CONSISTENCY_PROMO_DEFAULT_ACCOUNT_TITLE);
     case SetUpListItemType::kDefaultBrowser:
-      return l10n_util::GetNSString(IDS_IOS_SET_UP_LIST_DEFAULT_BROWSER_TITLE);
+      return l10n_util::GetNSString(
+          UseIPadTailoredStringForDefaultBrowserPromo()
+              ? IDS_IOS_SET_UP_LIST_DEFAULT_BROWSER_TITLE_IPAD
+              : IDS_IOS_SET_UP_LIST_DEFAULT_BROWSER_TITLE);
     case SetUpListItemType::kAutofill:
       return l10n_util::GetNSString(IDS_IOS_SET_UP_LIST_AUTOFILL_TITLE);
     case SetUpListItemType::kNotifications:
diff --git a/ios/chrome/browser/ui/default_promo/DEPS b/ios/chrome/browser/ui/default_promo/DEPS
deleted file mode 100644
index 974321e..0000000
--- a/ios/chrome/browser/ui/default_promo/DEPS
+++ /dev/null
@@ -1,4 +0,0 @@
-include_rules = [
-  "+ios/chrome/browser/ui/infobars",
-  "+ios/chrome/browser/ui/promos_manager",
-]
diff --git a/ios/chrome/browser/ui/default_promo/all_tabs_default_browser_promo_view_provider.h b/ios/chrome/browser/ui/default_promo/all_tabs_default_browser_promo_view_provider.h
deleted file mode 100644
index b8d2995..0000000
--- a/ios/chrome/browser/ui/default_promo/all_tabs_default_browser_promo_view_provider.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2024 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_ALL_TABS_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_ALL_TABS_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
-
-#import "ios/chrome/browser/ui/default_promo/base_default_browser_promo_view_provider.h"
-
-// Provider for displaying the All Tabs Default Browser Promo.
-@interface AllTabsDefaultBrowserPromoViewProvider
-    : BaseDefaultBrowserPromoViewProvider
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_ALL_TABS_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
diff --git a/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_commands.h b/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_commands.h
deleted file mode 100644
index 085272b1..0000000
--- a/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_commands.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_COMMANDS_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_COMMANDS_H_
-
-@protocol DefaultBrowserGenericPromoCommands <NSObject>
-
-// Command the promo to be hidden.
-- (void)hidePromo;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_COMMANDS_H_
diff --git a/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_mediator.h b/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_mediator.h
deleted file mode 100644
index 0bf07cf..0000000
--- a/ios/chrome/browser/ui/default_promo/generic/default_browser_generic_promo_mediator.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_MEDIATOR_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_MEDIATOR_H_
-
-#import <UIKit/UIKit.h>
-
-// The mediator for the generic default browser promo.
-@interface DefaultBrowserGenericPromoMediator : NSObject
-
-// Handles user tap on primary action.
-- (void)didTapPrimaryActionButton;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_GENERIC_DEFAULT_BROWSER_GENERIC_PROMO_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/default_promo/made_for_ios_default_browser_promo_view_provider.h b/ios/chrome/browser/ui/default_promo/made_for_ios_default_browser_promo_view_provider.h
deleted file mode 100644
index a3185b1a..0000000
--- a/ios/chrome/browser/ui/default_promo/made_for_ios_default_browser_promo_view_provider.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2024 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_MADE_FOR_IOS_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_MADE_FOR_IOS_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
-
-#import "ios/chrome/browser/ui/default_promo/base_default_browser_promo_view_provider.h"
-
-// Provider for displaying the Made For iOS Default Browser Promo.
-@interface MadeForIOSDefaultBrowserPromoViewProvider
-    : BaseDefaultBrowserPromoViewProvider
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_MADE_FOR_IOS_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
diff --git a/ios/chrome/browser/ui/default_promo/post_default_abandonment/post_default_abandonment_promo_provider.h b/ios/chrome/browser/ui/default_promo/post_default_abandonment/post_default_abandonment_promo_provider.h
deleted file mode 100644
index b6f7e378..0000000
--- a/ios/chrome/browser/ui/default_promo/post_default_abandonment/post_default_abandonment_promo_provider.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2024 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_POST_DEFAULT_ABANDONMENT_POST_DEFAULT_ABANDONMENT_PROMO_PROVIDER_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_POST_DEFAULT_ABANDONMENT_POST_DEFAULT_ABANDONMENT_PROMO_PROVIDER_H_
-
-#import "ios/chrome/browser/shared/public/commands/promos_manager_commands.h"
-#import "ios/chrome/browser/ui/promos_manager/standard_promo_alert_provider.h"
-
-// Provider for displaying the post-default browser abandonment alert.
-@interface PostDefaultBrowserAbandonmentPromoProvider
-    : NSObject <StandardPromoAlertProvider>
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_POST_DEFAULT_ABANDONMENT_POST_DEFAULT_ABANDONMENT_PROMO_PROVIDER_H_
diff --git a/ios/chrome/browser/ui/default_promo/stay_safe_default_browser_promo_view_provider.h b/ios/chrome/browser/ui/default_promo/stay_safe_default_browser_promo_view_provider.h
deleted file mode 100644
index c61106b0..0000000
--- a/ios/chrome/browser/ui/default_promo/stay_safe_default_browser_promo_view_provider.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2024 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_STAY_SAFE_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
-#define IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_STAY_SAFE_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
-
-#import "ios/chrome/browser/ui/default_promo/base_default_browser_promo_view_provider.h"
-
-// Provider for displaying the Stay Safe Default Browser Promo.
-@interface StaySafeDefaultBrowserPromoViewProvider
-    : BaseDefaultBrowserPromoViewProvider
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_DEFAULT_PROMO_STAY_SAFE_DEFAULT_BROWSER_PROMO_VIEW_PROVIDER_H_
diff --git a/ios/chrome/browser/ui/first_run/default_browser/default_browser_screen_view_controller.mm b/ios/chrome/browser/ui/first_run/default_browser/default_browser_screen_view_controller.mm
index 3f5c069..49a955c8 100644
--- a/ios/chrome/browser/ui/first_run/default_browser/default_browser_screen_view_controller.mm
+++ b/ios/chrome/browser/ui/first_run/default_browser/default_browser_screen_view_controller.mm
@@ -13,18 +13,8 @@
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/grit/ios_branded_strings.h"
 #import "ios/chrome/grit/ios_strings.h"
-#import "ui/base/device_form_factor.h"
 #import "ui/base/l10n/l10n_util.h"
 
-namespace {
-// Returns `YES` if the title and subtitle should be tailored for iPad.
-BOOL UseIPadTailoredString() {
-  return ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET &&
-         base::FeatureList::IsEnabled(
-             kDefaultBrowserPromoIPadExperimentalString);
-}
-}  // namespace
-
 @implementation DefaultBrowserScreenViewController
 
 #pragma mark - UIViewController
@@ -39,11 +29,11 @@
   self.bannerName = kChromiumDefaultBrowserScreenBannerImage;
 #endif
   self.titleText = l10n_util::GetNSString(
-      UseIPadTailoredString()
+      UseIPadTailoredStringForDefaultBrowserPromo()
           ? IDS_IOS_FIRST_RUN_DEFAULT_BROWSER_SCREEN_TITLE_IPAD
           : IDS_IOS_FIRST_RUN_DEFAULT_BROWSER_SCREEN_TITLE);
   self.subtitleText = l10n_util::GetNSString(
-      UseIPadTailoredString()
+      UseIPadTailoredStringForDefaultBrowserPromo()
           ? IDS_IOS_FIRST_RUN_DEFAULT_BROWSER_SCREEN_SUBTITLE_IPAD
           : IDS_IOS_FIRST_RUN_DEFAULT_BROWSER_SCREEN_SUBTITLE);
 
diff --git a/ios/chrome/browser/ui/incognito_reauth/BUILD.gn b/ios/chrome/browser/ui/incognito_reauth/BUILD.gn
index 86feccc..6c7c971 100644
--- a/ios/chrome/browser/ui/incognito_reauth/BUILD.gn
+++ b/ios/chrome/browser/ui/incognito_reauth/BUILD.gn
@@ -78,6 +78,7 @@
     "//base",
     "//base/test:test_support",
     "//components/prefs:test_support",
+    "//ios/chrome/browser/browser_view/ui_bundled",
     "//ios/chrome/browser/shared/coordinator/scene/test",
     "//ios/chrome/browser/shared/model/browser",
     "//ios/chrome/browser/shared/model/browser/test:test_support",
@@ -86,7 +87,6 @@
     "//ios/chrome/browser/shared/model/web_state_list",
     "//ios/chrome/browser/shared/model/web_state_list:web_state_list",
     "//ios/chrome/browser/shared/public/features",
-    "//ios/chrome/browser/ui/browser_view",
     "//ios/chrome/common/ui/reauthentication",
     "//ios/chrome/test:block_cleanup_test",
     "//ios/web/public/test",
diff --git a/ios/chrome/browser/ui/location_bar/BUILD.gn b/ios/chrome/browser/ui/location_bar/BUILD.gn
index bd6c8c3ab..467f26e 100644
--- a/ios/chrome/browser/ui/location_bar/BUILD.gn
+++ b/ios/chrome/browser/ui/location_bar/BUILD.gn
@@ -38,6 +38,7 @@
     "//ios/chrome/browser/browser_state_metrics/model:model",
     "//ios/chrome/browser/contextual_panel/entrypoint/coordinator",
     "//ios/chrome/browser/default_browser/model:default_browser_interest_signals",
+    "//ios/chrome/browser/default_promo/ui_bundled:coordinator",
     "//ios/chrome/browser/drag_and_drop/model",
     "//ios/chrome/browser/feature_engagement/model",
     "//ios/chrome/browser/geolocation/model",
@@ -56,6 +57,7 @@
     "//ios/chrome/browser/shared/model/application_context",
     "//ios/chrome/browser/shared/model/browser_state",
     "//ios/chrome/browser/shared/model/prefs:pref_names",
+    "//ios/chrome/browser/shared/model/url",
     "//ios/chrome/browser/shared/model/web_state_list",
     "//ios/chrome/browser/shared/public/commands",
     "//ios/chrome/browser/shared/public/features",
@@ -65,7 +67,6 @@
     "//ios/chrome/browser/shared/ui/util:util_swift",
     "//ios/chrome/browser/ssl/model",
     "//ios/chrome/browser/ui/content_suggestions:content_suggestions_ui_util",
-    "//ios/chrome/browser/ui/default_promo",
     "//ios/chrome/browser/ui/fullscreen",
     "//ios/chrome/browser/ui/fullscreen:ui",
     "//ios/chrome/browser/ui/lens:lens_entrypoint",
diff --git a/ios/chrome/browser/ui/location_bar/DEPS b/ios/chrome/browser/ui/location_bar/DEPS
index 995c22d..68851896 100644
--- a/ios/chrome/browser/ui/location_bar/DEPS
+++ b/ios/chrome/browser/ui/location_bar/DEPS
@@ -1,10 +1,10 @@
 include_rules = [
-  "+ios/chrome/browser/ui/omnibox",
   "+ios/chrome/browser/badges/ui_bundled",
+  "+ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_scheduler.h",
+  "+ios/chrome/browser/ui/omnibox",
   "+ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h",
   "+ios/chrome/browser/ui/fullscreen",
   "+ios/chrome/browser/ui/lens/lens_entrypoint.h",
-  "+ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_scheduler.h",
   "+ios/chrome/browser/ui/orchestrator",
   "+ios/chrome/browser/ui/ntp/new_tab_page_util.h",
   "+ios/chrome/browser/ui/toolbar/public/toolbar_type.h",
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_steady_view_mediator.mm b/ios/chrome/browser/ui/location_bar/location_bar_steady_view_mediator.mm
index a01241ad..5ae3ddad 100644
--- a/ios/chrome/browser/ui/location_bar/location_bar_steady_view_mediator.mm
+++ b/ios/chrome/browser/ui/location_bar/location_bar_steady_view_mediator.mm
@@ -11,6 +11,7 @@
 #import "ios/chrome/browser/overlays/model/public/overlay_presenter_observer_bridge.h"
 #import "ios/chrome/browser/overlays/model/public/overlay_request.h"
 #import "ios/chrome/browser/overlays/model/public/web_content_area/http_auth_overlay.h"
+#import "ios/chrome/browser/shared/model/url/url_util.h"
 #import "ios/chrome/browser/shared/model/web_state_list/active_web_state_observation_forwarder.h"
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list_observer_bridge.h"
 #import "ios/chrome/browser/ui/location_bar/location_bar_steady_view_consumer.h"
@@ -289,7 +290,15 @@
   }
 
   const GURL& URL = self.currentWebState->GetLastCommittedURL();
-  return URL.is_valid() && !web::GetWebClient()->IsAppSpecificURL(URL);
+
+  // Enable sharing when the current page url is valid and the url is not app
+  // specific (the url's scheme is `chrome`) except when:
+  // 1. The page url represents a chrome's download path `chrome://downloads`.
+  // 2. The page url is a reference to an external file
+  // `chrome://external-file`.
+  return URL.is_valid() &&
+         (UrlIsDownloadedFile(URL) || UrlIsExternalFileReference(URL) ||
+          !web::GetWebClient()->IsAppSpecificURL(URL));
 }
 
 @end
diff --git a/ios/chrome/browser/ui/main/BUILD.gn b/ios/chrome/browser/ui/main/BUILD.gn
index 6bdd121..7252ceab 100644
--- a/ios/chrome/browser/ui/main/BUILD.gn
+++ b/ios/chrome/browser/ui/main/BUILD.gn
@@ -13,12 +13,12 @@
     "//components/feature_engagement/public",
     "//ios/chrome/app/application_delegate:app_state_header",
     "//ios/chrome/browser/default_browser/model:utils",
+    "//ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment:features",
     "//ios/chrome/browser/feature_engagement/model",
     "//ios/chrome/browser/promos_manager/model",
     "//ios/chrome/browser/promos_manager/model:constants",
     "//ios/chrome/browser/shared/coordinator/scene:observing_scene_agent",
     "//ios/chrome/browser/signin/model",
-    "//ios/chrome/browser/ui/default_promo/post_default_abandonment:features",
   ]
   frameworks = [ "UIKit.framework" ]
 }
@@ -72,6 +72,7 @@
     "//ios/chrome/app/resources:launchscreen_xib",
     "//ios/chrome/browser/app_launcher/model",
     "//ios/chrome/browser/autofill/model:model_internal",
+    "//ios/chrome/browser/browser_view/ui_bundled",
     "//ios/chrome/browser/browsing_data/model",
     "//ios/chrome/browser/crash_report/model:model_internal",
     "//ios/chrome/browser/device_sharing/model",
@@ -98,7 +99,6 @@
     "//ios/chrome/browser/tabs/model/inactive_tabs:features",
     "//ios/chrome/browser/ui/autofill",
     "//ios/chrome/browser/ui/browser_container",
-    "//ios/chrome/browser/ui/browser_view",
     "//ios/chrome/browser/ui/incognito_reauth:incognito_reauth_scene_agent",
     "//ios/chrome/browser/ui/page_info:coordinator",
     "//ios/chrome/browser/ui/print",
@@ -148,8 +148,10 @@
     "//ios/chrome/app/application_delegate:test_support",
     "//ios/chrome/app/startup",
     "//ios/chrome/browser/bookmarks/model",
+    "//ios/chrome/browser/browser_view/ui_bundled",
     "//ios/chrome/browser/default_browser/model:test_support",
     "//ios/chrome/browser/default_browser/model:utils",
+    "//ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment:features",
     "//ios/chrome/browser/favicon/model",
     "//ios/chrome/browser/feature_engagement/model",
     "//ios/chrome/browser/history/model",
@@ -182,8 +184,6 @@
     "//ios/chrome/browser/sync/model",
     "//ios/chrome/browser/tabs/model",
     "//ios/chrome/browser/tabs/model/inactive_tabs:features",
-    "//ios/chrome/browser/ui/browser_view",
-    "//ios/chrome/browser/ui/default_promo/post_default_abandonment:features",
     "//ios/chrome/test:block_cleanup_test",
     "//ios/chrome/test:test_support",
     "//ios/testing:block_swizzler",
diff --git a/ios/chrome/browser/ui/main/browser_view_wrangler.mm b/ios/chrome/browser/ui/main/browser_view_wrangler.mm
index bf81166..33e0f29 100644
--- a/ios/chrome/browser/ui/main/browser_view_wrangler.mm
+++ b/ios/chrome/browser/ui/main/browser_view_wrangler.mm
@@ -10,6 +10,8 @@
 #import "base/memory/raw_ptr.h"
 #import "base/strings/sys_string_conversions.h"
 #import "ios/chrome/app/application_delegate/app_state.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.h"
 #import "ios/chrome/browser/crash_report/model/crash_report_helper.h"
 #import "ios/chrome/browser/device_sharing/model/device_sharing_browser_agent.h"
 #import "ios/chrome/browser/metrics/model/tab_usage_recorder_browser_agent.h"
@@ -32,8 +34,6 @@
 #import "ios/chrome/browser/snapshots/model/snapshot_browser_agent.h"
 #import "ios/chrome/browser/tabs/model/inactive_tabs/features.h"
 #import "ios/chrome/browser/tabs/model/inactive_tabs/utils.h"
-#import "ios/chrome/browser/ui/browser_view/browser_coordinator.h"
-#import "ios/chrome/browser/ui/browser_view/browser_view_controller.h"
 #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h"
 #import "ios/chrome/browser/ui/main/wrangled_browser.h"
 
diff --git a/ios/chrome/browser/ui/main/browser_view_wrangler_unittest.mm b/ios/chrome/browser/ui/main/browser_view_wrangler_unittest.mm
index a43a546..35277aa3 100644
--- a/ios/chrome/browser/ui/main/browser_view_wrangler_unittest.mm
+++ b/ios/chrome/browser/ui/main/browser_view_wrangler_unittest.mm
@@ -12,6 +12,7 @@
 #import "components/bookmarks/test/bookmark_test_helpers.h"
 #import "ios/chrome/browser/bookmarks/model/bookmark_model_factory.h"
 #import "ios/chrome/browser/bookmarks/model/local_or_syncable_bookmark_model_factory.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.h"
 #import "ios/chrome/browser/favicon/model/favicon_service_factory.h"
 #import "ios/chrome/browser/favicon/model/ios_chrome_favicon_loader_factory.h"
 #import "ios/chrome/browser/favicon/model/ios_chrome_large_icon_service_factory.h"
@@ -34,7 +35,6 @@
 #import "ios/chrome/browser/signin/model/fake_authentication_service_delegate.h"
 #import "ios/chrome/browser/sync/model/send_tab_to_self_sync_service_factory.h"
 #import "ios/chrome/browser/tabs/model/inactive_tabs/features.h"
-#import "ios/chrome/browser/ui/browser_view/browser_view_controller.h"
 #import "ios/chrome/browser/ui/main/wrangled_browser.h"
 #import "ios/chrome/test/ios_chrome_scoped_testing_local_state.h"
 #import "ios/web/public/test/web_task_environment.h"
diff --git a/ios/chrome/browser/ui/main/default_browser_promo_scene_agent.mm b/ios/chrome/browser/ui/main/default_browser_promo_scene_agent.mm
index 28da3d0..c764b0d9 100644
--- a/ios/chrome/browser/ui/main/default_browser_promo_scene_agent.mm
+++ b/ios/chrome/browser/ui/main/default_browser_promo_scene_agent.mm
@@ -9,6 +9,7 @@
 #import "ios/chrome/app/application_delegate/app_state.h"
 #import "ios/chrome/app/application_delegate/app_state_observer.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/features.h"
 #import "ios/chrome/browser/feature_engagement/model/tracker_factory.h"
 #import "ios/chrome/browser/promos_manager/model/constants.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
@@ -16,7 +17,6 @@
 #import "ios/chrome/browser/shared/model/browser/browser_provider_interface.h"
 #import "ios/chrome/browser/signin/model/authentication_service.h"
 #import "ios/chrome/browser/signin/model/authentication_service_factory.h"
-#import "ios/chrome/browser/ui/default_promo/post_default_abandonment/features.h"
 
 @interface DefaultBrowserPromoSceneAgent ()
 
diff --git a/ios/chrome/browser/ui/main/default_browser_promo_scene_agent_unittest.mm b/ios/chrome/browser/ui/main/default_browser_promo_scene_agent_unittest.mm
index e590f30..5d00456 100644
--- a/ios/chrome/browser/ui/main/default_browser_promo_scene_agent_unittest.mm
+++ b/ios/chrome/browser/ui/main/default_browser_promo_scene_agent_unittest.mm
@@ -16,6 +16,7 @@
 #import "ios/chrome/app/application_delegate/fake_startup_information.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
 #import "ios/chrome/browser/default_browser/model/utils_test_support.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/features.h"
 #import "ios/chrome/browser/feature_engagement/model/tracker_factory.h"
 #import "ios/chrome/browser/promos_manager/model/constants.h"
 #import "ios/chrome/browser/promos_manager/model/features.h"
@@ -33,7 +34,6 @@
 #import "ios/chrome/browser/signin/model/fake_authentication_service_delegate.h"
 #import "ios/chrome/browser/signin/model/fake_system_identity.h"
 #import "ios/chrome/browser/signin/model/fake_system_identity_manager.h"
-#import "ios/chrome/browser/ui/default_promo/post_default_abandonment/features.h"
 #import "ios/chrome/test/testing_application_context.h"
 #import "ios/web/public/test/web_task_environment.h"
 #import "testing/gmock/include/gmock/gmock.h"
@@ -66,7 +66,7 @@
     TestChromeBrowserState::Builder builder;
     builder.AddTestingFactory(
         AuthenticationServiceFactory::GetInstance(),
-        base::BindRepeating(AuthenticationServiceFactory::GetDefaultFactory()));
+        AuthenticationServiceFactory::GetDefaultFactory());
     builder.AddTestingFactory(
         feature_engagement::TrackerFactory::GetInstance(),
         base::BindRepeating(&BuildFeatureEngagementMockTracker));
diff --git a/ios/chrome/browser/ui/main/wrangled_browser.mm b/ios/chrome/browser/ui/main/wrangled_browser.mm
index ffaea667..107b1bf 100644
--- a/ios/chrome/browser/ui/main/wrangled_browser.mm
+++ b/ios/chrome/browser/ui/main/wrangled_browser.mm
@@ -5,10 +5,10 @@
 #import "ios/chrome/browser/ui/main/wrangled_browser.h"
 
 #import "base/check.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
-#import "ios/chrome/browser/ui/browser_view/browser_coordinator.h"
-#import "ios/chrome/browser/ui/browser_view/browser_view_controller.h"
 
 @interface WrangledBrowser ()
 @property(nonatomic, weak, readonly) BrowserCoordinator* coordinator;
diff --git a/ios/chrome/browser/ui/menu/action_factory_unittest.mm b/ios/chrome/browser/ui/menu/action_factory_unittest.mm
index 5c0e55c..69a7bd3 100644
--- a/ios/chrome/browser/ui/menu/action_factory_unittest.mm
+++ b/ios/chrome/browser/ui/menu/action_factory_unittest.mm
@@ -8,6 +8,7 @@
 #import "base/test/metrics/histogram_tester.h"
 #import "base/test/scoped_feature_list.h"
 #import "base/test/task_environment.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "components/tab_groups/tab_group_visual_data.h"
 #import "ios/chrome/browser/net/model/crurl.h"
 #import "ios/chrome/browser/shared/model/web_state_list/tab_group.h"
@@ -27,6 +28,8 @@
 #import "ui/base/test/ios/ui_image_test_utils.h"
 #import "url/gurl.h"
 
+using tab_groups::TabGroupId;
+
 namespace {
 const MenuScenarioHistogram kTestMenuScenario =
     kMenuScenarioHistogramHistoryEntry;
@@ -443,10 +446,12 @@
   ActionFactory* factory =
       [[ActionFactory alloc] initWithScenario:kTestMenuScenario];
 
-  TabGroup group1(tab_groups::TabGroupVisualData(
-      u"First", tab_groups::TabGroupColorId::kGrey));
-  TabGroup group2(tab_groups::TabGroupVisualData(
-      u"Second", tab_groups::TabGroupColorId::kGrey));
+  TabGroup group1(TabGroupId::GenerateNew(),
+                  tab_groups::TabGroupVisualData(
+                      u"First", tab_groups::TabGroupColorId::kGrey));
+  TabGroup group2(TabGroupId::GenerateNew(),
+                  tab_groups::TabGroupVisualData(
+                      u"Second", tab_groups::TabGroupColorId::kGrey));
   std::set<const TabGroup*> groups{&group1, &group2};
 
   UIMenuElement* menu_element =
@@ -519,10 +524,12 @@
   ActionFactory* factory =
       [[ActionFactory alloc] initWithScenario:kTestMenuScenario];
 
-  TabGroup group1(tab_groups::TabGroupVisualData(
-      u"First", tab_groups::TabGroupColorId::kGrey));
-  TabGroup group2(tab_groups::TabGroupVisualData(
-      u"Second", tab_groups::TabGroupColorId::kGrey));
+  TabGroup group1(TabGroupId::GenerateNew(),
+                  tab_groups::TabGroupVisualData(
+                      u"First", tab_groups::TabGroupColorId::kGrey));
+  TabGroup group2(TabGroupId::GenerateNew(),
+                  tab_groups::TabGroupVisualData(
+                      u"Second", tab_groups::TabGroupColorId::kGrey));
   std::set<const TabGroup*> groups{&group1, &group2};
 
   UIMenuElement* menu_element =
diff --git a/ios/chrome/browser/ui/ntp/BUILD.gn b/ios/chrome/browser/ui/ntp/BUILD.gn
index 947606d8..3d6eb05 100644
--- a/ios/chrome/browser/ui/ntp/BUILD.gn
+++ b/ios/chrome/browser/ui/ntp/BUILD.gn
@@ -98,6 +98,7 @@
     "//components/search",
     "//components/signin/public/base",
     "//components/signin/public/identity_manager/objc",
+    "//components/supervised_user/core/common:features",
     "//ios/chrome/app/application_delegate:app_state_header",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/context_menu/ui_bundled/link_preview",
@@ -126,6 +127,7 @@
     "//ios/chrome/browser/signin/model",
     "//ios/chrome/browser/signin/model:capabilities_types",
     "//ios/chrome/browser/signin/model:system_identity_manager",
+    "//ios/chrome/browser/supervised_user/model:capabilities",
     "//ios/chrome/browser/sync/model",
     "//ios/chrome/browser/ui/authentication/account_switching",
     "//ios/chrome/browser/ui/authentication/enterprise:enterprise_utils",
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
index 52ada2b..959449f0a 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -6,6 +6,7 @@
 
 #import <MaterialComponents/MaterialSnackbar.h>
 
+#import "base/feature_list.h"
 #import "base/metrics/field_trial_params.h"
 #import "base/metrics/histogram_functions.h"
 #import "base/metrics/histogram_macros.h"
@@ -21,6 +22,8 @@
 #import "components/search/search.h"
 #import "components/signin/public/base/signin_metrics.h"
 #import "components/signin/public/identity_manager/objc/identity_manager_observer_bridge.h"
+#import "components/signin/public/identity_manager/tribool.h"
+#import "components/supervised_user/core/common/features.h"
 #import "components/sync/service/sync_service.h"
 #import "ios/chrome/app/application_delegate/app_state.h"
 #import "ios/chrome/browser/context_menu/ui_bundled/link_preview/link_preview_coordinator.h"
@@ -62,6 +65,7 @@
 #import "ios/chrome/browser/signin/model/chrome_account_manager_service_factory.h"
 #import "ios/chrome/browser/signin/model/identity_manager_factory.h"
 #import "ios/chrome/browser/signin/model/system_identity_manager.h"
+#import "ios/chrome/browser/supervised_user/model/supervised_user_capabilities_observer_bridge.h"
 #import "ios/chrome/browser/sync/model/sync_service_factory.h"
 #import "ios/chrome/browser/ui/authentication/account_switching/account_switcher_coordinator.h"
 #import "ios/chrome/browser/ui/authentication/enterprise/enterprise_utils.h"
@@ -131,7 +135,8 @@
                                      NewTabPageHeaderCommands,
                                      NewTabPageMetricsDelegate,
                                      OverscrollActionsControllerDelegate,
-                                     SceneStateObserver> {
+                                     SceneStateObserver,
+                                     SupervisedUserCapabilitiesObserving> {
   // Observes changes in the IdentityManager.
   std::unique_ptr<signin::IdentityManagerObserverBridge>
       _identityObserverBridge;
@@ -142,6 +147,10 @@
   // Observer for auth service status changes.
   std::unique_ptr<AuthenticationServiceObserverBridge>
       _authServiceObserverBridge;
+
+  // Observer to track changes to supervision-related capabilities.
+  std::unique_ptr<supervised_user::SupervisedUserCapabilitiesObserverBridge>
+      _supervisedUserCapabilitiesObserverBridge;
 }
 
 // Coordinator for the ContentSuggestions.
@@ -316,8 +325,22 @@
     self.NTPViewController.focusAccessibilityOmniboxWhenViewAppears = NO;
   }
 
-  // Updates feed asynchronously if the account is subject to parental controls.
-  [self updateFeedVisibilityForSupervision];
+  // Update the feed if the account is subject to parental controls.
+  if (base::FeatureList::IsEnabled(
+          supervised_user::
+              kReplaceSupervisionSystemCapabilitiesWithAccountCapabilitiesOnIOS)) {
+    signin::IdentityManager* identityManager =
+        IdentityManagerFactory::GetForBrowserState(
+            self.browser->GetBrowserState());
+    signin::Tribool capability =
+        supervised_user::IsPrimaryAccountSubjectToParentalControls(
+            identityManager);
+    [self
+        updateFeedWithIsSupervisedUser:(capability == signin::Tribool::kTrue)];
+  } else {
+    // Update asynchronously using system capabilities.
+    [self updateFeedVisibilityForSupervision];
+  }
 
   [self configureNTPMediator];
   if (self.NTPMediator.feedHeaderVisible) {
@@ -397,6 +420,7 @@
   [self.feedMenuCoordinator stop];
   self.feedMenuCoordinator = nil;
 
+  _supervisedUserCapabilitiesObserverBridge.reset();
   _discoverFeedObserverBridge.reset();
   _identityObserverBridge.reset();
   _authServiceObserverBridge.reset();
@@ -575,6 +599,11 @@
       std::make_unique<signin::IdentityManagerObserverBridge>(identityManager,
                                                               self);
 
+  // Start observing supervised user capabilities.
+  _supervisedUserCapabilitiesObserverBridge = std::make_unique<
+      supervised_user::SupervisedUserCapabilitiesObserverBridge>(
+      identityManager, self);
+
   // Start observing DiscoverFeedService.
   _discoverFeedObserverBridge = std::make_unique<DiscoverFeedObserverBridge>(
       self, self.discoverFeedService);
@@ -1358,6 +1387,8 @@
 
 #pragma mark - IdentityManagerObserverBridgeDelegate
 
+// TODO(crbug.com/346756363): Remove this method as it is replaced with
+// `onIsSubjectToParentalControlsCapabilityChanged`.
 - (void)onPrimaryAccountChanged:
     (const signin::PrimaryAccountChangeEvent&)event {
   // An account change may trigger after the coordinator has been stopped.
@@ -1394,6 +1425,20 @@
   }
 }
 
+#pragma mark - SupervisedUserCapabilitiesObserving
+
+- (void)onIsSubjectToParentalControlsCapabilityChanged:
+    (supervised_user::CapabilityUpdateState)capabilityUpdateState {
+  if (base::FeatureList::IsEnabled(
+          supervised_user::
+              kReplaceSupervisionSystemCapabilitiesWithAccountCapabilitiesOnIOS)) {
+    BOOL isSubjectToParentalControl =
+        (capabilityUpdateState ==
+         supervised_user::CapabilityUpdateState::kSetToTrue);
+    [self updateFeedWithIsSupervisedUser:isSubjectToParentalControl];
+  }
+}
+
 #pragma mark - SceneStateObserver
 
 - (void)sceneState:(SceneState*)sceneState
@@ -1509,27 +1554,33 @@
 
 // Updates the visibility of the content suggestions on the NTP if the account
 // is subject to parental controls.
+// TODO(crbug.com/346756363): Remove this method as we deprecate getting
+// supervision status from SystemIdentityManager.
 - (void)updateFeedVisibilityForSupervision {
-  DCHECK(self.prefService);
-  DCHECK(self.authService);
+  if (!base::FeatureList::IsEnabled(
+          supervised_user::
+              kReplaceSupervisionSystemCapabilitiesWithAccountCapabilitiesOnIOS)) {
+    DCHECK(self.prefService);
+    DCHECK(self.authService);
 
-  id<SystemIdentity> identity =
-      self.authService->GetPrimaryIdentity(signin::ConsentLevel::kSignin);
-  if (!identity) {
-    [self updateFeedWithIsSupervisedUser:NO];
-    return;
+    id<SystemIdentity> identity =
+        self.authService->GetPrimaryIdentity(signin::ConsentLevel::kSignin);
+    if (!identity) {
+      [self updateFeedWithIsSupervisedUser:NO];
+      return;
+    }
+
+    using CapabilityResult = SystemIdentityCapabilityResult;
+
+    __weak NewTabPageCoordinator* weakSelf = self;
+    GetApplicationContext()
+        ->GetSystemIdentityManager()
+        ->IsSubjectToParentalControls(
+            identity, base::BindOnce(^(CapabilityResult result) {
+              const bool isSupervisedUser = result == CapabilityResult::kTrue;
+              [weakSelf updateFeedWithIsSupervisedUser:isSupervisedUser];
+            }));
   }
-
-  using CapabilityResult = SystemIdentityCapabilityResult;
-
-  __weak NewTabPageCoordinator* weakSelf = self;
-  GetApplicationContext()
-      ->GetSystemIdentityManager()
-      ->IsSubjectToParentalControls(
-          identity, base::BindOnce(^(CapabilityResult result) {
-            const bool isSupervisedUser = result == CapabilityResult::kTrue;
-            [weakSelf updateFeedWithIsSupervisedUser:isSupervisedUser];
-          }));
 }
 
 // Toggles feed visibility between hidden or expanded using the feed header
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm
index 8ab27982..bdbe9d1 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm
@@ -168,9 +168,8 @@
     test_cbs_builder.AddTestingFactory(
         segmentation_platform::SegmentationPlatformServiceFactory::
             GetInstance(),
-        base::BindRepeating(
-            segmentation_platform::SegmentationPlatformServiceFactory::
-                GetDefaultFactory()));
+        segmentation_platform::SegmentationPlatformServiceFactory::
+            GetDefaultFactory());
     browser_state_ = test_cbs_builder.Build();
     AuthenticationServiceFactory::CreateAndInitializeForBrowserState(
         browser_state_.get(),
diff --git a/ios/chrome/browser/ui/omnibox/BUILD.gn b/ios/chrome/browser/ui/omnibox/BUILD.gn
index 3016a04..c24c0fe 100644
--- a/ios/chrome/browser/ui/omnibox/BUILD.gn
+++ b/ios/chrome/browser/ui/omnibox/BUILD.gn
@@ -131,6 +131,7 @@
     "//ios/chrome/browser/bookmarks/model:model_utils",
     "//ios/chrome/browser/bubble/ui_bundled",
     "//ios/chrome/browser/default_browser/model:default_browser_interest_signals",
+    "//ios/chrome/browser/default_promo/ui_bundled:coordinator",
     "//ios/chrome/browser/favicon/model",
     "//ios/chrome/browser/feature_engagement/model",
     "//ios/chrome/browser/https_upgrades/model",
@@ -155,7 +156,6 @@
     "//ios/chrome/browser/shared/ui/util",
     "//ios/chrome/browser/shared/ui/util:omnibox_util",
     "//ios/chrome/browser/shared/ui/util:util_swift",
-    "//ios/chrome/browser/ui/default_promo",
     "//ios/chrome/browser/ui/fullscreen",
     "//ios/chrome/browser/ui/lens:lens_entrypoint",
     "//ios/chrome/browser/ui/location_bar:constants",
diff --git a/ios/chrome/browser/ui/omnibox/DEPS b/ios/chrome/browser/ui/omnibox/DEPS
index a070f0c2..aa151c8b 100644
--- a/ios/chrome/browser/ui/omnibox/DEPS
+++ b/ios/chrome/browser/ui/omnibox/DEPS
@@ -1,6 +1,6 @@
 include_rules = [
+  "+ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_scheduler.h",
   "+ios/chrome/browser/ui/location_bar",
-  "+ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_scheduler.h",
   "+ios/chrome/browser/ui/lens/lens_entrypoint.h",
   "+ios/chrome/browser/ui/orchestrator",
   "+ios/chrome/browser/ui/ntp/metrics/home_metrics.h",
diff --git a/ios/chrome/browser/ui/omnibox/popup/BUILD.gn b/ios/chrome/browser/ui/omnibox/popup/BUILD.gn
index 25f05cb0..af9be23 100644
--- a/ios/chrome/browser/ui/omnibox/popup/BUILD.gn
+++ b/ios/chrome/browser/ui/omnibox/popup/BUILD.gn
@@ -71,6 +71,7 @@
     "//ios/chrome/browser/autocomplete/model",
     "//ios/chrome/browser/default_browser/model",
     "//ios/chrome/browser/default_browser/model:default_browser_interest_signals",
+    "//ios/chrome/browser/default_promo/ui_bundled:coordinator",
     "//ios/chrome/browser/download/model",
     "//ios/chrome/browser/favicon/model",
     "//ios/chrome/browser/favicon/ui_bundled",
@@ -98,7 +99,6 @@
     "//ios/chrome/browser/shared/ui/symbols:symbols_views",
     "//ios/chrome/browser/shared/ui/util",
     "//ios/chrome/browser/shared/ui/util:util_swift",
-    "//ios/chrome/browser/ui/default_promo",
     "//ios/chrome/browser/ui/main:default_browser_scene_agent",
     "//ios/chrome/browser/ui/menu",
     "//ios/chrome/browser/ui/ntp/metrics:home_metrics",
diff --git a/ios/chrome/browser/ui/policy/idle/idle_timeout_confirmation_coordinator.mm b/ios/chrome/browser/ui/policy/idle/idle_timeout_confirmation_coordinator.mm
index 16e53f7d..979d3925 100644
--- a/ios/chrome/browser/ui/policy/idle/idle_timeout_confirmation_coordinator.mm
+++ b/ios/chrome/browser/ui/policy/idle/idle_timeout_confirmation_coordinator.mm
@@ -56,8 +56,8 @@
   CHECK(titleId)
       << "The idle timeout confirmation dialog title id should not be empty";
   int subtitleId = enterprise_idle::GetIdleTimeoutActionsSubtitleId(
-      actions, /*is_account_managed=*/authService->HasPrimaryIdentityManaged(
-          signin::ConsentLevel::kSignin));
+      actions,
+      /*is_data_cleared_on_signout=*/authService->ShouldClearDataOnSignOut());
 
   _presentedViewController = [[IdleTimeoutConfirmationViewController alloc]
       initWithIdleTimeoutTitleId:*titleId
diff --git a/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils.h b/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils.h
index e9d06b6..5177982 100644
--- a/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils.h
+++ b/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils.h
@@ -17,8 +17,10 @@
 std::optional<int> GetIdleTimeoutActionsTitleId(ActionSet actions);
 // Returns the string id that should be used for the subtitle of the
 // confirmation dialog. The subtitle has an additional sentence if data will be
-// cleared or if the user will be signed out from their managed account.
-int GetIdleTimeoutActionsSubtitleId(ActionSet actions, bool is_account_managed);
+// cleared or if the user will be signed out from their managed account in an
+// unmanaged browser.
+int GetIdleTimeoutActionsSubtitleId(ActionSet actions,
+                                    bool is_data_cleared_on_signout);
 // Returns the string id for the message that will be shown in the snackbar
 // after the idle timeout actions have run.
 std::optional<int> GetIdleTimeoutActionsSnackbarMessageId(ActionSet actions);
diff --git a/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils.mm b/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils.mm
index dd0e9e5..0344adf 100644
--- a/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils.mm
+++ b/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils.mm
@@ -39,12 +39,10 @@
 }
 
 int GetIdleTimeoutActionsSubtitleId(ActionSet actions,
-                                    bool is_account_managed) {
+                                    bool is_data_cleared_on_signout) {
   if (actions.clear) {
     return IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITH_CLEAR_DATA;
-  } else if (actions.signout && is_account_managed &&
-             base::FeatureList::IsEnabled(
-                 kClearDeviceDataOnSignOutForManagedUsers)) {
+  } else if (actions.signout && is_data_cleared_on_signout) {
     return IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITH_CLEAR_DATA_ON_SIGNOUT;
   } else {
     return IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITHOUT_CLEAR_DATA;
diff --git a/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils_unittest.mm b/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils_unittest.mm
index afeace9..5d5b0ff 100644
--- a/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils_unittest.mm
+++ b/ios/chrome/browser/ui/policy/idle/idle_timeout_policy_utils_unittest.mm
@@ -87,9 +87,9 @@
             IDS_IOS_IDLE_TIMEOUT_ALL_ACTIONS_TITLE);
   EXPECT_EQ(GetIdleTimeoutActionsSnackbarMessageId(action_set),
             IDS_IOS_IDLE_TIMEOUT_ALL_ACTIONS_SNACKBAR_MESSAGE);
-  EXPECT_EQ(
-      GetIdleTimeoutActionsSubtitleId(action_set, /*is_account_managed=*/false),
-      IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITH_CLEAR_DATA);
+  EXPECT_EQ(GetIdleTimeoutActionsSubtitleId(
+                action_set, /*is_data_cleared_on_signout=*/false),
+            IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITH_CLEAR_DATA);
 }
 
 TEST_F(IdleTimeoutPolicyUtilsTest, ActionsToActionSet_AllTypes_UserSignedOut) {
@@ -104,9 +104,9 @@
             IDS_IOS_IDLE_TIMEOUT_CLOSE_TABS_AND_CLEAR_DATA_TITLE);
   EXPECT_EQ(GetIdleTimeoutActionsSnackbarMessageId(action_set),
             IDS_IOS_IDLE_TIMEOUT_CLOSE_TABS_AND_CLEAR_DATA_SNACKBAR_MESSAGE);
-  EXPECT_EQ(
-      GetIdleTimeoutActionsSubtitleId(action_set, /*is_account_managed=*/false),
-      IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITH_CLEAR_DATA);
+  EXPECT_EQ(GetIdleTimeoutActionsSubtitleId(
+                action_set, /*is_data_cleared_on_signout=*/false),
+            IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITH_CLEAR_DATA);
 }
 
 TEST_F(IdleTimeoutPolicyUtilsTest, ActionsToActionSet_Signout_UserSignedIn) {
@@ -121,9 +121,9 @@
             IDS_IOS_IDLE_TIMEOUT_SIGNOUT_TITLE);
   EXPECT_EQ(GetIdleTimeoutActionsSnackbarMessageId(action_set),
             IDS_IOS_IDLE_TIMEOUT_SIGNOUT_SNACKBAR_MESSAGE);
-  EXPECT_EQ(
-      GetIdleTimeoutActionsSubtitleId(action_set, /*is_account_managed=*/false),
-      IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITHOUT_CLEAR_DATA);
+  EXPECT_EQ(GetIdleTimeoutActionsSubtitleId(
+                action_set, /*is_data_cleared_on_signout=*/false),
+            IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITHOUT_CLEAR_DATA);
 }
 
 TEST_F(IdleTimeoutPolicyUtilsTest, ActionsToActionSet_Signout_UserSignedOut) {
@@ -149,9 +149,9 @@
             IDS_IOS_IDLE_TIMEOUT_CLOSE_TABS_TITLE);
   EXPECT_EQ(GetIdleTimeoutActionsSnackbarMessageId(action_set),
             IDS_IOS_IDLE_TIMEOUT_CLOSE_TABS_SNACKBAR_MESSAGE);
-  EXPECT_EQ(
-      GetIdleTimeoutActionsSubtitleId(action_set, /*is_account_managed=*/false),
-      IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITHOUT_CLEAR_DATA);
+  EXPECT_EQ(GetIdleTimeoutActionsSubtitleId(
+                action_set, /*is_data_cleared_on_signout=*/false),
+            IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITHOUT_CLEAR_DATA);
 }
 
 TEST_F(IdleTimeoutPolicyUtilsTest, ActionsToActionSet_ClearBrowsingHistory) {
@@ -165,9 +165,9 @@
             IDS_IOS_IDLE_TIMEOUT_CLEAR_DATA_TITLE);
   EXPECT_EQ(GetIdleTimeoutActionsSnackbarMessageId(action_set),
             IDS_IOS_IDLE_TIMEOUT_CLEAR_DATA_SNACKBAR_MESSAGE);
-  EXPECT_EQ(
-      GetIdleTimeoutActionsSubtitleId(action_set, /*is_account_managed=*/false),
-      IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITH_CLEAR_DATA);
+  EXPECT_EQ(GetIdleTimeoutActionsSubtitleId(
+                action_set, /*is_data_cleared_on_signout=*/false),
+            IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITH_CLEAR_DATA);
 }
 
 TEST_F(IdleTimeoutPolicyUtilsTest,
@@ -220,9 +220,9 @@
   // `IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITH_CLEAR_DATA` should take precedence over
   // `IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITH_CLEAR_DATA_ON_SIGNOUT` even if the
   // `is_managed` flag is true.
-  EXPECT_EQ(
-      GetIdleTimeoutActionsSubtitleId(action_set, /*is_account_managed=*/true),
-      IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITH_CLEAR_DATA);
+  EXPECT_EQ(GetIdleTimeoutActionsSubtitleId(
+                action_set, /*is_data_cleared_on_signout=*/true),
+            IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITH_CLEAR_DATA);
 }
 
 TEST_F(IdleTimeoutPolicyUtilsTest, ActionsToActionSet_SignoutAndCloseTabs) {
@@ -237,17 +237,17 @@
             IDS_IOS_IDLE_TIMEOUT_CLOSE_TABS_AND_SIGNOUT_TITLE);
   EXPECT_EQ(GetIdleTimeoutActionsSnackbarMessageId(action_set),
             IDS_IOS_IDLE_TIMEOUT_CLOSE_TABS_AND_SIGNOUT_SNACKBAR_MESSAGE);
-  EXPECT_EQ(
-      GetIdleTimeoutActionsSubtitleId(action_set, /*is_account_managed=*/false),
-      IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITHOUT_CLEAR_DATA);
+  EXPECT_EQ(GetIdleTimeoutActionsSubtitleId(
+                action_set, /*is_data_cleared_on_signout=*/false),
+            IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITHOUT_CLEAR_DATA);
 }
 
 TEST_F(IdleTimeoutPolicyUtilsTest,
        ActionsToActionSet_SignoutAndCloseTabsWithManagedState) {
   // Sign in and verify that the signout action is set to true. Note that it
   // does not make a difference whether this is a sign-in to a managed or
-  // unmanaged account becasuse `is_account_managed` is hard coded to true in
-  // the `GetIdleTimeoutActionsSubtitleId` method under test below.
+  // unmanaged account becasuse `is_data_cleared_on_signout` is hard coded to
+  // true in the `GetIdleTimeoutActionsSubtitleId` method under test below.
   SignIn();
   SetIdleTimeoutActions({ActionType::kSignOut, ActionType::kCloseTabs});
   ActionSet action_set = GetActionSet(pref_service_, authentication_service_);
@@ -259,9 +259,9 @@
             IDS_IOS_IDLE_TIMEOUT_CLOSE_TABS_AND_SIGNOUT_TITLE);
   EXPECT_EQ(GetIdleTimeoutActionsSnackbarMessageId(action_set),
             IDS_IOS_IDLE_TIMEOUT_CLOSE_TABS_AND_SIGNOUT_SNACKBAR_MESSAGE);
-  EXPECT_EQ(
-      GetIdleTimeoutActionsSubtitleId(action_set, /*is_account_managed=*/true),
-      IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITH_CLEAR_DATA_ON_SIGNOUT);
+  EXPECT_EQ(GetIdleTimeoutActionsSubtitleId(
+                action_set, /*is_data_cleared_on_signout=*/true),
+            IDS_IOS_IDLE_TIMEOUT_SUBTITLE_WITH_CLEAR_DATA_ON_SIGNOUT);
 }
 
 }  // namespace enterprise_idle
diff --git a/ios/chrome/browser/ui/promos_manager/BUILD.gn b/ios/chrome/browser/ui/promos_manager/BUILD.gn
index 7927413..5ed0fa9 100644
--- a/ios/chrome/browser/ui/promos_manager/BUILD.gn
+++ b/ios/chrome/browser/ui/promos_manager/BUILD.gn
@@ -72,6 +72,7 @@
     "//base",
     "//components/feature_engagement/public",
     "//ios/chrome/app:tests_hook",
+    "//ios/chrome/browser/default_promo/ui_bundled:coordinator",
     "//ios/chrome/browser/feature_engagement/model",
     "//ios/chrome/browser/promos_manager/model",
     "//ios/chrome/browser/promos_manager/model:factory",
@@ -79,7 +80,6 @@
     "//ios/chrome/browser/promos_manager/model:types",
     "//ios/chrome/browser/shared/coordinator/chrome_coordinator",
     "//ios/chrome/browser/sync/model",
-    "//ios/chrome/browser/ui/default_promo",
     "//ios/public/provider/chrome/browser/signin:choice_api",
   ]
   deps = [
@@ -90,6 +90,10 @@
     "//ios/chrome/browser/app_store_rating/ui_bundled:features",
     "//ios/chrome/browser/credential_provider_promo/ui_bundled:coordinator",
     "//ios/chrome/browser/default_browser/model:utils",
+    "//ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment",
+    "//ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment:features",
+    "//ios/chrome/browser/default_promo/ui_bundled/post_restore:post_restore_default_browser",
+    "//ios/chrome/browser/default_promo/ui_bundled/promo_handler",
     "//ios/chrome/browser/docking_promo/ui",
     "//ios/chrome/browser/promos_manager/model:constants",
     "//ios/chrome/browser/shared/model/application_context",
@@ -97,10 +101,6 @@
     "//ios/chrome/browser/shared/public/commands",
     "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/shared/public/features:system_flags",
-    "//ios/chrome/browser/ui/default_promo/post_default_abandonment",
-    "//ios/chrome/browser/ui/default_promo/post_default_abandonment:features",
-    "//ios/chrome/browser/ui/default_promo/post_restore:post_restore_default_browser",
-    "//ios/chrome/browser/ui/default_promo/promo_handler",
     "//ios/chrome/browser/ui/first_run/omnibox_position/promo",
     "//ios/chrome/browser/ui/post_restore_signin",
     "//ios/chrome/browser/ui/whats_new:util",
diff --git a/ios/chrome/browser/ui/promos_manager/DEPS b/ios/chrome/browser/ui/promos_manager/DEPS
index 27c41de..3204e1e 100644
--- a/ios/chrome/browser/ui/promos_manager/DEPS
+++ b/ios/chrome/browser/ui/promos_manager/DEPS
@@ -1,9 +1,9 @@
 include_rules = [
+  "+ios/chrome/browser/credential_provider_promo/ui_bundled",
+  "+ios/chrome/browser/default_promo/ui_bundled",
   "+ios/chrome/browser/ui/app_store_rating",
   "+ios/chrome/browser/ui/post_restore_signin",
   "+ios/chrome/browser/ui/whats_new",
-  "+ios/chrome/browser/credential_provider_promo/ui_bundled",
-  "+ios/chrome/browser/ui/default_promo",
   "+ios/chrome/browser/ui/first_run/omnibox_position/promo",
 ]
 
diff --git a/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm b/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm
index b59e5c7b..129d4cc 100644
--- a/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm
+++ b/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm
@@ -23,6 +23,14 @@
 #import "ios/chrome/browser/app_store_rating/ui_bundled/features.h"
 #import "ios/chrome/browser/credential_provider_promo/ui_bundled/credential_provider_promo_display_handler.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/all_tabs_default_browser_promo_view_provider.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/made_for_ios_default_browser_promo_view_provider.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/features.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/post_default_abandonment/post_default_abandonment_promo_provider.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/post_restore/post_restore_default_browser_promo_provider.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_promo_display_handler.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/promo_handler/default_browser_remind_me_later_promo_display_handler.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/stay_safe_default_browser_promo_view_provider.h"
 #import "ios/chrome/browser/docking_promo/ui/docking_promo_display_handler.h"
 #import "ios/chrome/browser/feature_engagement/model/tracker_factory.h"
 #import "ios/chrome/browser/promos_manager/model/features.h"
@@ -37,14 +45,6 @@
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/public/features/system_flags.h"
 #import "ios/chrome/browser/sync/model/sync_service_factory.h"
-#import "ios/chrome/browser/ui/default_promo/all_tabs_default_browser_promo_view_provider.h"
-#import "ios/chrome/browser/ui/default_promo/made_for_ios_default_browser_promo_view_provider.h"
-#import "ios/chrome/browser/ui/default_promo/post_default_abandonment/features.h"
-#import "ios/chrome/browser/ui/default_promo/post_default_abandonment/post_default_abandonment_promo_provider.h"
-#import "ios/chrome/browser/ui/default_promo/post_restore/post_restore_default_browser_promo_provider.h"
-#import "ios/chrome/browser/ui/default_promo/promo_handler/default_browser_promo_display_handler.h"
-#import "ios/chrome/browser/ui/default_promo/promo_handler/default_browser_remind_me_later_promo_display_handler.h"
-#import "ios/chrome/browser/ui/default_promo/stay_safe_default_browser_promo_view_provider.h"
 #import "ios/chrome/browser/ui/first_run/omnibox_position/promo/omnibox_position_choice_display_handler.h"
 #import "ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider.h"
 #import "ios/chrome/browser/ui/promos_manager/bannered_promo_view_provider.h"
diff --git a/ios/chrome/browser/ui/settings/DEPS b/ios/chrome/browser/ui/settings/DEPS
index 57b1488..46bcadb 100644
--- a/ios/chrome/browser/ui/settings/DEPS
+++ b/ios/chrome/browser/ui/settings/DEPS
@@ -1,4 +1,6 @@
 include_rules = [
+  "+ios/chrome/browser/bubble/ui_bundled",
+  "+ios/chrome/browser/default_promo/ui_bundled/default_browser_instructions_view.h",
   "+ios/chrome/browser/ui/keyboard/key_command_actions.h",
   "+ios/chrome/browser/ui/keyboard/UIKeyCommand+Chrome.h",
   "+ios/chrome/browser/ui/authentication",
@@ -8,8 +10,6 @@
   "+ios/chrome/browser/ui/search_engine_choice/search_engine_choice_constants.h",
   "+ios/chrome/browser/ui/scoped_ui_blocker",
   "+ios/chrome/browser/ui/autofill/cells/autofill_edit_item.h",
-  "+ios/chrome/browser/ui/default_promo/default_browser_instructions_view.h",
-  "+ios/chrome/browser/bubble/ui_bundled",
   "+ios/chrome/browser/ui/push_notification/notifications_alert_presenter.h",
 ]
 
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_consumer.h b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_consumer.h
index 4e92f6b2..351e3d55 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_consumer.h
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_consumer.h
@@ -21,10 +21,9 @@
 @protocol ClearBrowsingDataConsumer <NSObject>
 // Execute action to clear browsing data.
 // `completionBlock` is then executed asynchronously.
-- (void)removeBrowsingDataForBrowserState:(ChromeBrowserState*)browserState
-                               timePeriod:(browsing_data::TimePeriod)timePeriod
-                               removeMask:(BrowsingDataRemoveMask)removeMask
-                          completionBlock:(ProceduralBlock)completionBlock;
+- (void)removeBrowsingDataForTimePeriod:(browsing_data::TimePeriod)timePeriod
+                             removeMask:(BrowsingDataRemoveMask)removeMask
+                        completionBlock:(ProceduralBlock)completionBlock;
 // Updates contents of a cell for a given item. Set reload to NO if a simple
 // reconfigre is enough.
 - (void)updateCellsForItem:(TableViewItem*)item reload:(BOOL)reload;
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_coordinator.mm b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_coordinator.mm
index 68ac5d5..635e6ce 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_coordinator.mm
@@ -7,14 +7,19 @@
 #import "base/apple/foundation_util.h"
 #import "base/check_op.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
+#import "ios/chrome/browser/shared/model/browser/browser_observer_bridge.h"
 #import "ios/chrome/browser/shared/public/commands/application_commands.h"
 #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
 #import "ios/chrome/browser/shared/public/commands/open_new_tab_command.h"
 #import "ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.h"
 #import "ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_ui_delegate.h"
 #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
-
-@interface ClearBrowsingDataCoordinator () <ClearBrowsingDataUIDelegate>
+@interface ClearBrowsingDataCoordinator () <BrowserObserving,
+                                            ClearBrowsingDataUIDelegate> {
+  // Observe BrowserObserver to prevent any access to Browser after its
+  // destroyed.
+  std::unique_ptr<BrowserObserverBridge> _browserObserver;
+}
 
 @property(nonatomic, strong) id<ApplicationCommands> handler;
 @property(nonatomic, strong)
@@ -40,6 +45,10 @@
 #pragma mark - ChromeCoordinator
 
 - (void)start {
+  DCHECK(!_browserObserver);
+  _browserObserver =
+      std::make_unique<BrowserObserverBridge>(self.browser, self);
+
   self.handler = HandlerForProtocol(self.browser->GetCommandDispatcher(),
                                     ApplicationCommands);
 
@@ -60,6 +69,8 @@
   self.viewController.dispatcher = nil;
   [self.viewController stop];
   self.viewController = nil;
+  _browserObserver.reset();
+
   [super stop];
 }
 
@@ -93,4 +104,11 @@
   [self.delegate clearBrowsingDataCoordinatorViewControllerWasRemoved:self];
 }
 
+#pragma mark - BrowserObserving
+
+- (void)browserDestroyed:(Browser*)browser {
+  DCHECK_EQ(browser, self.browser);
+  [self stop];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager.mm b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager.mm
index 1e397b2..c478344 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager.mm
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_manager.mm
@@ -123,6 +123,8 @@
 
 @interface ClearBrowsingDataManager () <BrowsingDataRemoverObserving,
                                         PrefObserverDelegate> {
+  base::WeakPtr<ChromeBrowserState> _browserState;
+
   // Access to the kDeleteTimePeriod preference.
   IntegerPrefMember _timeRangePref;
   // Pref observer to track changes to prefs.
@@ -144,7 +146,6 @@
       _countersByMasks;
 }
 
-@property(nonatomic, assign) ChromeBrowserState* browserState;
 // Whether to show alert about other forms of browsing history.
 @property(nonatomic, assign)
     BOOL shouldShowNoticeAboutOtherFormsOfBrowsingHistory;
@@ -168,7 +169,6 @@
 @end
 
 @implementation ClearBrowsingDataManager
-@synthesize browserState = _browserState;
 @synthesize consumer = _consumer;
 @synthesize shouldShowNoticeAboutOtherFormsOfBrowsingHistory =
     _shouldShowNoticeAboutOtherFormsOfBrowsingHistory;
@@ -190,11 +190,11 @@
         (BrowsingDataCounterWrapperProducer*)producer {
   self = [super init];
   if (self) {
-    _browserState = browserState;
+    _browserState = browserState->AsWeakPtr();
     _counterWrapperProducer = producer;
 
     _timeRangePref.Init(browsing_data::prefs::kDeleteTimePeriod,
-                        _browserState->GetPrefs());
+                        self.prefService);
 
     _browsingDataRemoverObserver =
         std::make_unique<BrowsingDataRemoverObserverBridge>(self);
@@ -204,7 +204,7 @@
             _browsingDataRemoverObserver.get());
     _scoped_observation->Observe(remover);
 
-    _prefChangeRegistrar.Init(_browserState->GetPrefs());
+    _prefChangeRegistrar.Init(self.prefService);
     _prefObserverBridge.reset(new PrefObserverBridge(self));
   }
   return self;
@@ -263,6 +263,7 @@
   _browsingDataRemoverObserver.reset();
   _countersByMasks.clear();
   _counterWrapperProducer = nil;
+  _browserState.reset();
 }
 
 // Add items for types of browsing data to clear.
@@ -274,8 +275,10 @@
                           titleID:IDS_IOS_CLEAR_BROWSING_HISTORY
                              mask:BrowsingDataRemoveMask::REMOVE_HISTORY
                          prefName:browsing_data::prefs::kDeleteBrowsingHistory];
-  [model addItem:self.browsingHistoryItem
-      toSectionWithIdentifier:SectionIdentifierDataTypes];
+  if (self.browsingHistoryItem) {
+    [model addItem:self.browsingHistoryItem
+        toSectionWithIdentifier:SectionIdentifierDataTypes];
+  }
 
   // This data type doesn't currently have an associated counter, but displays
   // an explanatory text instead.
@@ -284,32 +287,40 @@
                           titleID:IDS_IOS_CLEAR_COOKIES
                              mask:BrowsingDataRemoveMask::REMOVE_SITE_DATA
                          prefName:browsing_data::prefs::kDeleteCookies];
-  [model addItem:self.cookiesSiteDataItem
-      toSectionWithIdentifier:SectionIdentifierDataTypes];
+  if (self.cookiesSiteDataItem) {
+    [model addItem:self.cookiesSiteDataItem
+        toSectionWithIdentifier:SectionIdentifierDataTypes];
+  }
 
   self.cacheItem =
       [self clearDataItemWithType:ItemTypeDataTypeCache
                           titleID:IDS_IOS_CLEAR_CACHE
                              mask:BrowsingDataRemoveMask::REMOVE_CACHE
                          prefName:browsing_data::prefs::kDeleteCache];
-  [model addItem:self.cacheItem
-      toSectionWithIdentifier:SectionIdentifierDataTypes];
+  if (self.cacheItem) {
+    [model addItem:self.cacheItem
+        toSectionWithIdentifier:SectionIdentifierDataTypes];
+  }
 
   self.savedPasswordsItem =
       [self clearDataItemWithType:ItemTypeDataTypeSavedPasswords
                           titleID:IDS_IOS_CLEAR_SAVED_PASSWORDS
                              mask:BrowsingDataRemoveMask::REMOVE_PASSWORDS
                          prefName:browsing_data::prefs::kDeletePasswords];
-  [model addItem:self.savedPasswordsItem
-      toSectionWithIdentifier:SectionIdentifierDataTypes];
+  if (self.savedPasswordsItem) {
+    [model addItem:self.savedPasswordsItem
+        toSectionWithIdentifier:SectionIdentifierDataTypes];
+  }
 
   self.autofillItem =
       [self clearDataItemWithType:ItemTypeDataTypeAutofill
                           titleID:IDS_IOS_CLEAR_AUTOFILL
                              mask:BrowsingDataRemoveMask::REMOVE_FORM_DATA
                          prefName:browsing_data::prefs::kDeleteFormData];
-  [model addItem:self.autofillItem
-      toSectionWithIdentifier:SectionIdentifierDataTypes];
+  if (self.autofillItem) {
+    [model addItem:self.autofillItem
+        toSectionWithIdentifier:SectionIdentifierDataTypes];
+  }
 }
 
 - (NSString*)counterTextFromResult:
@@ -402,10 +413,16 @@
 
 // Add footers about user's account data.
 - (void)addSyncProfileItemsToModel:(ListModel*)model {
+  ChromeBrowserState* browserState = self.browserState;
+  if (!browserState) {
+    // The C++ model has been destroyed, return early.
+    return;
+  }
+
   // Google Account footer.
   const BOOL loggedIn = [self loggedIn];
   const TemplateURLService* templateURLService =
-      ios::TemplateURLServiceFactory::GetForBrowserState(_browserState);
+      ios::TemplateURLServiceFactory::GetForBrowserState(browserState);
   const TemplateURL* defaultSearchEngine =
       templateURLService->GetDefaultSearchProvider();
   const BOOL isDefaultSearchEngineGoogle =
@@ -430,7 +447,7 @@
   [self addSavedSiteDataSectionWithModel:model];
 
   history::WebHistoryService* historyService =
-      ios::WebHistoryServiceFactory::GetForBrowserState(_browserState);
+      ios::WebHistoryServiceFactory::GetForBrowserState(browserState);
 
   __weak ClearBrowsingDataManager* weakSelf = self;
 
@@ -473,11 +490,17 @@
                   titleID:(int)titleMessageID
                      mask:(BrowsingDataRemoveMask)mask
                  prefName:(const char*)prefName {
-  PrefService* prefs = self.browserState->GetPrefs();
+  ChromeBrowserState* browserState = self.browserState;
+  PrefService* prefService = self.prefService;
+  if (!browserState || !prefService) {
+    // The C++ model has been destroyed, return early.
+    return nullptr;
+  }
+
   TableViewClearBrowsingDataItem* clearDataItem =
       [[TableViewClearBrowsingDataItem alloc] initWithType:itemType];
   clearDataItem.text = l10n_util::GetNSString(titleMessageID);
-  clearDataItem.checked = prefs->GetBoolean(prefName);
+  clearDataItem.checked = prefService->GetBoolean(prefName);
   clearDataItem.accessibilityIdentifier =
       [self accessibilityIdentifierFromItemType:itemType];
   clearDataItem.dataTypeMask = mask;
@@ -620,12 +643,18 @@
 }
 
 - (TableViewDetailIconItem*)timeRangeItem {
+  PrefService* prefService = self.prefService;
+  if (!prefService) {
+    // The C++ model has been destroyed, return early.
+    return nil;
+  }
+
   TableViewDetailIconItem* timeRangeItem =
       [[TableViewDetailIconItem alloc] initWithType:ItemTypeTimeRange];
   timeRangeItem.text = l10n_util::GetNSString(
       IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_SELECTOR_TITLE);
   NSString* detailText = [TimeRangeSelectorTableViewController
-      timePeriodLabelForPrefs:self.browserState->GetPrefs()];
+      timePeriodLabelForPrefs:prefService];
   DCHECK(detailText);
   timeRangeItem.detailText = detailText;
   timeRangeItem.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
@@ -652,6 +681,19 @@
   }
 }
 
+#pragma mark - Properties
+
+- (ChromeBrowserState*)browserState {
+  return _browserState.get();
+}
+
+- (PrefService*)prefService {
+  if (ChromeBrowserState* browserState = self.browserState) {
+    return browserState->GetPrefs();
+  }
+  return nullptr;
+}
+
 #pragma mark - Private Methods
 
 // An identity manager
@@ -680,24 +722,29 @@
 }
 
 - (void)clearDataForDataTypes:(BrowsingDataRemoveMask)mask {
+  ChromeBrowserState* browserState = self.browserState;
+  PrefService* prefService = self.prefService;
+  if (!browserState || !prefService) {
+    // The C++ model has been destroyed, return early.
+    return;
+  }
+
   DCHECK(mask != BrowsingDataRemoveMask::REMOVE_NOTHING);
 
   browsing_data::TimePeriod timePeriod =
       static_cast<browsing_data::TimePeriod>(_timeRangePref.GetValue());
-  [self.consumer removeBrowsingDataForBrowserState:_browserState
-                                        timePeriod:timePeriod
-                                        removeMask:mask
-                                   completionBlock:nil];
+  [self.consumer removeBrowsingDataForTimePeriod:timePeriod
+                                      removeMask:mask
+                                 completionBlock:nil];
 
   // Send the "Cleared Browsing Data" event to the feature_engagement::Tracker
   // when the user initiates a clear browsing data action. No event is sent if
   // the browsing data is cleared without the user's input.
-  feature_engagement::TrackerFactory::GetForBrowserState(_browserState)
+  feature_engagement::TrackerFactory::GetForBrowserState(browserState)
       ->NotifyEvent(feature_engagement::events::kClearedBrowsingData);
 
   if (IsRemoveDataMaskSet(mask, BrowsingDataRemoveMask::REMOVE_HISTORY)) {
-    PrefService* prefs = _browserState->GetPrefs();
-    int noticeShownTimes = prefs->GetInteger(
+    int noticeShownTimes = prefService->GetInteger(
         browsing_data::prefs::kClearBrowsingDataHistoryNoticeShownTimes);
 
     // When the deletion is complete, we might show an additional dialog with
@@ -715,7 +762,7 @@
         showDialog);
 
     // Increment the preference.
-    prefs->SetInteger(
+    prefService->SetInteger(
         browsing_data::prefs::kClearBrowsingDataHistoryNoticeShownTimes,
         noticeShownTimes + 1);
     [self.consumer showBrowsingHistoryRemovedDialog];
@@ -728,7 +775,7 @@
     return;
   }
   feature_engagement::Tracker* tracker =
-      feature_engagement::TrackerFactory::GetForBrowserState(_browserState);
+      feature_engagement::TrackerFactory::GetForBrowserState(self.browserState);
   tracker->NotifyEvent(
       feature_engagement::events::kEnhancedSafeBrowsingPromoCriterionMet);
 }
@@ -760,26 +807,36 @@
 #pragma mark - PrefObserverDelegate
 
 - (void)onPreferenceChanged:(const std::string&)preferenceName {
-  PrefService* prefs = self.browserState->GetPrefs();
+  PrefService* prefService = self.prefService;
+  if (!prefService) {
+    // The C++ model has been destroyed, return early.
+    return;
+  }
+
   if (preferenceName == browsing_data::prefs::kDeleteTimePeriod) {
-    NSString* detailText =
-        [TimeRangeSelectorTableViewController timePeriodLabelForPrefs:prefs];
+    NSString* detailText = [TimeRangeSelectorTableViewController
+        timePeriodLabelForPrefs:prefService];
     self.tableViewTimeRangeItem.detailText = detailText;
     [self.consumer updateCellsForItem:self.tableViewTimeRangeItem reload:YES];
   } else if (preferenceName == browsing_data::prefs::kDeleteBrowsingHistory) {
-    self.browsingHistoryItem.checked = prefs->GetBoolean(preferenceName);
+    CHECK(self.browsingHistoryItem);
+    self.browsingHistoryItem.checked = prefService->GetBoolean(preferenceName);
     [self.consumer updateCellsForItem:self.browsingHistoryItem reload:NO];
   } else if (preferenceName == browsing_data::prefs::kDeleteCookies) {
-    self.cookiesSiteDataItem.checked = prefs->GetBoolean(preferenceName);
+    CHECK(self.cookiesSiteDataItem);
+    self.cookiesSiteDataItem.checked = prefService->GetBoolean(preferenceName);
     [self.consumer updateCellsForItem:self.cookiesSiteDataItem reload:NO];
   } else if (preferenceName == browsing_data::prefs::kDeleteCache) {
-    self.cacheItem.checked = prefs->GetBoolean(preferenceName);
+    CHECK(self.cacheItem);
+    self.cacheItem.checked = prefService->GetBoolean(preferenceName);
     [self.consumer updateCellsForItem:self.cacheItem reload:NO];
   } else if (preferenceName == browsing_data::prefs::kDeletePasswords) {
-    self.savedPasswordsItem.checked = prefs->GetBoolean(preferenceName);
+    CHECK(self.savedPasswordsItem);
+    self.savedPasswordsItem.checked = prefService->GetBoolean(preferenceName);
     [self.consumer updateCellsForItem:self.savedPasswordsItem reload:NO];
   } else if (preferenceName == browsing_data::prefs::kDeleteFormData) {
-    self.autofillItem.checked = prefs->GetBoolean(preferenceName);
+    CHECK(self.autofillItem);
+    self.autofillItem.checked = prefService->GetBoolean(preferenceName);
     [self.consumer updateCellsForItem:self.autofillItem reload:NO];
   } else {
     DCHECK(false) << "Unxpected clear browsing data item type.";
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.mm b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.mm
index 284b675..9f18507 100644
--- a/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_table_view_controller.mm
@@ -53,18 +53,15 @@
     IdentityManagerObserverBridgeDelegate,
     SignoutActionSheetCoordinatorDelegate,
     TableViewLinkHeaderFooterItemDelegate,
-    UIGestureRecognizerDelegate>
+    UIGestureRecognizerDelegate> {
+  // Browser.
+  base::WeakPtr<Browser> _browser;
+}
 
 // TODO(crbug.com/40579855): remove direct dependency and replace with
 // delegate.
 @property(nonatomic, readonly, strong) ClearBrowsingDataManager* dataManager;
 
-// Browser state.
-@property(nonatomic, readonly) ChromeBrowserState* browserState;
-
-// Browser.
-@property(nonatomic, readonly) Browser* browser;
-
 // Coordinator that managers a UIAlertController to clear browsing data.
 @property(nonatomic, strong) ActionSheetCoordinator* actionSheetCoordinator;
 
@@ -101,14 +98,14 @@
   UITableViewStyle style = ChromeTableViewStyle();
   self = [super initWithStyle:style];
   if (self) {
-    _browser = browser;
-    _browserState = browser->GetBrowserState();
+    _browser = browser->AsWeakPtr();
     _dataManager = [[ClearBrowsingDataManager alloc]
-        initWithBrowserState:browser->GetBrowserState()];
+        initWithBrowserState:self.browserState];
     _dataManager.consumer = self;
     _identityManagerObserverBridge.reset(
         new signin::IdentityManagerObserverBridge(
-            IdentityManagerFactory::GetForBrowserState(_browserState), self));
+            IdentityManagerFactory::GetForBrowserState(self.browserState),
+            self));
   }
   return self;
 }
@@ -119,8 +116,7 @@
   [_dataManager disconnect];
   _dataManager.consumer = nil;
   _dataManager = nil;
-  _browser = nil;
-  _browserState = nil;
+  _browser.reset();
 }
 
 - (void)didMoveToParentViewController:(UIViewController*)parent {
@@ -301,7 +297,9 @@
 
 - (void)tableView:(UITableView*)tableView
     didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
-  if (!self.browserState) {
+  PrefService* prefService = self.prefService;
+  if (!prefService) {
+    // The C++ model has been destroyed, return early.
     return;
   }
 
@@ -311,7 +309,7 @@
     case ItemTypeTimeRange: {
       UIViewController* controller =
           [[TimeRangeSelectorTableViewController alloc]
-              initWithPrefs:self.browserState->GetPrefs()];
+              initWithPrefs:prefService];
       [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
       [self.navigationController pushViewController:controller animated:YES];
       break;
@@ -325,8 +323,8 @@
       TableViewClearBrowsingDataItem* clearBrowsingDataItem =
           base::apple::ObjCCastStrict<TableViewClearBrowsingDataItem>(item);
 
-      self.browserState->GetPrefs()->SetBoolean(clearBrowsingDataItem.prefName,
-                                                !clearBrowsingDataItem.checked);
+      prefService->SetBoolean(clearBrowsingDataItem.prefName,
+                              !clearBrowsingDataItem.checked);
       // UI update will be trigerred by data manager.
       break;
     }
@@ -406,14 +404,16 @@
   }
 }
 
-- (void)removeBrowsingDataForBrowserState:(ChromeBrowserState*)browserState
-                               timePeriod:(browsing_data::TimePeriod)timePeriod
-                               removeMask:(BrowsingDataRemoveMask)removeMask
-                          completionBlock:(ProceduralBlock)completionBlock {
-  if (!self.browserState) {
+- (void)removeBrowsingDataForTimePeriod:(browsing_data::TimePeriod)timePeriod
+                             removeMask:(BrowsingDataRemoveMask)removeMask
+                        completionBlock:(ProceduralBlock)completionBlock {
+  Browser* browser = self.browser;
+  ChromeBrowserState* browserState = self.browserState;
+  PrefService* prefService = self.prefService;
+  if (!browser || !browserState || !prefService) {
+    // The C++ model has been destroyed, return early.
     return;
   }
-  CHECK(browserState, base::NotFatalUntil::M130);
 
   base::RecordAction(
       base::UserMetricsAction("MobileClearBrowsingDataTriggeredFromUIRefresh"));
@@ -421,7 +421,7 @@
   // Show activity indicator modal while removal is happening.
   self.overlayCoordinator = [[ChromeActivityOverlayCoordinator alloc]
       initWithBaseViewController:self.navigationController
-                         browser:_browser];
+                         browser:browser];
 
   self.overlayCoordinator.messageText = l10n_util::GetNSStringWithFixup(
       IDS_IOS_CLEAR_BROWSING_DATA_ACTIVITY_MODAL);
@@ -466,9 +466,8 @@
   // showing of customized content after history has been cleared. We might want
   // to create a specific Pref for this.
   if (IsRemoveDataMaskSet(removeMask, BrowsingDataRemoveMask::REMOVE_HISTORY)) {
-    browserState->GetPrefs()->SetInt64(
-        browsing_data::prefs::kLastClearBrowsingDataTime,
-        base::Time::Now().ToTimeT());
+    prefService->SetInt64(browsing_data::prefs::kLastClearBrowsingDataTime,
+                          base::Time::Now().ToTimeT());
 
     DiscoverFeedServiceFactory::GetForBrowserState(browserState)
         ->BrowsingHistoryCleared();
@@ -482,6 +481,12 @@
 }
 
 - (void)showBrowsingHistoryRemovedDialog {
+  Browser* browser = self.browser;
+  if (!browser) {
+    // The C++ model has been destroyed, return early.
+    return;
+  }
+
   NSString* title =
       l10n_util::GetNSString(IDS_IOS_CLEAR_BROWSING_DATA_HISTORY_NOTICE_TITLE);
   NSString* message = l10n_util::GetNSString(
@@ -489,7 +494,7 @@
 
   self.alertCoordinator =
       [[AlertCoordinator alloc] initWithBaseViewController:self
-                                                   browser:_browser
+                                                   browser:browser
                                                      title:title
                                                    message:message];
 
@@ -547,9 +552,35 @@
   [self allowUserInteraction];
 }
 
+#pragma mark - Properties
+
+- (Browser*)browser {
+  return _browser.get();
+}
+
+- (ChromeBrowserState*)browserState {
+  if (Browser* browser = self.browser) {
+    return browser->GetBrowserState();
+  }
+  return nullptr;
+}
+
+- (PrefService*)prefService {
+  if (ChromeBrowserState* browserState = self.browserState) {
+    return browserState->GetPrefs();
+  }
+  return nullptr;
+}
+
 #pragma mark - Private Helpers
 
 - (void)showClearBrowsingDataAlertController:(id)sender {
+  Browser* browser = self.browser;
+  if (!browser) {
+    // The C++ model has been destroyed, return early.
+    return;
+  }
+
   BrowsingDataRemoveMask dataTypeMaskToRemove =
       BrowsingDataRemoveMask::REMOVE_NOTHING;
   NSArray* dataTypeItems = [self.tableViewModel
@@ -563,7 +594,7 @@
   self.actionSheetCoordinator = [self.dataManager
       actionSheetCoordinatorWithDataTypesToRemove:dataTypeMaskToRemove
                                baseViewController:self
-                                          browser:_browser
+                                          browser:browser
                               sourceBarButtonItem:sender];
   __weak ClearBrowsingDataTableViewController* weakSelf = self;
   [self.actionSheetCoordinator
@@ -602,6 +633,12 @@
 // If they sync, they can keep or delete their data.
 // TODO(crbug.com/40879413) Test that correct histogram is registered.
 - (void)showSignOutWithItemView:(UIView*)itemView {
+  Browser* browser = self.browser;
+  if (!browser) {
+    // The C++ model has been destroyed, return early.
+    return;
+  }
+
   if (_signoutCoordinator) {
     // An action is already in progress, ignore user's request.
     return;
@@ -610,7 +647,7 @@
       ProfileSignout::kUserClickedSignoutFromClearBrowsingDataPage;
   _signoutCoordinator = [[SignoutActionSheetCoordinator alloc]
       initWithBaseViewController:self
-                         browser:_browser
+                         browser:browser
                             rect:itemView.frame
                             view:itemView
                       withSource:signout_source_metric];
diff --git a/ios/chrome/browser/ui/settings/default_browser/BUILD.gn b/ios/chrome/browser/ui/settings/default_browser/BUILD.gn
index c9474a5..959eac0 100644
--- a/ios/chrome/browser/ui/settings/default_browser/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/default_browser/BUILD.gn
@@ -11,11 +11,11 @@
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/default_browser/model",
     "//ios/chrome/browser/default_browser/model:utils",
+    "//ios/chrome/browser/default_promo/ui_bundled:coordinator",
     "//ios/chrome/browser/intents:intents_donation_helper",
     "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/shared/ui/table_view:utils",
     "//ios/chrome/browser/shared/ui/table_view/cells",
-    "//ios/chrome/browser/ui/default_promo",
     "//ios/chrome/browser/ui/settings:constants",
     "//ios/chrome/browser/ui/settings:settings_root",
     "//ios/chrome/browser/ui/settings/default_browser/resources",
diff --git a/ios/chrome/browser/ui/settings/default_browser/default_browser_settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/default_browser/default_browser_settings_table_view_controller.mm
index 68b2a16..39ad08fa0 100644
--- a/ios/chrome/browser/ui/settings/default_browser/default_browser_settings_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/default_browser/default_browser_settings_table_view_controller.mm
@@ -9,13 +9,13 @@
 #import "base/metrics/user_metrics_action.h"
 #import "base/strings/strcat.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
+#import "ios/chrome/browser/default_promo/ui_bundled/default_browser_instructions_view.h"
 #import "ios/chrome/browser/intents/intents_donation_helper.h"
 #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_detail_icon_item.h"
 #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_image_item.h"
 #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_link_header_footer_item.h"
 #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_text_item.h"
 #import "ios/chrome/browser/shared/ui/table_view/table_view_utils.h"
-#import "ios/chrome/browser/ui/default_promo/default_browser_instructions_view.h"
 #import "ios/chrome/browser/ui/settings/settings_table_view_controller_constants.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm
index 0f4e9ef4..62e8f9e 100644
--- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm
@@ -160,10 +160,7 @@
   BOOL isSyncConsentGiven =
       syncService &&
       syncService->GetUserSettings()->IsInitialSyncFeatureSetupComplete();
-  BOOL shouldClearDataOnSignOut =
-      self.authService->HasPrimaryIdentityManaged(
-          signin::ConsentLevel::kSignin) &&
-      base::FeatureList::IsEnabled(kClearDeviceDataOnSignOutForManagedUsers);
+  BOOL shouldClearDataOnSignOut = self.authService->ShouldClearDataOnSignOut();
 
   self.signOutCoordinator = [[ActionSheetCoordinator alloc]
       initWithBaseViewController:self.viewController
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm
index 4616d79..640f685 100644
--- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm
@@ -229,10 +229,7 @@
       break;
     case SyncSettingsAccountState::kSignedIn:
       BOOL would_clear_data_on_signout =
-          _authenticationService->HasPrimaryIdentityManaged(
-              signin::ConsentLevel::kSignin) &&
-          base::FeatureList::IsEnabled(
-              kClearDeviceDataOnSignOutForManagedUsers);
+          _authenticationService->ShouldClearDataOnSignOut();
       [model addSectionWithIdentifier:SyncDataTypeSectionIdentifier];
       TableViewTextHeaderFooterItem* headerItem =
           [[TableViewTextHeaderFooterItem alloc]
diff --git a/ios/chrome/browser/ui/sharing/activity_services/BUILD.gn b/ios/chrome/browser/ui/sharing/activity_services/BUILD.gn
index 126d8df..d66ed56 100644
--- a/ios/chrome/browser/ui/sharing/activity_services/BUILD.gn
+++ b/ios/chrome/browser/ui/sharing/activity_services/BUILD.gn
@@ -23,6 +23,7 @@
     "//components/prefs",
     "//components/ui_metrics",
     "//ios/chrome/browser/bookmarks/model",
+    "//ios/chrome/browser/default_promo/ui_bundled:coordinator",
     "//ios/chrome/browser/reading_list/model",
     "//ios/chrome/browser/shared/coordinator/chrome_coordinator",
     "//ios/chrome/browser/shared/coordinator/default_browser_promo",
@@ -38,7 +39,6 @@
     "//ios/chrome/browser/shared/ui/util:url_with_title",
     "//ios/chrome/browser/sync/model",
     "//ios/chrome/browser/tabs/model",
-    "//ios/chrome/browser/ui/default_promo",
     "//ios/chrome/browser/ui/main:default_browser_scene_agent",
     "//ios/chrome/browser/ui/sharing",
     "//ios/chrome/browser/ui/sharing/activity_services/activities",
diff --git a/ios/chrome/browser/ui/sharing/activity_services/DEPS b/ios/chrome/browser/ui/sharing/activity_services/DEPS
index f4279b9..ac5ae1f 100644
--- a/ios/chrome/browser/ui/sharing/activity_services/DEPS
+++ b/ios/chrome/browser/ui/sharing/activity_services/DEPS
@@ -1,5 +1,5 @@
 include_rules = [
-  "+ios/chrome/browser/ui/default_promo/default_browser_promo_non_modal_scheduler.h",
+  "+ios/chrome/browser/default_promo/ui_bundled/default_browser_promo_non_modal_scheduler.h",
 ]
 
 specific_include_rules = {
diff --git a/ios/chrome/browser/ui/start_surface/BUILD.gn b/ios/chrome/browser/ui/start_surface/BUILD.gn
index 62bf35f..23d386a 100644
--- a/ios/chrome/browser/ui/start_surface/BUILD.gn
+++ b/ios/chrome/browser/ui/start_surface/BUILD.gn
@@ -62,6 +62,7 @@
     "//base/test:test_support",
     "//components/favicon/ios",
     "//components/sync_preferences:test_support",
+    "//components/tab_groups",
     "//ios/chrome/app:app_internal",
     "//ios/chrome/app/application_delegate:app_state_header",
     "//ios/chrome/app/application_delegate:application_delegate_internal",
diff --git a/ios/chrome/browser/ui/start_surface/start_surface_scene_agent_unittest.mm b/ios/chrome/browser/ui/start_surface/start_surface_scene_agent_unittest.mm
index 64bb8be5..eea67651 100644
--- a/ios/chrome/browser/ui/start_surface/start_surface_scene_agent_unittest.mm
+++ b/ios/chrome/browser/ui/start_surface/start_surface_scene_agent_unittest.mm
@@ -8,6 +8,7 @@
 #import "base/test/scoped_feature_list.h"
 #import "components/favicon/ios/web_favicon_driver.h"
 #import "components/sync_preferences/testing_pref_service_syncable.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "ios/chrome/app/application_delegate/app_state.h"
 #import "ios/chrome/app/application_delegate/fake_startup_information.h"
 #import "ios/chrome/browser/ntp/model/new_tab_page_tab_helper.h"
@@ -33,6 +34,8 @@
 #import "testing/platform_test.h"
 #import "third_party/ocmock/OCMock/OCMock.h"
 
+using tab_groups::TabGroupId;
+
 namespace {
 const char kURL[] = "https://chromium.org/";
 }
@@ -261,8 +264,10 @@
   WebStateList* web_state_list =
       scene_state_.browserProviderInterface.mainBrowserProvider.browser
           ->GetWebStateList();
-  const TabGroup* group_0 = web_state_list->CreateGroup({0, 1, 2, 3}, {});
-  const TabGroup* group_1 = web_state_list->CreateGroup({6}, {});
+  const TabGroup* group_0 =
+      web_state_list->CreateGroup({0, 1, 2, 3}, {}, TabGroupId::GenerateNew());
+  const TabGroup* group_1 =
+      web_state_list->CreateGroup({6}, {}, TabGroupId::GenerateNew());
   [agent_ sceneState:scene_state_
       transitionedToActivationLevel:SceneActivationLevelForegroundActive];
   histogram_tester_->ExpectTotalCount("IOS.NTP.ExcessRemovedTabCount", 0);
@@ -311,7 +316,8 @@
       scene_state_.browserProviderInterface.mainBrowserProvider.browser
           ->GetWebStateList();
   web_state_list->ActivateWebStateAt(0);
-  const TabGroup* group_0 = web_state_list->CreateGroup({0, 1}, {});
+  const TabGroup* group_0 =
+      web_state_list->CreateGroup({0, 1}, {}, TabGroupId::GenerateNew());
   [agent_ sceneState:scene_state_
       transitionedToActivationLevel:SceneActivationLevelForegroundActive];
   histogram_tester_->ExpectTotalCount("IOS.NTP.ExcessRemovedTabCount", 0);
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_collection_drag_drop_metrics.h b/ios/chrome/browser/ui/tab_switcher/tab_collection_drag_drop_metrics.h
index b7a6120..d04880ef 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_collection_drag_drop_metrics.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_collection_drag_drop_metrics.h
@@ -47,7 +47,7 @@
 enum class DragItemOrigin {
   kSameCollection = 0,
   kSameBrowser = 1,
-  kOtherBrwoser = 2,
+  kOtherBrowser = 2,
   kOther = 3,
   kMaxValue = kOther
 };
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.mm
index 5fbd353d..6729295 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.mm
@@ -1238,7 +1238,7 @@
     if (sourceWebStateIndex == WebStateList::kInvalidIndex) {
       // Move tab across Browsers.
       base::UmaHistogramEnumeration(kUmaGridViewDragOrigin,
-                                    DragItemOrigin::kOtherBrwoser);
+                                    DragItemOrigin::kOtherBrowser);
       int destinationWebStateIndex =
           WebStateIndexFromGridDropItemIndex(webStateList, destinationIndex);
 
@@ -1247,13 +1247,14 @@
     }
 
     if (fromSameCollection) {
-      base::UmaHistogramEnumeration(kUmaGroupViewDragOrigin,
+      base::UmaHistogramEnumeration(kUmaGridViewDragOrigin,
                                     DragItemOrigin::kSameCollection);
     } else {
       base::UmaHistogramEnumeration(kUmaGridViewDragOrigin,
                                     DragItemOrigin::kSameBrowser);
     }
 
+    // Reorder tabs.
     int destinationWebStateIndex = WebStateIndexFromGridDropItemIndex(
         webStateList, destinationIndex, sourceWebStateIndex);
     const auto insertionParams =
@@ -1271,7 +1272,7 @@
       return;
     }
     if (fromSameCollection) {
-      base::UmaHistogramEnumeration(kUmaGridViewGroupDragOrigin,
+      base::UmaHistogramEnumeration(kUmaGridViewDragOrigin,
                                     DragItemOrigin::kSameCollection);
       CHECK(tabGroupInfo.tabGroup);
       int sourceIndex = tabGroupInfo.tabGroup->range().range_begin();
@@ -1280,8 +1281,8 @@
       webStateList->MoveGroup(tabGroupInfo.tabGroup, nextWebStateIndex);
       return;
     } else {
-      base::UmaHistogramEnumeration(kUmaGridViewGroupDragOrigin,
-                                    DragItemOrigin::kOtherBrwoser);
+      base::UmaHistogramEnumeration(kUmaGridViewDragOrigin,
+                                    DragItemOrigin::kOtherBrowser);
     }
 
     int destinationWebStateIndex =
@@ -1308,13 +1309,23 @@
     return;
   }
 
+  if (_currentMode == TabGridModeGroup) {
+    base::UmaHistogramEnumeration(kUmaGroupViewDragOrigin,
+                                  DragItemOrigin::kOther);
+  } else {
+    base::UmaHistogramEnumeration(kUmaGridViewDragOrigin,
+                                  DragItemOrigin::kOther);
+  }
+
+  __weak BaseGridMediator* weakSelf = self;
   auto loadHandler =
       ^(__kindof id<NSItemProviderReading> providedItem, NSError* error) {
         dispatch_async(dispatch_get_main_queue(), ^{
           [placeholderContext deletePlaceholder];
           NSURL* droppedURL = static_cast<NSURL*>(providedItem);
-          [self insertNewWebStateAtGridIndex:destinationIndex
-                                     withURL:net::GURLWithNSURL(droppedURL)];
+          [weakSelf
+              insertNewWebStateAtGridIndex:destinationIndex
+                                   withURL:net::GURLWithNSURL(droppedURL)];
         });
       };
   [itemProvider loadObjectOfClass:[NSURL class] completionHandler:loadHandler];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator_unittest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator_unittest.mm
index 9688ae67..20111276 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator_unittest.mm
@@ -13,8 +13,10 @@
 #import "base/containers/contains.h"
 #import "base/strings/sys_string_conversions.h"
 #import "base/test/ios/wait_util.h"
+#import "base/test/metrics/histogram_tester.h"
 #import "base/time/time.h"
 #import "components/commerce/core/commerce_feature_list.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "components/tab_groups/tab_group_visual_data.h"
 #import "ios/chrome/browser/commerce/model/shopping_persisted_data_tab_helper.h"
 #import "ios/chrome/browser/drag_and_drop/model/drag_item_util.h"
@@ -28,6 +30,7 @@
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_opener.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/snapshots/model/snapshot_browser_agent.h"
+#import "ios/chrome/browser/ui/tab_switcher/tab_collection_drag_drop_metrics.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_item_identifier.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_mediator_test.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/incognito/incognito_grid_mediator.h"
@@ -48,6 +51,8 @@
 #import "ui/base/l10n/l10n_util_mac.h"
 #import "url/gurl.h"
 
+using tab_groups::TabGroupId;
+
 namespace {
 
 // URL to be used for drag and drop tests.
@@ -92,8 +97,15 @@
     GridMediatorTestClass::TearDown();
   }
 
+  // Checks that the drag item origin metric is logged in UMA.
+  void ExpectThatDragItemOriginMetricLogged(DragItemOrigin origin,
+                                            int count = 1) {
+    histogram_tester_.ExpectUniqueSample(kUmaGridViewDragOrigin, origin, count);
+  }
+
  protected:
   BaseGridMediator* mediator_;
+  base::HistogramTester histogram_tester_;
 };
 
 // Variation on BaseGridMediatorTest which enable PriceDropIndicatorsFlag.
@@ -591,8 +603,10 @@
 
   [mediator_ selectTabsButtonTapped:nil];
   browser_->GetWebStateList()->CreateGroup(
-      {1}, tab_groups::TabGroupVisualData(u"My group",
-                                          tab_groups::TabGroupColorId::kBlue));
+      {1},
+      tab_groups::TabGroupVisualData(u"My group",
+                                     tab_groups::TabGroupColorId::kBlue),
+      TabGroupId::GenerateNew());
 
   // Simulate a user who tapped on a tab.
   [mediator_ userTappedOnItemID:[GridItemIdentifier
@@ -656,8 +670,10 @@
 
   [mediator_ selectTabsButtonTapped:nil];
   browser_->GetWebStateList()->CreateGroup(
-      {1}, tab_groups::TabGroupVisualData(u"My group",
-                                          tab_groups::TabGroupColorId::kBlue));
+      {1},
+      tab_groups::TabGroupVisualData(u"My group",
+                                     tab_groups::TabGroupColorId::kBlue),
+      TabGroupId::GenerateNew());
 
   // Simulate a user who tapped on a tab and on the group.
   [mediator_ userTappedOnItemID:[GridItemIdentifier
@@ -718,7 +734,7 @@
 TEST_P(BaseGridMediatorTest, UngroupGroup) {
   WebStateList* web_state_list = browser_->GetWebStateList();
 
-  web_state_list->CreateGroup({1}, {});
+  web_state_list->CreateGroup({1}, {}, TabGroupId::GenerateNew());
   const TabGroup* group = web_state_list->GetGroupOfWebStateAt(1);
 
   EXPECT_EQ(3UL, consumer_.items.size());
@@ -737,7 +753,7 @@
 // Tests that closing the last tab of a selected group clears the selection.
 TEST_P(BaseGridMediatorTest, CloseSelectedGroup) {
   WebStateList* web_state_list = browser_->GetWebStateList();
-  web_state_list->CreateGroup({1}, {});
+  web_state_list->CreateGroup({1}, {}, TabGroupId::GenerateNew());
   const TabGroup* group = web_state_list->GetGroupOfWebStateAt(1);
   [mediator_ switchToMode:TabGridModeSelection];
   [mediator_
@@ -755,7 +771,7 @@
 // clears the selection.
 TEST_P(BaseGridMediatorTest, CloseSelectedGroupInBatch) {
   WebStateList* web_state_list = browser_->GetWebStateList();
-  web_state_list->CreateGroup({1}, {});
+  web_state_list->CreateGroup({1}, {}, TabGroupId::GenerateNew());
   const TabGroup* group = web_state_list->GetGroupOfWebStateAt(1);
   [mediator_ switchToMode:TabGridModeSelection];
   [mediator_
@@ -827,6 +843,7 @@
   [mediator_ dropItem:drag_item toIndex:0 fromSameCollection:YES];
 
   EXPECT_EQ("| c a* b", builder.GetWebStateListDescription());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kSameCollection);
 }
 
 // Tests dropping a tabs from the tab group view in the grid.
@@ -854,6 +871,7 @@
   drag_item.localObject = local_object;
   [mediator_ dropItem:drag_item toIndex:1 fromSameCollection:NO];
   EXPECT_EQ("| a* d b c [ 0 e f ] g", builder.GetWebStateListDescription());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kSameBrowser, 1);
 
   // Drop "E" (in a group) before "G".
   web_state_id = web_state_list->GetWebStateAt(4)->GetUniqueIdentifier();
@@ -865,6 +883,7 @@
   drag_item.localObject = local_object;
   [mediator_ dropItem:drag_item toIndex:5 fromSameCollection:NO];
   EXPECT_EQ("| a* d b c [ 0 f ] e g", builder.GetWebStateListDescription());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kSameBrowser, 2);
 }
 
 // Tests dropping a tab from another browser (e.g. drag from another window) in
@@ -904,6 +923,7 @@
   EXPECT_EQ(4, web_state_list->count());
   EXPECT_EQ(0, other_browser->GetWebStateList()->count());
   EXPECT_EQ(url_to_load, web_state_list->GetWebStateAt(1)->GetVisibleURL());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kOtherBrowser);
 }
 
 // Tests dropping a local Tab Group (i.e. from the same window).
@@ -933,6 +953,7 @@
   [mediator_ dropItem:drag_item toIndex:1 fromSameCollection:YES];
 
   EXPECT_EQ("| [ 1 a* b ] [ 2 d e ] c", builder.GetWebStateListDescription());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kSameCollection);
 }
 
 // TODO:(crbug.com/346293139): Re-enable this test.
@@ -961,7 +982,8 @@
   GURL url_to_load = GURL(kDraggedUrl);
   other_browser->GetWebStateList()->InsertWebState(
       CreateFakeWebStateWithURL(url_to_load));
-  other_browser->GetWebStateList()->CreateGroup({0}, {});
+  other_browser->GetWebStateList()->CreateGroup({0}, {},
+                                                TabGroupId::GenerateNew());
 
   const TabGroup* other_tab_group =
       other_browser->GetWebStateList()->GetGroupOfWebStateAt(0);
@@ -979,6 +1001,7 @@
 
   EXPECT_EQ(nullptr, web_state_list->GetGroupOfWebStateAt(2));
   EXPECT_EQ(other_tab_group, web_state_list->GetGroupOfWebStateAt(3));
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kOtherBrowser);
 }
 
 // Tests dropping an interal URL (e.g. drag from omnibox) in the grid.
@@ -1003,6 +1026,7 @@
   web::WebState* web_state = web_state_list->GetWebStateAt(1);
   EXPECT_EQ(url_to_load,
             web_state->GetNavigationManager()->GetPendingItem()->GetURL());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kOther);
 }
 
 // Tests dropping an external URL in the grid.
@@ -1029,6 +1053,7 @@
   web::WebState* web_state = web_state_list->GetWebStateAt(1);
   EXPECT_EQ(GURL(kDraggedUrl),
             web_state->GetNavigationManager()->GetPendingItem()->GetURL());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kOther);
 }
 
 INSTANTIATE_TEST_SUITE_P(
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_utils_unittest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_utils_unittest.mm
index 7473ba7..989f10c 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_utils_unittest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_utils_unittest.mm
@@ -8,6 +8,7 @@
 #import "base/numerics/safe_conversions.h"
 #import "base/test/scoped_feature_list.h"
 #import "components/tab_groups/tab_group_color.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "ios/chrome/browser/shared/model/browser/test/test_browser.h"
 #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
 #import "ios/chrome/browser/shared/model/web_state_list/tab_group.h"
@@ -23,6 +24,7 @@
 #import "testing/platform_test.h"
 #import "ui/base/device_form_factor.h"
 
+using tab_groups::TabGroupId;
 using tab_groups::TabGroupVisualData;
 
 class GridUtilsTest : public PlatformTest {
@@ -109,8 +111,10 @@
   TabGroupVisualData visual_data_b =
       TabGroupVisualData(u"Group B", tab_groups::TabGroupColorId::kRed);
 
-  web_state_list_->CreateGroup({0, 1, 2}, visual_data_a);
-  web_state_list_->CreateGroup({5, 6}, visual_data_b);
+  web_state_list_->CreateGroup({0, 1, 2}, visual_data_a,
+                               TabGroupId::GenerateNew());
+  web_state_list_->CreateGroup({5, 6}, visual_data_b,
+                               TabGroupId::GenerateNew());
 
   NSArray<GridItemIdentifier*>* itemsList = CreateItems(web_state_list_);
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/BUILD.gn
index 25e0f8b..9f330b90 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/BUILD.gn
@@ -199,6 +199,7 @@
     ":tab_groups_commands",
     ":tab_groups_ui",
     "//base/test:test_support",
+    "//components/tab_groups",
     "//ios/chrome/browser/drag_and_drop/model",
     "//ios/chrome/browser/main/model",
     "//ios/chrome/browser/shared/model/browser",
@@ -209,6 +210,7 @@
     "//ios/chrome/browser/shared/public/commands",
     "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/snapshots/model",
+    "//ios/chrome/browser/ui/tab_switcher",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid/grid:test_fixture",
     "//ios/chrome/browser/ui/tab_switcher/test:fakes",
     "//ios/web/public/test/fakes",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_mediator.mm
index 545f626..fa7d3bc 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_mediator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_mediator.mm
@@ -148,7 +148,8 @@
       }
     }
     if (!tabIndexes.empty()) {
-      _webStateList->CreateGroup(tabIndexes, visualData);
+      _webStateList->CreateGroup(tabIndexes, visualData,
+                                 tab_groups::TabGroupId::GenerateNew());
     }
   }
   completion();
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_view_controller.mm
index 1bcad00d0b..df463786 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_view_controller.mm
@@ -65,10 +65,6 @@
 const CGFloat kButtonsMargin = 8;
 const CGFloat kButtonBackgroundCornerRadius = 15;
 
-// Threshold for considering whether the displayed keyboard is a toolbar or the
-// virtual keyboard.
-const CGFloat kKeyboardToolbarHeightThreshold = 70;
-
 // Clear button constants.
 const CGFloat kClearButtonAlpha = 0.34;
 const CGFloat kClearButtonSize = 20;
@@ -108,10 +104,6 @@
   // are displayed.
   NSArray<NSLayoutConstraint*>* _singleSnapshotConstraints;
   NSArray<NSLayoutConstraint*>* _multipleSnapshotsConstraints;
-  // Constraints for the top anchor of the `_colorsScrollView`, depending on if
-  // the `_snapshotsView` is displayed.
-  NSLayoutConstraint* _snapshotsViewDisplayedConstraint;
-  NSLayoutConstraint* _snapshotsViewHiddenConstraint;
 
   // Buttons to create or cancel the group creation.
   UIButton* _creationButton;
@@ -125,9 +117,6 @@
 
   // Scrollview that containts color selection buttons.
   UIView* _colorsScrollView;
-
-  // YES if the visual keyboard is displayed.
-  BOOL _keyboardDisplayed;
 }
 
 - (instancetype)initWithEditMode:(BOOL)editMode
@@ -168,29 +157,13 @@
   [_selectedButton setSelected:YES];
 
   [self createConfigurations];
-  [self updateViews];
+  [self updateViews:self.view previousTraitCollection:nil];
 
   if (@available(iOS 17, *)) {
     [self registerForTraitChanges:@[ UITraitVerticalSizeClass.self ]
-                       withAction:@selector(updateViews)];
+                       withAction:@selector(updateViews:
+                                      previousTraitCollection:)];
   }
-  [[NSNotificationCenter defaultCenter]
-      addObserver:self
-         selector:@selector(keyboardDidShow:)
-             name:UIKeyboardDidShowNotification
-           object:nil];
-  [[NSNotificationCenter defaultCenter]
-      addObserver:self
-         selector:@selector(keyboardDidHide:)
-             name:UIKeyboardDidHideNotification
-           object:nil];
-
-  // Force-hide the snapshots on iPad by simulating a visible virtual keyboard.
-  // The keyboard will appear when the view controller is presented, so this
-  // avoids having the snapshots visible by default.
-  _keyboardDisplayed = YES;
-  [self hideSnapshotsIfNeeded:NO];
-  _keyboardDisplayed = NO;
 
   // To force display the keyboard when the view is shown.
   [_tabGroupTextField becomeFirstResponder];
@@ -207,7 +180,8 @@
   }
   if (self.traitCollection.verticalSizeClass !=
       previousTraitCollection.verticalSizeClass) {
-    [self updateViews];
+    [self updateViews:self.view
+        previousTraitCollection:previousTraitCollection];
   }
 }
 
@@ -235,9 +209,12 @@
                   action:@selector(clearTextField)
         forControlEvents:UIControlEventTouchUpInside];
 
+  NSLayoutConstraint* buttonWidth = [clearButton.widthAnchor
+      constraintEqualToConstant:kClearButtonWidthAndHeight];
+  buttonWidth.priority = UILayoutPriorityDefaultHigh;
+
   [NSLayoutConstraint activateConstraints:@[
-    [clearButton.widthAnchor
-        constraintEqualToConstant:kClearButtonWidthAndHeight],
+    buttonWidth,
     [clearButton.heightAnchor constraintEqualToAnchor:clearButton.widthAnchor],
   ]];
 
@@ -580,97 +557,71 @@
 }
 
 // Updates all the view and subviews depending on space available.
-- (void)updateViews {
-  _cancelButton.hidden = NO;
-  _creationButton.hidden = NO;
-  _cancelButtonCompact.hidden = NO;
-  _creationButtonCompact.hidden = NO;
+- (void)updateViews:(UIView*)updatedView
+    previousTraitCollection:(UITraitCollection*)previousTraitCollection {
+  if (previousTraitCollection.verticalSizeClass ==
+      self.traitCollection.verticalSizeClass) {
+    return;
+  }
+  NSArray<UIView*>* toHide;
+  NSArray<UIView*>* toDisplay;
 
   BOOL isVerticallyCompacted =
       self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact;
   if (isVerticallyCompacted) {
-    _cancelButton.hidden = YES;
-    _creationButton.hidden = YES;
+    toHide = @[ _cancelButton, _creationButton ];
+    toDisplay = @[ _cancelButtonCompact, _creationButtonCompact ];
     [NSLayoutConstraint deactivateConstraints:_regularConstraints];
     [NSLayoutConstraint activateConstraints:_compactConstraints];
   } else {
-    _cancelButtonCompact.hidden = YES;
-    _creationButtonCompact.hidden = YES;
+    toHide = @[ _cancelButtonCompact, _creationButtonCompact ];
+    toDisplay = @[ _cancelButton, _creationButton ];
     [NSLayoutConstraint deactivateConstraints:_compactConstraints];
     [NSLayoutConstraint activateConstraints:_regularConstraints];
   }
 
-  [self.view layoutIfNeeded];
-  [self hideSnapshotsIfNeeded:YES];
+  for (UIView* view in toDisplay) {
+    view.hidden = NO;
+    view.alpha = 0;
+  }
+  __weak __typeof(self) weakSelf = self;
+  [UIView animateWithDuration:kSnapshotViewAnimationTime
+      animations:^{
+        for (UIView* view in toHide) {
+          view.alpha = 0;
+        }
+        for (UIView* view in toDisplay) {
+          view.alpha = 1;
+        }
+        [weakSelf.view layoutIfNeeded];
+        [weakSelf hideSnapshotsIfNeeded];
+      }
+      completion:^(BOOL finished) {
+        for (UIView* view in toHide) {
+          view.hidden = YES;
+        }
+      }];
+
   // To force display the keyboard.
   [_tabGroupTextField becomeFirstResponder];
 }
 
 // Hides the snapshots container depending on some conditions.
-- (void)hideSnapshotsIfNeeded:(BOOL)animated {
-  BOOL tooSmall = _snapshotsContainer.frame.size.height < 60;
+- (void)hideSnapshotsIfNeeded {
+  BOOL tooSmall = _snapshotsContainer.frame.size.height < 100;
   BOOL isVerticallyCompacted =
       self.traitCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact;
 
-  const UIDeviceOrientation deviceOrientation =
-      [[UIDevice currentDevice] orientation];
-  BOOL isInLandscape = deviceOrientation == UIDeviceOrientationLandscapeRight ||
-                       deviceOrientation == UIDeviceOrientationLandscapeLeft;
-  BOOL isIpadConfiguration =
-      (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) &&
-      _keyboardDisplayed;
-  BOOL isIpadInLandscapeWithKeyboard = isIpadConfiguration && isInLandscape;
-
   // The snapshots container should not be displayed in the following
   // scenarios:
   // - When the container lacks sufficient space.
   // - On devices with a vertically compact form factor.
-  // - iPad in landscape orientation with the virtual keyboard visible.
-  CGFloat updatedAlpha =
-      (tooSmall || isVerticallyCompacted || isIpadInLandscapeWithKeyboard) ? 0
-                                                                           : 1;
+  CGFloat updatedAlpha = (tooSmall || isVerticallyCompacted) ? 0 : 1;
   if (_snapshotsContainer.alpha == updatedAlpha) {
     return;
   }
 
-  __weak __typeof(self) weakSelf = self;
-  [UIView
-      animateWithDuration:animated ? kSnapshotViewAnimationTime : 0
-               animations:^{
-                 [weakSelf hideSnapshotsIfNeededAnimationBlock:updatedAlpha];
-               }];
-}
-
-// Animation block for the `hideSnapshotsIfNeeded:` method.
-- (void)hideSnapshotsIfNeededAnimationBlock:(CGFloat)updatedAlpha {
   [_snapshotsContainer setAlpha:updatedAlpha];
-
-  if (updatedAlpha != 1) {
-    _snapshotsViewDisplayedConstraint.active = NO;
-    _snapshotsViewHiddenConstraint.active = YES;
-  } else {
-    _snapshotsViewHiddenConstraint.active = NO;
-    _snapshotsViewDisplayedConstraint.active = YES;
-  }
-  [self.view layoutIfNeeded];
-}
-
-// Called when the virtual keyboard is shown.
-- (void)keyboardDidShow:(NSNotification*)notification {
-  CGRect keyboardFrameEnd = [[[notification userInfo]
-      objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
-  // If the `keyboardFrameEnd` height is below the threshold, that means we are
-  // only displaying the keyboard toolbar.
-  _keyboardDisplayed =
-      keyboardFrameEnd.size.height > kKeyboardToolbarHeightThreshold;
-
-  [self hideSnapshotsIfNeeded:YES];
-}
-
-// Called when the virtual keyboard is hidden.
-- (void)keyboardDidHide:(NSNotification*)notification {
-  _keyboardDisplayed = NO;
-  [self hideSnapshotsIfNeeded:YES];
 }
 
 // Configures the view and all subviews when there is enough space.
@@ -712,79 +663,37 @@
       constraintEqualToAnchor:self.view.keyboardLayoutGuide.topAnchor];
   keyboardConstraint.priority = UILayoutPriorityDefaultHigh + 1;
 
-  _snapshotsViewDisplayedConstraint = [_colorsScrollView.topAnchor
-      constraintEqualToAnchor:snapshotsContainerLayoutGuide.bottomAnchor
-                     constant:kSnapshotViewVerticalMargin];
-  _snapshotsViewDisplayedConstraint.priority = UILayoutPriorityRequired - 1;
-  _snapshotsViewHiddenConstraint = [_colorsScrollView.topAnchor
-      constraintEqualToAnchor:dotAndFieldContainer.bottomAnchor
-                     constant:kSnapshotViewVerticalMargin];
+  NSLayoutConstraint* snapshotLayoutGuideConstraint =
+      [snapshotsContainerLayoutGuide.bottomAnchor
+          constraintEqualToAnchor:_colorsScrollView.topAnchor
+                         constant:-kSnapshotViewVerticalMargin];
+  snapshotLayoutGuideConstraint.priority = UILayoutPriorityDefaultLow;
 
   _regularConstraints = @[
-    _snapshotsViewDisplayedConstraint,
     [dotAndFieldContainer.leadingAnchor
         constraintGreaterThanOrEqualToAnchor:container.leadingAnchor
                                     constant:kHorizontalMargin],
     [dotAndFieldContainer.trailingAnchor
         constraintLessThanOrEqualToAnchor:container.trailingAnchor
                                  constant:-kHorizontalMargin],
-    [_creationButton.bottomAnchor
-        constraintEqualToAnchor:_cancelButton.topAnchor],
-    [_cancelButton.bottomAnchor constraintEqualToAnchor:container.bottomAnchor
-                                               constant:-kButtonsMargin],
-    [_creationButton.topAnchor
-        constraintEqualToAnchor:_colorsScrollView.bottomAnchor
-                       constant:kColorListBottomMargin],
-
-    [snapshotsContainerLayoutGuide.topAnchor
-        constraintEqualToAnchor:viewAboveSnapshots.bottomAnchor
-                       constant:kSnapshotViewVerticalMargin],
-
-    [_snapshotsContainer.centerXAnchor
-        constraintEqualToAnchor:snapshotsContainerLayoutGuide.centerXAnchor],
-    [_snapshotsContainer.centerYAnchor
-        constraintEqualToAnchor:snapshotsContainerLayoutGuide.centerYAnchor],
-    [_snapshotsContainer.topAnchor
-        constraintGreaterThanOrEqualToAnchor:snapshotsContainerLayoutGuide
-                                                 .topAnchor],
-    [_snapshotsContainer.bottomAnchor
-        constraintLessThanOrEqualToAnchor:snapshotsContainerLayoutGuide
-                                              .bottomAnchor],
-    [snapshotsContainerLayoutGuide.widthAnchor
-        constraintEqualToAnchor:dotAndFieldContainer.widthAnchor],
     [_creationButton.widthAnchor
         constraintEqualToAnchor:dotAndFieldContainer.widthAnchor],
     [_cancelButton.widthAnchor
         constraintEqualToAnchor:dotAndFieldContainer.widthAnchor],
-
-    [snapshotsContainerLayoutGuide.centerXAnchor
-        constraintEqualToAnchor:self.view.centerXAnchor],
-    [_creationButton.centerXAnchor
-        constraintEqualToAnchor:self.view.centerXAnchor],
-    [_cancelButton.centerXAnchor
-        constraintEqualToAnchor:self.view.centerXAnchor],
+    [_cancelButton.bottomAnchor constraintEqualToAnchor:container.bottomAnchor
+                                               constant:-kButtonsMargin],
   ];
 
   _compactConstraints = @[
-    [_cancelButtonCompact.leadingAnchor
-        constraintEqualToAnchor:container.leadingAnchor
-                       constant:kHorizontalMargin],
+
     [_cancelButtonCompact.trailingAnchor
         constraintLessThanOrEqualToAnchor:dotAndFieldContainer.leadingAnchor],
-    [_cancelButtonCompact.topAnchor
-        constraintEqualToAnchor:container.topAnchor
-                       constant:kDotAndFieldContainerMargin],
     [_creationButtonCompact.leadingAnchor
         constraintGreaterThanOrEqualToAnchor:dotAndFieldContainer
                                                  .trailingAnchor],
-    [_creationButtonCompact.trailingAnchor
-        constraintEqualToAnchor:container.trailingAnchor
-                       constant:-kHorizontalMargin],
-    [_creationButtonCompact.topAnchor
-        constraintEqualToAnchor:container.topAnchor
-                       constant:kDotAndFieldContainerMargin],
     [_colorsScrollView.bottomAnchor
-        constraintEqualToAnchor:container.bottomAnchor],
+        constraintEqualToAnchor:container.bottomAnchor
+                       constant:-kColorListBottomMargin],
   ];
 
   NSLayoutConstraint* dotAndFieldWidth = [dotAndFieldContainer.widthAnchor
@@ -814,6 +723,49 @@
     [container.trailingAnchor
         constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor],
     [container.heightAnchor constraintLessThanOrEqualToConstant:kMaxHeight],
+
+    [_creationButton.centerXAnchor
+        constraintEqualToAnchor:self.view.centerXAnchor],
+    [_cancelButton.centerXAnchor
+        constraintEqualToAnchor:self.view.centerXAnchor],
+    [_creationButton.bottomAnchor
+        constraintEqualToAnchor:_cancelButton.topAnchor],
+    [_creationButton.topAnchor
+        constraintEqualToAnchor:_colorsScrollView.bottomAnchor
+                       constant:kColorListBottomMargin],
+
+    [_cancelButtonCompact.leadingAnchor
+        constraintEqualToAnchor:container.leadingAnchor
+                       constant:kHorizontalMargin],
+    [_creationButtonCompact.trailingAnchor
+        constraintEqualToAnchor:container.trailingAnchor
+                       constant:-kHorizontalMargin],
+    [_cancelButtonCompact.topAnchor
+        constraintEqualToAnchor:container.topAnchor
+                       constant:kDotAndFieldContainerMargin],
+    [_creationButtonCompact.topAnchor
+        constraintEqualToAnchor:container.topAnchor
+                       constant:kDotAndFieldContainerMargin],
+
+    [snapshotsContainerLayoutGuide.centerXAnchor
+        constraintEqualToAnchor:self.view.centerXAnchor],
+    [snapshotsContainerLayoutGuide.topAnchor
+        constraintEqualToAnchor:viewAboveSnapshots.bottomAnchor
+                       constant:kSnapshotViewVerticalMargin],
+    [snapshotsContainerLayoutGuide.widthAnchor
+        constraintEqualToAnchor:dotAndFieldContainer.widthAnchor],
+    snapshotLayoutGuideConstraint,
+
+    [_snapshotsContainer.centerXAnchor
+        constraintEqualToAnchor:snapshotsContainerLayoutGuide.centerXAnchor],
+    [_snapshotsContainer.centerYAnchor
+        constraintEqualToAnchor:snapshotsContainerLayoutGuide.centerYAnchor],
+    [_snapshotsContainer.heightAnchor
+        constraintLessThanOrEqualToAnchor:snapshotsContainerLayoutGuide
+                                              .heightAnchor],
+    [_snapshotsContainer.widthAnchor
+        constraintLessThanOrEqualToAnchor:snapshotsContainerLayoutGuide
+                                              .widthAnchor],
     keyboardConstraint,
   ]];
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_coordinator_unittest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_coordinator_unittest.mm
index 06d33f58..9877328 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_coordinator_unittest.mm
@@ -6,6 +6,7 @@
 
 #import "base/test/scoped_feature_list.h"
 #import "base/test/task_environment.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "ios/chrome/browser/shared/model/browser/test/test_browser.h"
 #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
 #import "ios/chrome/browser/shared/model/web_state_list/tab_group.h"
@@ -20,6 +21,8 @@
 #import "testing/platform_test.h"
 #import "third_party/ocmock/OCMock/OCMock.h"
 
+using tab_groups::TabGroupId;
+
 // Fake WebStateList delegate that attaches the required tab helper.
 class TabGroupCoordinatorFakeWebStateListDelegate
     : public FakeWebStateListDelegate {
@@ -60,8 +63,8 @@
     web_state_list->InsertWebState(
         std::make_unique<web::FakeWebState>(web::WebStateID::NewUnique()),
         WebStateList::InsertionParams::Automatic().Activate());
-    const TabGroup* group =
-        web_state_list->CreateGroup({0}, temporaryVisualData);
+    const TabGroup* group = web_state_list->CreateGroup(
+        {0}, temporaryVisualData, TabGroupId::GenerateNew());
 
     coordinator_ = [[TabGroupCoordinator alloc]
         initWithBaseViewController:base_view_controller_
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_mediator.mm
index 0d352a6..206325b7 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_mediator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_mediator.mm
@@ -224,7 +224,7 @@
             .InGroup(_tabGroup.get());
     if (sourceWebStateIndex == WebStateList::kInvalidIndex) {
       base::UmaHistogramEnumeration(kUmaGroupViewDragOrigin,
-                                    DragItemOrigin::kOtherBrwoser);
+                                    DragItemOrigin::kOtherBrowser);
       MoveTabToBrowser(tabInfo.tabID, self.browser, insertionParams);
       return;
     }
@@ -233,14 +233,17 @@
       base::UmaHistogramEnumeration(kUmaGroupViewDragOrigin,
                                     DragItemOrigin::kSameCollection);
     } else {
-      base::UmaHistogramEnumeration(kUmaGridViewDragOrigin,
+      base::UmaHistogramEnumeration(kUmaGroupViewDragOrigin,
                                     DragItemOrigin::kSameBrowser);
     }
 
+    // Reorder tabs.
     MoveWebStateWithIdentifierToInsertionParams(
         tabInfo.tabID, insertionParams, webStateList, fromSameCollection);
     return;
   }
+  base::UmaHistogramEnumeration(kUmaGroupViewDragOrigin,
+                                DragItemOrigin::kOther);
 
   // Handle URLs from within Chrome synchronously using a local object.
   if ([dragItem.localObject isKindOfClass:[URLInfo class]]) {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_mediator_unittest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_mediator_unittest.mm
index 8ff55f1c..70a1a25 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_mediator_unittest.mm
@@ -7,6 +7,7 @@
 #import <memory>
 
 #import "base/test/ios/wait_util.h"
+#import "base/test/metrics/histogram_tester.h"
 #import "base/test/scoped_feature_list.h"
 #import "ios/chrome/browser/drag_and_drop/model/drag_item_util.h"
 #import "ios/chrome/browser/main/model/browser_web_state_list_delegate.h"
@@ -19,6 +20,7 @@
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/snapshots/model/snapshot_browser_agent.h"
+#import "ios/chrome/browser/ui/tab_switcher/tab_collection_drag_drop_metrics.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_mediator_test.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_consumer.h"
 #import "ios/chrome/browser/ui/tab_switcher/test/fake_tab_collection_consumer.h"
@@ -61,12 +63,20 @@
     GridMediatorTestClass::TearDown();
   }
 
+  // Checks that the drag item origin metric is logged in UMA.
+  void ExpectThatDragItemOriginMetricLogged(DragItemOrigin origin,
+                                            int count = 1) {
+    histogram_tester_.ExpectUniqueSample(kUmaGroupViewDragOrigin, origin,
+                                         count);
+  }
+
  protected:
   TabGroupMediator* mediator_;
   id<TabGroupConsumer> tab_group_consumer_;
   const TabGroup* tab_group_;
   std::unique_ptr<WebStateListBuilderFromDescription> builder_;
   base::test::ScopedFeatureList scoped_feature_list_;
+  base::HistogramTester histogram_tester_;
 };
 
 // Tests dropping a local tab (e.g. drag from same window) in the grid.
@@ -88,6 +98,7 @@
   [mediator_ dropItem:drag_item toIndex:1 fromSameCollection:YES];
 
   EXPECT_EQ("| f [ 1 a* d b c ] e", builder_->GetWebStateListDescription());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kSameCollection);
 }
 
 // Tests dropping tabs from the grid to a tab group.
@@ -106,6 +117,7 @@
   drag_item.localObject = local_object;
   [mediator_ dropItem:drag_item toIndex:0 fromSameCollection:NO];
   EXPECT_EQ("| [ 1 f a* b c ] d e", builder_->GetWebStateListDescription());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kSameBrowser, 1);
 
   // Drop "D" before "B".
   web_state_id = web_state_list->GetWebStateAt(4)->GetUniqueIdentifier();
@@ -117,6 +129,7 @@
   drag_item.localObject = local_object;
   [mediator_ dropItem:drag_item toIndex:2 fromSameCollection:NO];
   EXPECT_EQ("| [ 1 f a* d b c ] e", builder_->GetWebStateListDescription());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kSameBrowser, 2);
 }
 
 // Tests dropping a tab from another browser (e.g. drag from another window) in
@@ -153,6 +166,7 @@
   EXPECT_EQ(0, other_browser->GetWebStateList()->count());
   EXPECT_EQ(url_to_load, web_state_list->GetWebStateAt(4)->GetVisibleURL());
   EXPECT_EQ(tab_group_, web_state_list->GetGroupOfWebStateAt(4));
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kOtherBrowser);
 }
 
 // Tests dropping an interal URL (e.g. drag from omnibox) in the grid.
@@ -168,13 +182,14 @@
   drag_item.localObject = local_object;
 
   // Drop item.
-  [mediator_ dropItem:drag_item toIndex:1 fromSameCollection:YES];
+  [mediator_ dropItem:drag_item toIndex:1 fromSameCollection:NO];
 
   EXPECT_EQ(7, web_state_list->count());
   web::WebState* web_state = web_state_list->GetWebStateAt(2);
   EXPECT_EQ(url_to_load,
             web_state->GetNavigationManager()->GetPendingItem()->GetURL());
   EXPECT_EQ(tab_group_, web_state_list->GetGroupOfWebStateAt(2));
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kOther);
 }
 
 // Tests dropping an external URL in the grid.
@@ -198,4 +213,5 @@
   EXPECT_EQ(GURL("https://dragged_url.com"),
             web_state->GetNavigationManager()->GetPendingItem()->GetURL());
   EXPECT_EQ(tab_group_, web_state_list->GetGroupOfWebStateAt(2));
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kOther);
 }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_mediator.mm
index 436ce76..ae2a740 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_mediator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_mediator.mm
@@ -360,56 +360,50 @@
 - (void)dropItem:(UIDragItem*)dragItem
                toIndex:(NSUInteger)destinationIndex
     fromSameCollection:(BOOL)fromSameCollection {
+  WebStateList* webStateList = self.webStateList;
+
   // Tab move operations only originate from Chrome so a local object is used.
   // Local objects allow synchronous drops, whereas NSItemProvider only allows
   // asynchronous drops.
   if ([dragItem.localObject isKindOfClass:[TabInfo class]]) {
     TabInfo* tabInfo = static_cast<TabInfo*>(dragItem.localObject);
-    if (!fromSameCollection) {
-      // Try to pin the tab. If the returned index is invalid that means the
-      // tab lives in another Browser.
-      int tabIndex = SetWebStatePinnedState(self.webStateList, tabInfo.tabID,
-                                            /*pin_state=*/true);
-      if (tabIndex == WebStateList::kInvalidIndex) {
-        BrowserList* browserList =
-            BrowserListFactory::GetForBrowserState(self.browserState);
-        BrowserAndIndex tabBrowserAndIndex = FindBrowserAndIndex(
-            tabInfo.tabID, browserList->AllRegularBrowsers());
-        if (!tabBrowserAndIndex.browser) {
-          // This could happen if the tab is deleted during a drag-and-drop
-          // action.
-          return;
-        }
 
-        // Move tab across Browsers.
-        base::UmaHistogramEnumeration(kUmaPinnedViewDragOrigin,
-                                      DragItemOrigin::kOtherBrwoser);
-        const WebStateList::InsertionParams params =
-            WebStateList::InsertionParams::AtIndex(destinationIndex).Pinned();
-        MoveTabToBrowser(tabInfo.tabID, self.browser, params);
-        return;
-      }
-      base::UmaHistogramEnumeration(kUmaPinnedViewDragOrigin,
-                                    DragItemOrigin::kSameBrowser);
-    } else {
-      base::UmaHistogramEnumeration(kUmaPinnedViewDragOrigin,
-                                    DragItemOrigin::kSameCollection);
-    }
+    // Try to pin the tab, if pinned nothing happens.
+    SetWebStatePinnedState(webStateList, tabInfo.tabID,
+                           /*pin_state=*/true);
 
-    // Reorder tabs.
-    int sourceIndex = GetWebStateIndex(self.webStateList,
-                                       WebStateSearchCriteria{
+    int sourceWebStateIndex =
+        GetWebStateIndex(webStateList, WebStateSearchCriteria{
                                            .identifier = tabInfo.tabID,
                                            .pinned_state = PinnedState::kPinned,
                                        });
-    if (sourceIndex != WebStateList::kInvalidIndex &&
-        destinationIndex != NSNotFound &&
-        static_cast<int>(destinationIndex) <
-            self.webStateList->pinned_tabs_count()) {
-      self.webStateList->MoveWebStateAt(sourceIndex, destinationIndex);
+
+    if (sourceWebStateIndex == WebStateList::kInvalidIndex) {
+      // Move tab across Browsers.
+      base::UmaHistogramEnumeration(kUmaPinnedViewDragOrigin,
+                                    DragItemOrigin::kOtherBrowser);
+      const WebStateList::InsertionParams params =
+          WebStateList::InsertionParams::AtIndex(destinationIndex).Pinned();
+      MoveTabToBrowser(tabInfo.tabID, self.browser, params);
+      return;
     }
+
+    if (fromSameCollection) {
+      base::UmaHistogramEnumeration(kUmaPinnedViewDragOrigin,
+                                    DragItemOrigin::kSameCollection);
+    } else {
+      base::UmaHistogramEnumeration(kUmaPinnedViewDragOrigin,
+                                    DragItemOrigin::kSameBrowser);
+    }
+
+    // Reorder tabs.
+    const auto insertionParams =
+        WebStateList::InsertionParams::AtIndex(destinationIndex);
+    MoveWebStateWithIdentifierToInsertionParams(
+        tabInfo.tabID, insertionParams, webStateList, fromSameCollection);
     return;
   }
+
   base::UmaHistogramEnumeration(kUmaPinnedViewDragOrigin,
                                 DragItemOrigin::kOther);
 
@@ -429,6 +423,8 @@
     [placeholderContext deletePlaceholder];
     return;
   }
+  base::UmaHistogramEnumeration(kUmaPinnedViewDragOrigin,
+                                DragItemOrigin::kOther);
 
   __weak __typeof(self) weakSelf = self;
   auto loadHandler =
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/tests/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/tests/BUILD.gn
index 56234785..5d03ab25 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/tests/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/tests/BUILD.gn
@@ -38,6 +38,7 @@
     "//ios/chrome/browser/shared/model/browser/test:test_support",
     "//ios/chrome/browser/shared/model/browser_state:test_support",
     "//ios/chrome/browser/shared/model/web_state_list",
+    "//ios/chrome/browser/shared/model/web_state_list/test:test_support",
     "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/ui/tab_switcher",
     "//ios/chrome/browser/ui/tab_switcher:items",
@@ -45,6 +46,7 @@
     "//ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs:pinned_tabs_ui",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid/transitions",
     "//ios/chrome/browser/ui/tab_switcher/test:fakes",
+    "//ios/web/public/test",
     "//ios/web/public/test/fakes",
     "//third_party/ocmock",
   ]
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/tests/pinned_tabs_mediator_unittest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/tests/pinned_tabs_mediator_unittest.mm
index fcf0206..4849711 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/tests/pinned_tabs_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/tests/pinned_tabs_mediator_unittest.mm
@@ -2,26 +2,30 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import <UIKit/UIKit.h>
-
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_mediator.h"
 
+#import <UIKit/UIKit.h>
+
 #import "base/memory/raw_ptr.h"
+#import "base/test/ios/wait_util.h"
+#import "base/test/metrics/histogram_tester.h"
 #import "base/test/scoped_feature_list.h"
-#import "base/test/task_environment.h"
 #import "ios/chrome/browser/drag_and_drop/model/drag_item_util.h"
 #import "ios/chrome/browser/shared/model/browser/browser_list.h"
 #import "ios/chrome/browser/shared/model/browser/browser_list_factory.h"
 #import "ios/chrome/browser/shared/model/browser/test/test_browser.h"
 #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
+#import "ios/chrome/browser/shared/model/web_state_list/test/web_state_list_builder_from_description.h"
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_opener.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
+#import "ios/chrome/browser/ui/tab_switcher/tab_collection_drag_drop_metrics.h"
 #import "ios/chrome/browser/ui/tab_switcher/test/fake_drag_session.h"
 #import "ios/chrome/browser/ui/tab_switcher/test/fake_drop_session.h"
 #import "ios/chrome/browser/ui/tab_switcher/test/fake_pinned_tab_collection_consumer.h"
 #import "ios/web/public/test/fakes/fake_navigation_manager.h"
 #import "ios/web/public/test/fakes/fake_web_state.h"
+#import "ios/web/public/test/web_task_environment.h"
 #import "testing/platform_test.h"
 #import "third_party/ocmock/OCMock/OCMock.h"
 #import "ui/base/device_form_factor.h"
@@ -83,14 +87,22 @@
     return web_state;
   }
 
+  // Checks that the drag item origin metric is logged in UMA.
+  void ExpectThatDragItemOriginMetricLogged(DragItemOrigin origin,
+                                            int count = 1) {
+    histogram_tester_.ExpectUniqueSample(kUmaPinnedViewDragOrigin, origin,
+                                         count);
+  }
+
  protected:
   std::unique_ptr<TestBrowser> regular_browser_;
   std::unique_ptr<Browser> incognito_browser_;
   FakePinnedTabCollectionConsumer* consumer_;
   PinnedTabsMediator* mediator_;
+  base::HistogramTester histogram_tester_;
 
  private:
-  base::test::TaskEnvironment task_environment_;
+  web::WebTaskEnvironment task_environment_;
   base::test::ScopedFeatureList feature_list_;
   raw_ptr<BrowserList> browser_list_;
   std::unique_ptr<TestChromeBrowserState> browser_state_;
@@ -196,3 +208,169 @@
   EXPECT_EQ(web_state_to_move,
             regular_browser_->GetWebStateList()->GetWebStateAt(2));
 }
+
+// Tests dropping pinned tabs.
+TEST_F(PinnedTabsMediatorTest, DropPinnedTabs) {
+  // The Pinned Tabs feature is not available on iPad.
+  if (!IsPinnedTabsEnabled()) {
+    return;
+  }
+
+  WebStateList* web_state_list = regular_browser_->GetWebStateList();
+  CloseAllWebStates(*web_state_list, WebStateList::CLOSE_NO_FLAGS);
+  WebStateListBuilderFromDescription builder(web_state_list);
+  ASSERT_TRUE(builder.BuildWebStateListFromDescription(
+      "a* b c | d e f", regular_browser_->GetBrowserState()));
+
+  // Drop "A" after "C".
+  web::WebStateID web_state_id =
+      web_state_list->GetWebStateAt(0)->GetUniqueIdentifier();
+  id local_object = [[TabInfo alloc]
+      initWithTabID:web_state_id
+          incognito:regular_browser_->GetBrowserState()->IsOffTheRecord()];
+  NSItemProvider* item_provider = [[NSItemProvider alloc] init];
+  UIDragItem* drag_item =
+      [[UIDragItem alloc] initWithItemProvider:item_provider];
+  drag_item.localObject = local_object;
+  [mediator_ dropItem:drag_item toIndex:2 fromSameCollection:YES];
+  EXPECT_EQ("b c a* | d e f", builder.GetWebStateListDescription());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kSameCollection, 1);
+
+  // Drop "C" before "B".
+  web_state_id = web_state_list->GetWebStateAt(1)->GetUniqueIdentifier();
+  local_object = [[TabInfo alloc]
+      initWithTabID:web_state_id
+          incognito:regular_browser_->GetBrowserState()->IsOffTheRecord()];
+  item_provider = [[NSItemProvider alloc] init];
+  drag_item = [[UIDragItem alloc] initWithItemProvider:item_provider];
+  drag_item.localObject = local_object;
+  [mediator_ dropItem:drag_item toIndex:0 fromSameCollection:YES];
+  EXPECT_EQ("c b a* | d e f", builder.GetWebStateListDescription());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kSameCollection, 2);
+}
+
+// Tests dropping regular tabs .
+TEST_F(PinnedTabsMediatorTest, DropRegularTabs) {
+  // The Pinned Tabs feature is not available on iPad.
+  if (!IsPinnedTabsEnabled()) {
+    return;
+  }
+
+  WebStateList* web_state_list = regular_browser_->GetWebStateList();
+  CloseAllWebStates(*web_state_list, WebStateList::CLOSE_NO_FLAGS);
+  WebStateListBuilderFromDescription builder(web_state_list);
+  ASSERT_TRUE(builder.BuildWebStateListFromDescription(
+      "a* b c | d e f", regular_browser_->GetBrowserState()));
+
+  // Drop "E" after "C".
+  web::WebStateID web_state_id =
+      web_state_list->GetWebStateAt(4)->GetUniqueIdentifier();
+  id local_object = [[TabInfo alloc]
+      initWithTabID:web_state_id
+          incognito:regular_browser_->GetBrowserState()->IsOffTheRecord()];
+  NSItemProvider* item_provider = [[NSItemProvider alloc] init];
+  UIDragItem* drag_item =
+      [[UIDragItem alloc] initWithItemProvider:item_provider];
+  drag_item.localObject = local_object;
+  [mediator_ dropItem:drag_item toIndex:3 fromSameCollection:NO];
+  EXPECT_EQ("a* b c e | d f", builder.GetWebStateListDescription());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kSameBrowser, 1);
+
+  // Drop "D" after "E".
+  web_state_id = web_state_list->GetWebStateAt(4)->GetUniqueIdentifier();
+  local_object = [[TabInfo alloc]
+      initWithTabID:web_state_id
+          incognito:regular_browser_->GetBrowserState()->IsOffTheRecord()];
+  item_provider = [[NSItemProvider alloc] init];
+  drag_item = [[UIDragItem alloc] initWithItemProvider:item_provider];
+  drag_item.localObject = local_object;
+  [mediator_ dropItem:drag_item toIndex:4 fromSameCollection:NO];
+  EXPECT_EQ("a* b c e d | f", builder.GetWebStateListDescription());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kSameBrowser, 2);
+}
+
+// Tests dropping tabs from tab group.
+TEST_F(PinnedTabsMediatorTest, DropTabGroupTabs) {
+  // The Pinned Tabs feature is not available on iPad.
+  if (!IsPinnedTabsEnabled()) {
+    return;
+  }
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeature(kTabGroupsInGrid);
+
+  WebStateList* web_state_list = regular_browser_->GetWebStateList();
+  CloseAllWebStates(*web_state_list, WebStateList::CLOSE_NO_FLAGS);
+  WebStateListBuilderFromDescription builder(web_state_list);
+  ASSERT_TRUE(builder.BuildWebStateListFromDescription(
+      "a* b c | d [ 0 e f ]", regular_browser_->GetBrowserState()));
+
+  // Drop "E" after "C".
+  web::WebStateID web_state_id =
+      web_state_list->GetWebStateAt(4)->GetUniqueIdentifier();
+  id local_object = [[TabInfo alloc]
+      initWithTabID:web_state_id
+          incognito:regular_browser_->GetBrowserState()->IsOffTheRecord()];
+  NSItemProvider* item_provider = [[NSItemProvider alloc] init];
+  UIDragItem* drag_item =
+      [[UIDragItem alloc] initWithItemProvider:item_provider];
+  drag_item.localObject = local_object;
+  [mediator_ dropItem:drag_item toIndex:3 fromSameCollection:NO];
+  EXPECT_EQ("a* b c e | d [ 0 f ]", builder.GetWebStateListDescription());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kSameBrowser, 1);
+
+  // Drop "D" after "E".
+  web_state_id = web_state_list->GetWebStateAt(4)->GetUniqueIdentifier();
+  local_object = [[TabInfo alloc]
+      initWithTabID:web_state_id
+          incognito:regular_browser_->GetBrowserState()->IsOffTheRecord()];
+  item_provider = [[NSItemProvider alloc] init];
+  drag_item = [[UIDragItem alloc] initWithItemProvider:item_provider];
+  drag_item.localObject = local_object;
+  [mediator_ dropItem:drag_item toIndex:4 fromSameCollection:NO];
+  EXPECT_EQ("a* b c e d | [ 0 f ]", builder.GetWebStateListDescription());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kSameBrowser, 2);
+
+  // Drop "F" after "D".
+  web_state_id = web_state_list->GetWebStateAt(5)->GetUniqueIdentifier();
+  local_object = [[TabInfo alloc]
+      initWithTabID:web_state_id
+          incognito:regular_browser_->GetBrowserState()->IsOffTheRecord()];
+  item_provider = [[NSItemProvider alloc] init];
+  drag_item = [[UIDragItem alloc] initWithItemProvider:item_provider];
+  drag_item.localObject = local_object;
+  [mediator_ dropItem:drag_item toIndex:5 fromSameCollection:NO];
+  EXPECT_EQ("a* b c e d f |", builder.GetWebStateListDescription());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kSameBrowser, 3);
+}
+
+// Tests dropping an external URL.
+TEST_F(PinnedTabsMediatorTest, DropExternalURL) {
+  // The Pinned Tabs feature is not available on iPad.
+  if (!IsPinnedTabsEnabled()) {
+    return;
+  }
+
+  WebStateList* web_state_list = regular_browser_->GetWebStateList();
+  CloseAllWebStates(*web_state_list, WebStateList::CLOSE_NO_FLAGS);
+  WebStateListBuilderFromDescription builder(web_state_list);
+  ASSERT_TRUE(builder.BuildWebStateListFromDescription(
+      "a* b c | d", regular_browser_->GetBrowserState()));
+  ASSERT_EQ(4, web_state_list->count());
+
+  NSItemProvider* item_provider = [[NSItemProvider alloc]
+      initWithContentsOfURL:[NSURL URLWithString:@"https://dragged_url.com"]];
+
+  // Drop item after "C".
+  [mediator_ dropItemFromProvider:item_provider
+                          toIndex:3
+               placeholderContext:nil];
+
+  EXPECT_TRUE(base::test::ios::WaitUntilConditionOrTimeout(
+      base::Seconds(1), ^bool(void) {
+        return web_state_list->count() == 5;
+      }));
+  web::WebState* web_state = web_state_list->GetWebStateAt(3);
+  EXPECT_EQ(GURL("https://dragged_url.com"),
+            web_state->GetNavigationManager()->GetPendingItem()->GetURL());
+  ExpectThatDragItemOriginMetricLogged(DragItemOrigin::kOther);
+}
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/coordinator/tab_strip_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_strip/coordinator/tab_strip_mediator.mm
index f75365e..513b205 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/coordinator/tab_strip_mediator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/coordinator/tab_strip_mediator.mm
@@ -839,7 +839,7 @@
     if (fromSameCollection) {
       base::UmaHistogramEnumeration(kUmaTabStripViewDragOrigin,
                                     DragItemOrigin::kSameCollection);
-      // Reorder tab within same grid.
+      // Reorder tabs.
       const WebStateList::InsertionParams insertionParams =
           [self insertionParamsForDestinationItemIndex:destinationIndex
                                                  items:_dragItems];
@@ -849,7 +849,7 @@
       // The tab lives in another Browser.
       // TODO(crbug.com/41488813): Need to be updated for pinned tabs.
       base::UmaHistogramEnumeration(kUmaTabStripViewDragOrigin,
-                                    DragItemOrigin::kOtherBrwoser);
+                                    DragItemOrigin::kOtherBrowser);
       [self moveItemWithIDFromDifferentBrowser:tabInfo.tabID
                                        toIndex:destinationIndex];
     }
@@ -871,7 +871,7 @@
                                     DragItemOrigin::kSameCollection);
     } else {
       base::UmaHistogramEnumeration(kUmaTabStripViewGroupDragOrigin,
-                                    DragItemOrigin::kOtherBrwoser);
+                                    DragItemOrigin::kOtherBrowser);
     }
     // Determine the tab strip item before which the group should be moved.
     NSArray<TabStripItemIdentifier*>* items = _dragItems;
@@ -907,6 +907,8 @@
     [placeholderContext deletePlaceholder];
     return;
   }
+  base::UmaHistogramEnumeration(kUmaTabStripViewDragOrigin,
+                                DragItemOrigin::kOther);
 
   __weak __typeof(self) weakSelf = self;
   auto loadHandler =
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/coordinator/tab_strip_mediator_unittest.mm b/ios/chrome/browser/ui/tab_switcher/tab_strip/coordinator/tab_strip_mediator_unittest.mm
index bb4ed6d..66fc9bc 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/coordinator/tab_strip_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/coordinator/tab_strip_mediator_unittest.mm
@@ -10,6 +10,7 @@
 #import "components/favicon/core/favicon_url.h"
 #import "components/favicon/ios/web_favicon_driver.h"
 #import "components/keyed_service/core/service_access_type.h"
+#import "components/tab_groups/tab_group_id.h"
 #import "components/tab_groups/tab_group_visual_data.h"
 #import "ios/chrome/browser/favicon/model/favicon_service_factory.h"
 #import "ios/chrome/browser/history/model/history_service_factory.h"
@@ -35,6 +36,8 @@
 #import "testing/platform_test.h"
 #import "third_party/ocmock/OCMock/OCMock.h"
 
+using tab_groups::TabGroupId;
+
 // Fake handler to get commands in tests.
 @interface FakeTabStripHandler : NSObject <TabStripCommands>
 
@@ -352,7 +355,8 @@
             consumer_.items[1].tabSwitcherItem.identifier);
 
   // Check that the group is correctly added to the consumer.
-  const TabGroup* group_0 = web_state_list_->CreateGroup({0}, {});
+  const TabGroup* group_0 =
+      web_state_list_->CreateGroup({0}, {}, TabGroupId::GenerateNew());
 
   ASSERT_NE(nil, consumer_.selectedItem);
   EXPECT_EQ(web_state_list_->GetActiveWebState()->GetUniqueIdentifier(),
@@ -530,7 +534,7 @@
                                         builder.GetWebStateForIdentifier('g')),
                                     web_state_list_->GetIndexOfWebState(
                                         builder.GetWebStateForIdentifier('h'))},
-                                   {});
+                                   {}, TabGroupId::GenerateNew());
   builder.SetTabGroupIdentifier(group_2, '2');
   UIColor* group_2_color = group_2->GetColor();
   ASSERT_EQ(builder.GetWebStateListDescription(),
@@ -661,7 +665,7 @@
                                         builder.GetWebStateForIdentifier('g')),
                                     web_state_list_->GetIndexOfWebState(
                                         builder.GetWebStateForIdentifier('h'))},
-                                   {});
+                                   {}, TabGroupId::GenerateNew());
   builder.SetTabGroupIdentifier(group_2, '2');
   ASSERT_EQ(builder.GetWebStateListDescription(),
             "a b | [ 2 c* d f g h ] [ 0 e ]");
@@ -836,7 +840,8 @@
   AddWebState();
   AddWebState();
   AddWebState();
-  const TabGroup* group = web_state_list_->CreateGroup({1, 2}, {});
+  const TabGroup* group =
+      web_state_list_->CreateGroup({1, 2}, {}, TabGroupId::GenerateNew());
 
   InitializeMediator();
 
@@ -1029,7 +1034,8 @@
   AddWebState();
   AddWebState();
   AddWebState();
-  const TabGroup* group = web_state_list_->CreateGroup({1, 2}, {});
+  const TabGroup* group =
+      web_state_list_->CreateGroup({1, 2}, {}, TabGroupId::GenerateNew());
   TabGroupItem* group_item =
       [[TabGroupItem alloc] initWithTabGroup:group
                                 webStateList:web_state_list_];
@@ -1069,7 +1075,8 @@
 TEST_F(TabStripMediatorTest, RenameGroup) {
   AddWebState();
   AddWebState();
-  const TabGroup* group = web_state_list_->CreateGroup({0, 1}, {});
+  const TabGroup* group =
+      web_state_list_->CreateGroup({0, 1}, {}, TabGroupId::GenerateNew());
   TabGroupItem* groupItem =
       [[TabGroupItem alloc] initWithTabGroup:group
                                 webStateList:web_state_list_];
@@ -1084,7 +1091,8 @@
 TEST_F(TabStripMediatorTest, AddTabInGroup) {
   AddWebState();
   AddWebState();
-  const TabGroup* group = web_state_list_->CreateGroup({0, 1}, {});
+  const TabGroup* group =
+      web_state_list_->CreateGroup({0, 1}, {}, TabGroupId::GenerateNew());
   TabGroupItem* groupItem =
       [[TabGroupItem alloc] initWithTabGroup:group
                                 webStateList:web_state_list_];
@@ -1108,7 +1116,8 @@
 TEST_F(TabStripMediatorTest, UngroupTabs) {
   AddWebState();
   AddWebState();
-  const TabGroup* group = web_state_list_->CreateGroup({0, 1}, {});
+  const TabGroup* group =
+      web_state_list_->CreateGroup({0, 1}, {}, TabGroupId::GenerateNew());
   TabGroupItem* groupItem =
       [[TabGroupItem alloc] initWithTabGroup:group
                                 webStateList:web_state_list_];
@@ -1131,7 +1140,8 @@
 TEST_F(TabStripMediatorTest, DeleteGroup) {
   AddWebState();
   AddWebState();
-  const TabGroup* group = web_state_list_->CreateGroup({0, 1}, {});
+  const TabGroup* group =
+      web_state_list_->CreateGroup({0, 1}, {}, TabGroupId::GenerateNew());
   TabGroupItem* groupItem =
       [[TabGroupItem alloc] initWithTabGroup:group
                                 webStateList:web_state_list_];
@@ -1154,7 +1164,8 @@
 TEST_F(TabStripMediatorTest, AddTabToGroup) {
   AddWebState();
   AddWebState();
-  const TabGroup* group = web_state_list_->CreateGroup({0}, {});
+  const TabGroup* group =
+      web_state_list_->CreateGroup({0}, {}, TabGroupId::GenerateNew());
 
   InitializeMediator();
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/BUILD.gn
index 51314c7..631f01dc 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/BUILD.gn
@@ -83,6 +83,7 @@
   sources = [ "tab_strip_item_identifier_unittest.mm" ]
   deps = [
     ":swift",
+    "//components/tab_groups",
     "//ios/chrome/browser/shared/model/web_state_list",
     "//ios/chrome/browser/shared/model/web_state_list/test:test_support",
     "//ios/chrome/browser/ui/tab_switcher",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_item_identifier_unittest.mm b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_item_identifier_unittest.mm
index 8c8ed31..63dcf861 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_item_identifier_unittest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_item_identifier_unittest.mm
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#import "components/tab_groups/tab_group_id.h"
 #import "ios/chrome/browser/shared/model/web_state_list/tab_group.h"
 #import "ios/chrome/browser/shared/model/web_state_list/test/fake_web_state_list_delegate.h"
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
@@ -15,6 +16,8 @@
 
 using TabStripItemIdentifierTest = PlatformTest;
 
+using tab_groups::TabGroupId;
+
 // Verifies the properties of a Tab strip tab item.
 TEST_F(TabStripItemIdentifierTest, Tab) {
   web::WebStateID web_state_id = web::WebStateID::NewUnique();
@@ -89,7 +92,8 @@
   std::unique_ptr<WebStateList> web_state_list =
       std::make_unique<WebStateList>(&web_state_list_delegate);
   web_state_list->InsertWebState(std::make_unique<web::FakeWebState>());
-  const TabGroup* tab_group = web_state_list->CreateGroup({0}, {});
+  const TabGroup* tab_group =
+      web_state_list->CreateGroup({0}, {}, TabGroupId::GenerateNew());
   TabGroupItem* tab_group_item =
       [[TabGroupItem alloc] initWithTabGroup:tab_group
                                 webStateList:web_state_list.get()];
@@ -106,7 +110,8 @@
   std::unique_ptr<WebStateList> web_state_list =
       std::make_unique<WebStateList>(&web_state_list_delegate);
   web_state_list->InsertWebState(std::make_unique<web::FakeWebState>());
-  const TabGroup* tab_group = web_state_list->CreateGroup({0}, {});
+  const TabGroup* tab_group =
+      web_state_list->CreateGroup({0}, {}, TabGroupId::GenerateNew());
   TabGroupItem* tab_group_item_1 =
       [[TabGroupItem alloc] initWithTabGroup:tab_group
                                 webStateList:web_state_list.get()];
@@ -129,13 +134,15 @@
       std::make_unique<WebStateList>(&web_state_list_delegate);
   web_state_list->InsertWebState(std::make_unique<web::FakeWebState>());
   web_state_list->InsertWebState(std::make_unique<web::FakeWebState>());
-  const TabGroup* tab_group_1 = web_state_list->CreateGroup({0}, {});
+  const TabGroup* tab_group_1 =
+      web_state_list->CreateGroup({0}, {}, TabGroupId::GenerateNew());
   TabGroupItem* tab_group_item_1 =
       [[TabGroupItem alloc] initWithTabGroup:tab_group_1
                                 webStateList:web_state_list.get()];
   TabStripItemIdentifier* item_identifier_1 =
       [TabStripItemIdentifier groupIdentifier:tab_group_item_1];
-  const TabGroup* tab_group_2 = web_state_list->CreateGroup({1}, {});
+  const TabGroup* tab_group_2 =
+      web_state_list->CreateGroup({1}, {}, TabGroupId::GenerateNew());
   TabGroupItem* tab_group_item_2 =
       [[TabGroupItem alloc] initWithTabGroup:tab_group_2
                                 webStateList:web_state_list.get()];
@@ -155,7 +162,8 @@
   std::unique_ptr<WebStateList> web_state_list =
       std::make_unique<WebStateList>(&web_state_list_delegate);
   web_state_list->InsertWebState(std::make_unique<web::FakeWebState>());
-  const TabGroup* tab_group = web_state_list->CreateGroup({0}, {});
+  const TabGroup* tab_group =
+      web_state_list->CreateGroup({0}, {}, TabGroupId::GenerateNew());
   TabGroupItem* tab_group_item =
       [[TabGroupItem alloc] initWithTabGroup:tab_group
                                 webStateList:web_state_list.get()];
@@ -175,7 +183,8 @@
   std::unique_ptr<WebStateList> web_state_list =
       std::make_unique<WebStateList>(&web_state_list_delegate);
   web_state_list->InsertWebState(std::make_unique<web::FakeWebState>());
-  const TabGroup* tab_group = web_state_list->CreateGroup({0}, {});
+  const TabGroup* tab_group =
+      web_state_list->CreateGroup({0}, {}, TabGroupId::GenerateNew());
   TabGroupItem* tab_group_item =
       [[TabGroupItem alloc] initWithTabGroup:tab_group
                                 webStateList:web_state_list.get()];
diff --git a/ios/chrome/browser/ui/toolbar/BUILD.gn b/ios/chrome/browser/ui/toolbar/BUILD.gn
index 57855b6..b081199 100644
--- a/ios/chrome/browser/ui/toolbar/BUILD.gn
+++ b/ios/chrome/browser/ui/toolbar/BUILD.gn
@@ -39,6 +39,8 @@
     "//ios/chrome/browser/autocomplete/model",
     "//ios/chrome/browser/bookmarks/model",
     "//ios/chrome/browser/bookmarks/ui_bundled:core",
+    "//ios/chrome/browser/contextual_panel/model",
+    "//ios/chrome/browser/contextual_panel/model:public",
     "//ios/chrome/browser/feature_engagement/model",
     "//ios/chrome/browser/first_run/model",
     "//ios/chrome/browser/iph_for_new_chrome_user/model",
@@ -113,6 +115,7 @@
     "primary_toolbar_view_controller.h",
     "primary_toolbar_view_controller.mm",
     "primary_toolbar_view_controller_delegate.h",
+    "secondary_toolbar_consumer.h",
     "secondary_toolbar_keyboard_state_provider.h",
     "secondary_toolbar_view.h",
     "secondary_toolbar_view.mm",
diff --git a/ios/chrome/browser/ui/toolbar/secondary_toolbar_consumer.h b/ios/chrome/browser/ui/toolbar/secondary_toolbar_consumer.h
new file mode 100644
index 0000000..894a6d4
--- /dev/null
+++ b/ios/chrome/browser/ui/toolbar/secondary_toolbar_consumer.h
@@ -0,0 +1,19 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_TOOLBAR_SECONDARY_TOOLBAR_CONSUMER_H_
+#define IOS_CHROME_BROWSER_UI_TOOLBAR_SECONDARY_TOOLBAR_CONSUMER_H_
+
+// Consumer protocol for the secondary toolbar.
+@protocol SecondaryToolbarConsumer
+
+// Notifies the consumer to turn translucent.
+- (void)makeTranslucent;
+
+// Notifies the consumer to turn opaque.
+- (void)makeOpaque;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_TOOLBAR_SECONDARY_TOOLBAR_CONSUMER_H_
diff --git a/ios/chrome/browser/ui/toolbar/secondary_toolbar_coordinator.mm b/ios/chrome/browser/ui/toolbar/secondary_toolbar_coordinator.mm
index 7c463af..cfdc6cab 100644
--- a/ios/chrome/browser/ui/toolbar/secondary_toolbar_coordinator.mm
+++ b/ios/chrome/browser/ui/toolbar/secondary_toolbar_coordinator.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/ui/toolbar/secondary_toolbar_coordinator.h"
 
+#import "ios/chrome/browser/contextual_panel/model/contextual_panel_tab_helper.h"
 #import "ios/chrome/browser/shared/coordinator/layout_guide/layout_guide_util.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
@@ -13,6 +14,8 @@
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_controller.h"
 #import "ios/chrome/browser/ui/toolbar/adaptive_toolbar_coordinator+subclassing.h"
+#import "ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.h"
+#import "ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.h"
 #import "ios/chrome/browser/ui/toolbar/secondary_toolbar_mediator.h"
 #import "ios/chrome/browser/ui/toolbar/secondary_toolbar_view_controller.h"
 
@@ -47,6 +50,8 @@
   self.viewController.fullscreenController = controller;
   self.viewController.toolbarHeightDelegate = self.toolbarHeightDelegate;
 
+  _secondaryToolbarMediator.consumer = self.viewController;
+
   [super start];
 }
 
diff --git a/ios/chrome/browser/ui/toolbar/secondary_toolbar_mediator.h b/ios/chrome/browser/ui/toolbar/secondary_toolbar_mediator.h
index f52d1de..aa679f5 100644
--- a/ios/chrome/browser/ui/toolbar/secondary_toolbar_mediator.h
+++ b/ios/chrome/browser/ui/toolbar/secondary_toolbar_mediator.h
@@ -9,6 +9,7 @@
 
 #import "ios/chrome/browser/ui/toolbar/secondary_toolbar_keyboard_state_provider.h"
 
+@protocol SecondaryToolbarConsumer;
 class WebStateList;
 
 /// Mediator providing web state information to SecondaryToolbarViewController.
@@ -18,6 +19,9 @@
 /// Creates an instance of the mediator.
 - (instancetype)initWithWebStateList:(WebStateList*)webStateList;
 
+// The consumer for this mediator.
+@property(nonatomic, weak) id<SecondaryToolbarConsumer> consumer;
+
 /// Disconnects web state list reference.
 - (void)disconnect;
 
diff --git a/ios/chrome/browser/ui/toolbar/secondary_toolbar_mediator.mm b/ios/chrome/browser/ui/toolbar/secondary_toolbar_mediator.mm
index ff045f5..fb37743c 100644
--- a/ios/chrome/browser/ui/toolbar/secondary_toolbar_mediator.mm
+++ b/ios/chrome/browser/ui/toolbar/secondary_toolbar_mediator.mm
@@ -5,27 +5,75 @@
 #import "ios/chrome/browser/ui/toolbar/secondary_toolbar_mediator.h"
 
 #import "base/memory/weak_ptr.h"
+#import "ios/chrome/browser/contextual_panel/model/active_contextual_panel_tab_helper_observation_forwarder.h"
+#import "ios/chrome/browser/contextual_panel/model/contextual_panel_tab_helper.h"
+#import "ios/chrome/browser/contextual_panel/model/contextual_panel_tab_helper_observer_bridge.h"
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
+#import "ios/chrome/browser/shared/model/web_state_list/web_state_list_observer_bridge.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
+#import "ios/chrome/browser/ui/toolbar/secondary_toolbar_consumer.h"
 #import "ios/web/public/ui/crw_web_view_proxy.h"
 #import "ios/web/public/web_state.h"
 
+@interface SecondaryToolbarMediator () <ContextualPanelTabHelperObserving,
+                                        WebStateListObserving>
+
+@end
+
 @implementation SecondaryToolbarMediator {
   // The Browser's WebStateList.
   base::WeakPtr<WebStateList> _webStateList;
+
+  // Observer machinery for the web state list.
+  std::unique_ptr<WebStateListObserverBridge> _webStateListObserver;
+  std::unique_ptr<
+      base::ScopedObservation<WebStateList, WebStateListObserverBridge>>
+      _webStateListObservation;
+
+  // Bridge for the ContextualPanelTabHelper observation.
+  std::unique_ptr<ContextualPanelTabHelperObserverBridge>
+      _contextualPanelObserverBridge;
+
+  // Forwarder to always be observing the active ContextualPanelTabHelper.
+  std::unique_ptr<ActiveContextualPanelTabHelperObservationForwarder>
+      _activeContextualPanelObservationForwarder;
 }
 
 - (instancetype)initWithWebStateList:(WebStateList*)webStateList {
   if (self = [super init]) {
     DCHECK(webStateList);
     _webStateList = webStateList->AsWeakPtr();
+
+    // Web state list observation is only necessary for Contextual Panel
+    // feature.
+    if (IsContextualPanelEnabled()) {
+      // Set up web state list observation.
+      _webStateListObserver =
+          std::make_unique<WebStateListObserverBridge>(self);
+      _webStateListObservation = std::make_unique<
+          base::ScopedObservation<WebStateList, WebStateListObserverBridge>>(
+          _webStateListObserver.get());
+      _webStateListObservation->Observe(_webStateList.get());
+
+      // Set up active ContextualPanelTabHelper observation.
+      _contextualPanelObserverBridge =
+          std::make_unique<ContextualPanelTabHelperObserverBridge>(self);
+      _activeContextualPanelObservationForwarder =
+          std::make_unique<ActiveContextualPanelTabHelperObservationForwarder>(
+              webStateList, _contextualPanelObserverBridge.get());
+    }
   }
   return self;
 }
 
 - (void)disconnect {
   if (_webStateList) {
+    _activeContextualPanelObservationForwarder.reset();
+    _webStateListObservation.reset();
     _webStateList.reset();
   }
+  _contextualPanelObserverBridge.reset();
+  _webStateListObserver.reset();
 }
 
 #pragma mark - SecondaryToolbarKeyboardStateProvider
@@ -39,4 +87,37 @@
   return NO;
 }
 
+#pragma mark - WebStateListObserving
+
+- (void)didChangeWebStateList:(WebStateList*)webStateList
+                       change:(const WebStateListChange&)change
+                       status:(const WebStateListStatus&)status {
+  // Return early if the active web state is the same as before the change.
+  if (!status.active_web_state_change()) {
+    return;
+  }
+
+  // Return early if no new webstates are active.
+  if (!status.new_active_web_state) {
+    return;
+  }
+  ContextualPanelTabHelper* contextualPanelTabHelper =
+      ContextualPanelTabHelper::FromWebState(status.new_active_web_state);
+  if (contextualPanelTabHelper->IsContextualPanelCurrentlyOpened()) {
+    [self.consumer makeTranslucent];
+  } else {
+    [self.consumer makeOpaque];
+  }
+}
+
+#pragma mark - ContextualPanelTabHelperObserving
+
+- (void)contextualPanelOpened:(ContextualPanelTabHelper*)tabHelper {
+  [self.consumer makeTranslucent];
+}
+
+- (void)contextualPanelClosed:(ContextualPanelTabHelper*)tabHelper {
+  [self.consumer makeOpaque];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.h b/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.h
index c2a444d..e4ad3d4 100644
--- a/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.h
+++ b/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.h
@@ -34,6 +34,12 @@
 - (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
 - (instancetype)init NS_UNAVAILABLE;
 
+// Makes the toolbar translucent.
+- (void)makeTranslucent;
+
+// Makes the toolbar opaque.
+- (void)makeOpaque;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_TOOLBAR_SECONDARY_TOOLBAR_VIEW_H_
diff --git a/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm b/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm
index 5bdce4b..21251b29 100644
--- a/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm
+++ b/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm
@@ -96,6 +96,11 @@
   // `buttonStackView.topAnchor`. Active when the omnibox is in the bottom
   // toolbar.
   NSLayoutConstraint* _locationBarBottomConstraint;
+
+  // Visual effect view to make the toolbar appear translucent when necessary.
+  UIVisualEffectView* _visualEffectView;
+  // Content view to hold the main toolbar content above the visual effect view.
+  UIView* _contentView;
 }
 
 @synthesize allButtons = _allButtons;
@@ -136,7 +141,8 @@
     _locationBarKeyboardConstraint.active = NO;
 
     // UIKeyboardLayoutGuide is updated sooner in superview's
-    // keyboardLayoutGuide rendering smoother animation. Constraint is updated
+    // keyboardLayoutGuide rendering smoother animation. Constraint is
+    // updated
     // in view controller.
     _locationBarKeyboardConstraint = [newSuperview.keyboardLayoutGuide.topAnchor
         constraintGreaterThanOrEqualToAnchor:self.locationBarContainer
@@ -156,10 +162,23 @@
 
   self.translatesAutoresizingMaskIntoConstraints = NO;
 
-  self.backgroundColor =
+  UIBlurEffect* blurEffect =
+      [UIBlurEffect effectWithStyle:UIBlurEffectStyleRegular];
+  _visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
+  _visualEffectView.translatesAutoresizingMaskIntoConstraints = NO;
+  _visualEffectView.hidden = YES;
+
+  [self addSubview:_visualEffectView];
+  AddSameConstraints(self, _visualEffectView);
+
+  _contentView = [[UIView alloc] init];
+  _contentView.translatesAutoresizingMaskIntoConstraints = NO;
+  [self addSubview:_contentView];
+  AddSameConstraints(self, _contentView);
+  _contentView.backgroundColor =
       self.buttonFactory.toolbarConfiguration.backgroundColor;
 
-  UIView* contentView = self;
+  UIView* contentView = _contentView;
 
   // Toolbar buttons.
   self.backButton = [self.buttonFactory backButton];
@@ -183,7 +202,7 @@
   self.separator = [[UIView alloc] init];
   self.separator.backgroundColor = [UIColor colorNamed:kToolbarShadowColor];
   self.separator.translatesAutoresizingMaskIntoConstraints = NO;
-  [self addSubview:self.separator];
+  [contentView addSubview:self.separator];
 
   // Button StackView.
   self.buttonStackView =
@@ -195,7 +214,6 @@
   UILayoutGuide* safeArea = self.safeAreaLayoutGuide;
 
   if (IsBottomOmniboxAvailable()) {
-    self.buttonStackView.backgroundColor = self.backgroundColor;
     self.collapsedToolbarButton = SecondaryToolbarCollapsedToolbarButton();
     self.locationBarContainer =
         SecondaryToolbarLocationBarContainerView(self.buttonFactory);
@@ -247,7 +265,7 @@
         [UIColor colorNamed:kToolbarShadowColor];
     self.bottomSeparator.translatesAutoresizingMaskIntoConstraints = NO;
     self.bottomSeparator.alpha = 0.0;
-    [self addSubview:self.bottomSeparator];
+    [contentView addSubview:self.bottomSeparator];
     AddSameConstraintsToSides(self, self.bottomSeparator,
                               LayoutSides::kLeading | LayoutSides::kTrailing);
 
@@ -348,4 +366,15 @@
   }
 }
 
+- (void)makeTranslucent {
+  _visualEffectView.hidden = NO;
+  _contentView.backgroundColor = nil;
+}
+
+- (void)makeOpaque {
+  _visualEffectView.hidden = YES;
+  _contentView.backgroundColor =
+      self.buttonFactory.toolbarConfiguration.backgroundColor;
+}
+
 @end
diff --git a/ios/chrome/browser/ui/toolbar/secondary_toolbar_view_controller.h b/ios/chrome/browser/ui/toolbar/secondary_toolbar_view_controller.h
index 67b88a8..2b8bcb6 100644
--- a/ios/chrome/browser/ui/toolbar/secondary_toolbar_view_controller.h
+++ b/ios/chrome/browser/ui/toolbar/secondary_toolbar_view_controller.h
@@ -6,6 +6,7 @@
 #define IOS_CHROME_BROWSER_UI_TOOLBAR_SECONDARY_TOOLBAR_VIEW_CONTROLLER_H_
 
 #import "ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.h"
+#import "ios/chrome/browser/ui/toolbar/secondary_toolbar_consumer.h"
 
 class FullscreenController;
 
@@ -14,7 +15,8 @@
 
 /// View controller for the secondary part of the adaptive toolbar. It is the
 /// one at the bottom of the screen. Displayed only on specific size classes.
-@interface SecondaryToolbarViewController : AdaptiveToolbarViewController
+@interface SecondaryToolbarViewController
+    : AdaptiveToolbarViewController <SecondaryToolbarConsumer>
 
 /// Protocol to retrieve the keyboard state on the active web state.
 @property(nonatomic, weak) id<SecondaryToolbarKeyboardStateProvider>
diff --git a/ios/chrome/browser/ui/toolbar/secondary_toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/secondary_toolbar_view_controller.mm
index ea4a1549..93bfe81 100644
--- a/ios/chrome/browser/ui/toolbar/secondary_toolbar_view_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/secondary_toolbar_view_controller.mm
@@ -168,4 +168,14 @@
   }
 }
 
+#pragma mark - SecondaryToolbarConsumer
+
+- (void)makeTranslucent {
+  [self.view makeTranslucent];
+}
+
+- (void)makeOpaque {
+  [self.view makeOpaque];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/whats_new/data_source/BUILD.gn b/ios/chrome/browser/ui/whats_new/data_source/BUILD.gn
index b4d06987..2541acf 100644
--- a/ios/chrome/browser/ui/whats_new/data_source/BUILD.gn
+++ b/ios/chrome/browser/ui/whats_new/data_source/BUILD.gn
@@ -22,8 +22,8 @@
     "resources:whats_new_entries_plist",
     "//base",
     "//ios/chrome/app/strings",
+    "//ios/chrome/browser/default_promo/ui_bundled/resources:animation_files",
     "//ios/chrome/browser/shared/ui/symbols",
-    "//ios/chrome/browser/ui/default_promo/resources:animation_files",
     "//ios/chrome/browser/ui/whats_new:util",
     "//ios/chrome/common/ui/colors",
     "//ui/base",
diff --git a/ios/chrome/browser/visited_url_ranking/model/ios_tab_model_url_visit_data_fetcher_unittest.mm b/ios/chrome/browser/visited_url_ranking/model/ios_tab_model_url_visit_data_fetcher_unittest.mm
index 16f4883a..61f7fcf 100644
--- a/ios/chrome/browser/visited_url_ranking/model/ios_tab_model_url_visit_data_fetcher_unittest.mm
+++ b/ios/chrome/browser/visited_url_ranking/model/ios_tab_model_url_visit_data_fetcher_unittest.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/visited_url_ranking/model/ios_tab_model_url_visit_data_fetcher.h"
 
+#import "components/tab_groups/tab_group_id.h"
 #import "components/tab_groups/tab_group_visual_data.h"
 #import "components/visited_url_ranking/public/url_visit.h"
 #import "ios/chrome/browser/sessions/ios_chrome_session_tab_helper.h"
@@ -17,6 +18,8 @@
 #import "ios/web/public/test/web_task_environment.h"
 #import "testing/platform_test.h"
 
+using tab_groups::TabGroupId;
+
 class IOSTabModelURLVisitDataFetcherTest : public PlatformTest {
  protected:
   IOSTabModelURLVisitDataFetcherTest() {
@@ -135,7 +138,7 @@
       u"test", tab_groups::TabGroupColorId::kGrey);
   EXPECT_EQ(GURL(normal_urls[2]),
             web_state_list->GetWebStateAt(2)->GetLastCommittedURL());
-  web_state_list->CreateGroup({2}, visual_data);
+  web_state_list->CreateGroup({2}, visual_data, TabGroupId::GenerateNew());
   web_state_list->GetWebStateAt(2)
       ->GetNavigationManager()
       ->GetLastCommittedItem()
@@ -242,7 +245,7 @@
   EXPECT_EQ(GURL(url), web_state1->GetLastCommittedURL());
   tab_groups::TabGroupVisualData visual_data(
       u"test", tab_groups::TabGroupColorId::kGrey);
-  web_state_list->CreateGroup({1}, visual_data);
+  web_state_list->CreateGroup({1}, visual_data, TabGroupId::GenerateNew());
   web_state1->GetNavigationManager()->GetLastCommittedItem()->SetTimestamp(
       now - base::Hours(1));
   web_state1->SetLastActiveTime(now - base::Hours(5));
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn
index 74e0701e..fce63892 100644
--- a/ios/chrome/test/BUILD.gn
+++ b/ios/chrome/test/BUILD.gn
@@ -220,6 +220,7 @@
     "//ios/chrome/browser/bring_android_tabs/model:unit_tests",
     "//ios/chrome/browser/bring_android_tabs/ui_bundled:unit_tests",
     "//ios/chrome/browser/browser_state/model:unit_tests",
+    "//ios/chrome/browser/browser_view/ui_bundled:unit_tests",
     "//ios/chrome/browser/browsing_data/model:unit_tests",
     "//ios/chrome/browser/bubble/ui_bundled:unit_tests",
     "//ios/chrome/browser/commerce/model:unit_tests",
@@ -235,6 +236,9 @@
     "//ios/chrome/browser/credential_provider_promo/ui_bundled:unit_tests",
     "//ios/chrome/browser/data_sharing/model:unit_tests",
     "//ios/chrome/browser/default_browser/model:unit_tests",
+    "//ios/chrome/browser/default_promo/ui_bundled:unit_tests",
+    "//ios/chrome/browser/default_promo/ui_bundled/generic:unit_tests",
+    "//ios/chrome/browser/default_promo/ui_bundled/promo_handler:unit_tests",
     "//ios/chrome/browser/device_reauth:unit_tests",
     "//ios/chrome/browser/device_sharing/model:unit_tests",
     "//ios/chrome/browser/dialogs/ui_bundled:unit_tests",
@@ -262,6 +266,7 @@
     "//ios/chrome/browser/itunes_urls/model:unit_tests",
     "//ios/chrome/browser/language/model:unit_tests",
     "//ios/chrome/browser/lens/model:unit_tests",
+    "//ios/chrome/browser/lens_overlay/model:unit_tests",
     "//ios/chrome/browser/link_to_text/model:unit_tests",
     "//ios/chrome/browser/main/model:unit_tests",
     "//ios/chrome/browser/metrics/model:unit_tests",
@@ -353,7 +358,6 @@
     "//ios/chrome/browser/ui/autofill/progress_dialog:unit_tests",
     "//ios/chrome/browser/ui/broadcaster:unit_tests",
     "//ios/chrome/browser/ui/browser_container:unit_tests",
-    "//ios/chrome/browser/ui/browser_view:unit_tests",
     "//ios/chrome/browser/ui/content_suggestions:unit_tests",
     "//ios/chrome/browser/ui/content_suggestions/cells:unit_tests",
     "//ios/chrome/browser/ui/content_suggestions/magic_stack:unit_tests",
@@ -361,9 +365,6 @@
     "//ios/chrome/browser/ui/content_suggestions/safety_check:unit_tests",
     "//ios/chrome/browser/ui/content_suggestions/set_up_list:unit_tests",
     "//ios/chrome/browser/ui/content_suggestions/tab_resumption:unit_tests",
-    "//ios/chrome/browser/ui/default_promo:unit_tests",
-    "//ios/chrome/browser/ui/default_promo/generic:unit_tests",
-    "//ios/chrome/browser/ui/default_promo/promo_handler:unit_tests",
     "//ios/chrome/browser/ui/first_run/omnibox_position:unit_tests",
     "//ios/chrome/browser/ui/first_run/omnibox_position/promo:unit_tests",
     "//ios/chrome/browser/ui/first_run/tos:unit_tests",
diff --git a/ios/chrome/test/app/BUILD.gn b/ios/chrome/test/app/BUILD.gn
index cbfe1f8..d745113 100644
--- a/ios/chrome/test/app/BUILD.gn
+++ b/ios/chrome/test/app/BUILD.gn
@@ -60,6 +60,7 @@
     "//ios/chrome/browser/bookmarks/model",
     "//ios/chrome/browser/bookmarks/ui_bundled:core",
     "//ios/chrome/browser/browser_state/model",
+    "//ios/chrome/browser/browser_view/ui_bundled",
     "//ios/chrome/browser/browsing_data/model",
     "//ios/chrome/browser/content_settings/model",
     "//ios/chrome/browser/history/model",
@@ -92,7 +93,6 @@
     "//ios/chrome/browser/ui/authentication/cells",
     "//ios/chrome/browser/ui/authentication/history_sync",
     "//ios/chrome/browser/ui/autofill/form_input_accessory:common",
-    "//ios/chrome/browser/ui/browser_view",
     "//ios/chrome/browser/ui/main",
     "//ios/chrome/browser/ui/settings/password:test_support",
     "//ios/chrome/browser/ui/settings/password/password_settings:common",
diff --git a/ios/chrome/test/app/chrome_test_util.mm b/ios/chrome/test/app/chrome_test_util.mm
index ef242c4e..df157ebf 100644
--- a/ios/chrome/test/app/chrome_test_util.mm
+++ b/ios/chrome/test/app/chrome_test_util.mm
@@ -19,6 +19,7 @@
 #import "ios/chrome/app/chrome_overlay_window.h"
 #import "ios/chrome/app/main_application_delegate_testing.h"
 #import "ios/chrome/app/main_controller.h"
+#import "ios/chrome/browser/browser_view/ui_bundled/browser_view_controller.h"
 #import "ios/chrome/browser/infobars/model/infobar_manager_impl.h"
 #import "ios/chrome/browser/shared/coordinator/scene/scene_controller.h"
 #import "ios/chrome/browser/shared/coordinator/scene/scene_controller_testing.h"
@@ -34,7 +35,6 @@
 #import "ios/chrome/browser/shared/public/commands/country_code_picker_commands.h"
 #import "ios/chrome/browser/shared/public/commands/unit_conversion_commands.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
-#import "ios/chrome/browser/ui/browser_view/browser_view_controller.h"
 #import "ios/chrome/browser/ui/main/bvc_container_view_controller.h"
 #import "ios/chrome/common/crash_report/crash_helper.h"
 #import "ios/chrome/test/app/tab_test_util.h"
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
index a0aa9eb..1339d21 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
@@ -194,6 +194,66 @@
   [[[EarlGrey selectElementWithMatcher:interactableSettingsButton]
          usingSearchAction:scrollAction
       onElementWithMatcher:ToolsMenuView()] performAction:grey_tap()];
+
+  // TODO(crbug.com/347267212): On iOS18 tools menu taps will fail due to an
+  // apparent EG2 SwiftUI bug. Use XCUIapplication APIs instead here.
+  if (@available(iOS 18, *)) {
+    NSError* error;
+    [[EarlGrey selectElementWithMatcher:buttonMatcher]
+        assertWithMatcher:grey_notNil()
+                    error:&error];
+
+    if ([error.domain isEqual:kGREYInteractionErrorDomain] &&
+        error.code == kGREYInteractionElementNotFoundErrorCode) {
+      // If buttonMatcher is gone, that means it wasn't a SwiftUI element (or
+      // EG2 is fixed).
+      return;
+    }
+
+    // GREYMatcher's that match: accessibilityID('kToolsMenuBookmarksId'))
+    NSString* description = [buttonMatcher description];
+    NSRegularExpression* regex = [NSRegularExpression
+        regularExpressionWithPattern:@"accessibilityID\\('(.*?)'\\)"
+                             options:NSRegularExpressionCaseInsensitive
+                               error:nil];
+    NSTextCheckingResult* match =
+        [regex firstMatchInString:description
+                          options:0
+                            range:NSMakeRange(0, description.length)];
+    if (match) {
+      XCUIApplication* app = [[XCUIApplication alloc] init];
+      NSString* accessibilityID =
+          [description substringWithRange:[match rangeAtIndex:1]];
+      [app.buttons[accessibilityID] tap];
+      return;
+    }
+
+    // GREYMatcher's that match "starts with('kToolsMenuSettingsId')"
+    regex = [NSRegularExpression
+        regularExpressionWithPattern:@"starts with\\('(.*?)'\\)"
+                             options:NSRegularExpressionCaseInsensitive
+                               error:nil];
+    match = [regex firstMatchInString:description
+                              options:0
+                                range:NSMakeRange(0, description.length)];
+    if (match) {
+      NSString* prefix =
+          [description substringWithRange:[match rangeAtIndex:1]];
+      NSPredicate* predicate =
+          [NSPredicate predicateWithFormat:@"identifier BEGINSWITH %@", prefix];
+      XCUIApplication* app = [[XCUIApplication alloc] init];
+      XCUIElement* button = [app.buttons elementMatchingPredicate:predicate];
+      XCTAssertTrue(
+          button.exists,
+          @"Button with accessibility label starting with '%@' should exist",
+          prefix);
+      [button tap];
+      return;
+    }
+
+    XCTFail("SwiftUI/EG2 workaround missing GREYMatcher equivalent "
+            "NSRegularExpression.");
+  }
 }
 
 - (void)tapToolsMenuAction:(id<GREYMatcher>)buttonMatcher {
diff --git a/ios/chrome/test/earl_grey2/BUILD.gn b/ios/chrome/test/earl_grey2/BUILD.gn
index b935f3d..5e7ed1f 100644
--- a/ios/chrome/test/earl_grey2/BUILD.gn
+++ b/ios/chrome/test/earl_grey2/BUILD.gn
@@ -82,6 +82,7 @@
   deps = [
     "//ios/chrome/browser/autofill/model:eg2_tests",
     "//ios/chrome/browser/context_menu/ui_bundled:eg2_tests",
+    "//ios/chrome/browser/default_promo/ui_bundled:eg2_tests",
     "//ios/chrome/browser/device_sharing/model:eg2_tests",
     "//ios/chrome/browser/feature_engagement/model:eg2_tests",
     "//ios/chrome/browser/find_in_page/model:eg2_tests",
@@ -105,7 +106,6 @@
     "//ios/chrome/browser/ui/autofill/manual_fill:eg2_tests",
     "//ios/chrome/browser/ui/content_suggestions:eg2_tests",
     "//ios/chrome/browser/ui/content_suggestions/tab_resumption:eg2_tests",
-    "//ios/chrome/browser/ui/default_promo:eg2_tests",
     "//ios/chrome/browser/ui/incognito_reauth:eg2_tests",
     "//ios/chrome/browser/ui/integration_tests:eg2_tests",
     "//ios/chrome/browser/ui/push_notification:eg2_tests",
@@ -170,6 +170,7 @@
 
   deps = [
     "//ios/chrome/browser/signin/model:eg2_tests",
+    "//ios/chrome/browser/ui/authentication/account_switching:eg2_tests",
     "//ios/chrome/browser/ui/authentication/signin:eg2_tests",
     "//ios/chrome/browser/ui/authentication/signin/consistency_promo_signin:eg2_tests",
     "//ios/chrome/browser/ui/authentication/signin/forced_signin:eg2_tests",
@@ -184,8 +185,10 @@
 
   deps = [
     "//ios/chrome/browser/bring_android_tabs/ui_bundled:eg2_tests",
+    "//ios/chrome/browser/browser_view/ui_bundled:eg2_tests",
     "//ios/chrome/browser/bubble/ui_bundled:eg2_tests",
     "//ios/chrome/browser/contextual_panel/ui:eg2_tests",
+    "//ios/chrome/browser/default_promo/ui_bundled/post_restore:eg2_tests",
     "//ios/chrome/browser/dialogs/ui_bundled:eg2_tests",
     "//ios/chrome/browser/download/ui_bundled:eg2_tests",
     "//ios/chrome/browser/passwords/ui_bundled:eg2_tests",
@@ -197,9 +200,7 @@
     "//ios/chrome/browser/ui/autofill/authentication:eg2_tests",
     "//ios/chrome/browser/ui/autofill/bottom_sheet:eg2_tests",
     "//ios/chrome/browser/ui/autofill/form_input_accessory:eg2_tests",
-    "//ios/chrome/browser/ui/browser_view:eg2_tests",
     "//ios/chrome/browser/ui/content_suggestions/safety_check:eg2_tests",
-    "//ios/chrome/browser/ui/default_promo/post_restore:eg2_tests",
     "//ios/chrome/browser/ui/find_bar:eg2_tests",
     "//ios/chrome/browser/ui/first_run:eg2_tests",
     "//ios/chrome/browser/ui/first_run/omnibox_position:eg2_tests",
diff --git a/ios/chrome/test/earl_grey2/smoke_egtest.mm b/ios/chrome/test/earl_grey2/smoke_egtest.mm
index b3fe912..241915f 100644
--- a/ios/chrome/test/earl_grey2/smoke_egtest.mm
+++ b/ios/chrome/test/earl_grey2/smoke_egtest.mm
@@ -90,9 +90,16 @@
                                    chrome_test_util::SettingsDoneButton(),
                                    grey_sufficientlyVisible(), nil)]
       performAction:grey_tap()];
-  // Close Password Manager.
-  [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsDoneButton()]
-      performAction:grey_tap()];
+
+  // TODO(crbug.com/347330366): The mock reauth is somehow interfering with the
+  // left and right navigation buttons appearing.  Instead, skip this step on
+  // iOS18 until fixed.
+  if (@available(iOS 18, *)) {
+  } else {
+    // Close Password Manager.
+    [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsDoneButton()]
+        performAction:grey_tap()];
+  }
 
   // Remove mock to keep the app in the same state as before running the test.
   [PasswordSettingsAppInterface removeMockReauthenticationModule];
@@ -266,6 +273,11 @@
   [ChromeEarlGrey openNewIncognitoTab];
   [ChromeEarlGrey openNewTab];
   [ChromeEarlGrey loadURL:GURL("chrome://about")];
+  if (@available(iOS 18, *)) {
+    // TODO(crbug.com/347443965): Something is broken here on iOS18 and this
+    // test doesn't seem to be syncing chrome://about to disk.
+    sleep(3);
+  }
   [[AppLaunchManager sharedManager] ensureAppLaunchedWithFeaturesEnabled:{}
       disabled:{}
       relaunchPolicy:ForceRelaunchByKilling];
diff --git a/ios/components/security_interstitials/safe_browsing/url_checker_delegate_impl.h b/ios/components/security_interstitials/safe_browsing/url_checker_delegate_impl.h
index b6600c3..ad9dc48 100644
--- a/ios/components/security_interstitials/safe_browsing/url_checker_delegate_impl.h
+++ b/ios/components/security_interstitials/safe_browsing/url_checker_delegate_impl.h
@@ -37,11 +37,9 @@
       const security_interstitials::UnsafeResource& resource,
       const std::string& method,
       const net::HttpRequestHeaders& headers,
-      bool is_main_frame,
       bool has_user_gesture) override;
   void StartObservingInteractionsForDelayedBlockingPageHelper(
-      const security_interstitials::UnsafeResource& resource,
-      bool is_main_frame) override;
+      const security_interstitials::UnsafeResource& resource) override;
   bool IsUrlAllowlisted(const GURL& url) override;
   void SetPolicyAllowlistDomains(
       const std::vector<std::string>& allowlist_domains) override;
diff --git a/ios/components/security_interstitials/safe_browsing/url_checker_delegate_impl.mm b/ios/components/security_interstitials/safe_browsing/url_checker_delegate_impl.mm
index 4aba3da..69fb094 100644
--- a/ios/components/security_interstitials/safe_browsing/url_checker_delegate_impl.mm
+++ b/ios/components/security_interstitials/safe_browsing/url_checker_delegate_impl.mm
@@ -89,7 +89,6 @@
     const security_interstitials::UnsafeResource& resource,
     const std::string& method,
     const net::HttpRequestHeaders& headers,
-    bool is_main_frame,
     bool has_user_gesture) {
   // Query the allow list on the UI thread to determine whether the navigation
   // can proceed.
@@ -100,8 +99,7 @@
 
 void UrlCheckerDelegateImpl::
     StartObservingInteractionsForDelayedBlockingPageHelper(
-        const security_interstitials::UnsafeResource& resource,
-        bool is_main_frame) {}
+        const security_interstitials::UnsafeResource& resource) {}
 
 bool UrlCheckerDelegateImpl::IsUrlAllowlisted(const GURL& url) {
   return false;
diff --git a/ios/components/security_interstitials/safe_browsing/url_checker_delegate_impl_unittest.mm b/ios/components/security_interstitials/safe_browsing/url_checker_delegate_impl_unittest.mm
index b2eef9b7..69b3d4d 100644
--- a/ios/components/security_interstitials/safe_browsing/url_checker_delegate_impl_unittest.mm
+++ b/ios/components/security_interstitials/safe_browsing/url_checker_delegate_impl_unittest.mm
@@ -120,7 +120,6 @@
   // Instruct the delegate to display the blocking page.
   delegate_->StartDisplayingBlockingPageHelper(resource, /*method=*/"",
                                                net::HttpRequestHeaders(),
-                                               /*is_main_frame*/ true,
                                                /*has_user_gesture=*/true);
   EXPECT_TRUE(WaitForUnsafeResourceCallbackExecution(&callback_state));
 
@@ -142,7 +141,6 @@
   // Instruct the delegate to display the blocking page.
   delegate_->StartDisplayingBlockingPageHelper(resource, /*method=*/"",
                                                net::HttpRequestHeaders(),
-                                               /*is_main_frame*/ true,
                                                /*has_user_gesture=*/true);
   EXPECT_TRUE(WaitForUnsafeResourceCallbackExecution(&callback_state));
 
@@ -169,7 +167,6 @@
   // Instruct the delegate to display the blocking page.
   delegate_->StartDisplayingBlockingPageHelper(resource, /*method=*/"",
                                                net::HttpRequestHeaders(),
-                                               /*is_main_frame*/ true,
                                                /*has_user_gesture=*/true);
   EXPECT_TRUE(WaitForUnsafeResourceCallbackExecution(&callback_state));
 
diff --git a/ios/web/content/web_state/content_web_state.mm b/ios/web/content/web_state/content_web_state.mm
index dec19ca..c0a37786 100644
--- a/ios/web/content/web_state/content_web_state.mm
+++ b/ios/web/content/web_state/content_web_state.mm
@@ -282,7 +282,11 @@
   return weak_factory_.GetWeakPtr();
 }
 
-void ContentWebState::OpenURL(const OpenURLParams& params) {}
+void ContentWebState::OpenURL(const OpenURLParams& params) {
+  if (delegate_) {
+    delegate_->OpenURLFromWebState(this, params);
+  }
+}
 
 void ContentWebState::LoadSimulatedRequest(const GURL& url,
                                            NSString* response_html_string) {}
diff --git a/ios/web/web_state/web_state_unittest.mm b/ios/web/web_state/web_state_unittest.mm
index 19a3eae..ac9d0eb 100644
--- a/ios/web/web_state/web_state_unittest.mm
+++ b/ios/web/web_state/web_state_unittest.mm
@@ -561,8 +561,15 @@
     NavigationItem* item = navigation_manager->GetItemAtIndex(i);
     EXPECT_EQ(GURL(base::StringPrintf("http://www.%u.com", i)),
               item->GetVirtualURL());
-    EXPECT_EQ(base::ASCIIToUTF16(base::StringPrintf("Test%u", i)),
-              item->GetTitle());
+    // TODO(crbug.com/347207400): Remove iOS18 condition as soon as deprecation
+    // is reverted.
+    if (@available(iOS 18.0, *)) {
+    } else {
+      EXPECT_EQ(base::ASCIIToUTF16(base::StringPrintf("Test%u", i)),
+                item->GetTitle());
+      EXPECT_EQ(base::ASCIIToUTF16(base::StringPrintf("Test%u", i)),
+                item->GetTitleForDisplay());
+    }
   }
 }
 
diff --git a/ios/web_view/internal/autofill/cwv_autofill_controller_unittest.mm b/ios/web_view/internal/autofill/cwv_autofill_controller_unittest.mm
index 02ac8308..22c9c6b 100644
--- a/ios/web_view/internal/autofill/cwv_autofill_controller_unittest.mm
+++ b/ios/web_view/internal/autofill/cwv_autofill_controller_unittest.mm
@@ -155,7 +155,7 @@
       suggestionWithValue:kTestFieldValue
        displayDescription:kTestDisplayDescription
                      icon:nil
-              popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                     type:autofill::SuggestionType::kAutocompleteEntry
         backendIdentifier:nil
            requiresReauth:NO];
   [autofill_agent_ addSuggestion:suggestion
@@ -202,7 +202,7 @@
       suggestionWithValue:kTestFieldValue
        displayDescription:nil
                      icon:nil
-              popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                     type:autofill::SuggestionType::kAutocompleteEntry
         backendIdentifier:nil
            requiresReauth:NO];
   OCMExpect([password_controller_
@@ -252,7 +252,7 @@
       suggestionWithValue:kTestFieldValue
        displayDescription:nil
                      icon:nil
-              popupItemId:autofill::SuggestionType::kAutocompleteEntry
+                     type:autofill::SuggestionType::kAutocompleteEntry
         backendIdentifier:nil
            requiresReauth:NO];
   CWVAutofillSuggestion* suggestion =
diff --git a/ios/web_view/internal/autofill/cwv_autofill_suggestion_unittest.mm b/ios/web_view/internal/autofill/cwv_autofill_suggestion_unittest.mm
index 00d6dc2..6c600cf 100644
--- a/ios/web_view/internal/autofill/cwv_autofill_suggestion_unittest.mm
+++ b/ios/web_view/internal/autofill/cwv_autofill_suggestion_unittest.mm
@@ -24,7 +24,7 @@
       suggestionWithValue:@"TestValue"
        displayDescription:@"TestDisplayDescription"
                      icon:nil
-              popupItemId:autofill::SuggestionType::kAddressEntry
+                     type:autofill::SuggestionType::kAddressEntry
         backendIdentifier:nil
            requiresReauth:NO];
   CWVAutofillSuggestion* suggestion =
diff --git a/ios_internal b/ios_internal
index 5effe23..1bcfec0 160000
--- a/ios_internal
+++ b/ios_internal
@@ -1 +1 @@
-Subproject commit 5effe237b43d0d5ec9c1fa2d85b806904da4858a
+Subproject commit 1bcfec0bcdfd92bbf39cddde202d6f63156cc6dd
diff --git a/ipc/message_view.h b/ipc/message_view.h
index a8b43675..645a1d584 100644
--- a/ipc/message_view.h
+++ b/ipc/message_view.h
@@ -10,6 +10,7 @@
 
 #include "base/component_export.h"
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "ipc/ipc_message.h"
 #include "mojo/public/interfaces/bindings/native_struct.mojom-forward.h"
 
@@ -34,7 +35,7 @@
   std::optional<std::vector<mojo::native::SerializedHandlePtr>> TakeHandles();
 
  private:
-  base::span<const uint8_t> bytes_;
+  base::raw_span<const uint8_t> bytes_;
   std::optional<std::vector<mojo::native::SerializedHandlePtr>> handles_;
 };
 
diff --git a/media/base/audio_buffer.cc b/media/base/audio_buffer.cc
index 23b017392..3ccfd50 100644
--- a/media/base/audio_buffer.cc
+++ b/media/base/audio_buffer.cc
@@ -16,6 +16,13 @@
 
 namespace media {
 
+AudioBuffer::ExternalMemory::ExternalMemory() = default;
+AudioBuffer::ExternalMemory::ExternalMemory(base::span<uint8_t> span)
+    : span_(span) {}
+AudioBuffer::ExternalMemory::~ExternalMemory() = default;
+AudioBuffer::ExternalMemory::ExternalMemory(const ExternalMemory&) = default;
+AudioBuffer::ExternalMemory::ExternalMemory(ExternalMemory&&) = default;
+
 namespace {
 
 // TODO(crbug.com/41258600): Use vector instructions to speed this up.
diff --git a/media/base/audio_buffer.h b/media/base/audio_buffer.h
index cab597e..7710776 100644
--- a/media/base/audio_buffer.h
+++ b/media/base/audio_buffer.h
@@ -15,6 +15,7 @@
 
 #include "base/containers/span.h"
 #include "base/memory/aligned_memory.h"
+#include "base/memory/raw_span.h"
 #include "base/memory/ref_counted.h"
 #include "base/synchronization/lock.h"
 #include "base/thread_annotations.h"
@@ -46,13 +47,16 @@
  public:
   struct MEDIA_EXPORT ExternalMemory {
    public:
-    explicit ExternalMemory(base::span<uint8_t> span) : span_(span) {}
-    virtual ~ExternalMemory() = default;
-    base::span<uint8_t>& span() { return span_; }
+    explicit ExternalMemory(base::span<uint8_t> span);
+    virtual ~ExternalMemory();
+    ExternalMemory(const ExternalMemory&);
+    ExternalMemory(ExternalMemory&&);
+
+    base::span<uint8_t> span() { return span_; }
 
    protected:
-    ExternalMemory() = default;
-    base::span<uint8_t> span_;
+    ExternalMemory();
+    base::raw_span<uint8_t, DanglingUntriaged> span_;
   };
 
   // Create an AudioBuffer whose channel data is copied from |data|. For
diff --git a/media/base/decoder_buffer.cc b/media/base/decoder_buffer.cc
index ac8a2a36..1392f675 100644
--- a/media/base/decoder_buffer.cc
+++ b/media/base/decoder_buffer.cc
@@ -251,4 +251,8 @@
   return memory_usage;
 }
 
+DecoderBuffer::ExternalMemory::ExternalMemory(base::span<const uint8_t> span)
+    : span_(span) {}
+DecoderBuffer::ExternalMemory::~ExternalMemory() = default;
+DecoderBuffer::ExternalMemory::ExternalMemory() = default;
 }  // namespace media
diff --git a/media/base/decoder_buffer.h b/media/base/decoder_buffer.h
index a8c39788..a6e9daa0 100644
--- a/media/base/decoder_buffer.h
+++ b/media/base/decoder_buffer.h
@@ -17,6 +17,7 @@
 #include "base/check.h"
 #include "base/containers/heap_array.h"
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "base/memory/read_only_shared_memory_region.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/shared_memory_mapping.h"
@@ -46,13 +47,13 @@
   // class cannot be included in //media/base.
   struct MEDIA_EXPORT ExternalMemory {
    public:
-    explicit ExternalMemory(base::span<const uint8_t> span) : span_(span) {}
-    virtual ~ExternalMemory() = default;
-    const base::span<const uint8_t>& span() const { return span_; }
+    explicit ExternalMemory(base::span<const uint8_t> span);
+    virtual ~ExternalMemory();
+    const base::span<const uint8_t> span() const { return span_; }
 
    protected:
-    ExternalMemory() = default;
-    base::span<const uint8_t> span_;
+    ExternalMemory();
+    base::raw_span<const uint8_t, DanglingUntriaged> span_;
   };
 
   using DiscardPadding = std::pair<base::TimeDelta, base::TimeDelta>;
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index dd1708e..d9604ba9 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -598,12 +598,6 @@
              base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Enables creating single shared image and mailbox for multi-planar formats for
-// hardware video decoders.
-BASE_FEATURE(kUseMultiPlaneFormatForHardwareVideo,
-             "UseMultiPlaneFormatForHardwareVideo",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
-// Enables creating single shared image and mailbox for multi-planar formats for
 // software video decoders.
 BASE_FEATURE(kUseMultiPlaneFormatForSoftwareVideo,
              "UseMultiPlaneFormatForSoftwareVideo",
@@ -1852,10 +1846,6 @@
 #endif
 }
 
-bool IsMultiPlaneFormatForHardwareVideoEnabled() {
-  return true;
-}
-
 bool IsMultiPlaneFormatForSoftwareVideoEnabled() {
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE)
   return true;
diff --git a/media/base/media_switches.h b/media/base/media_switches.h
index d6ad6c4..cffc535 100644
--- a/media/base/media_switches.h
+++ b/media/base/media_switches.h
@@ -307,7 +307,6 @@
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kMediaPowerExperiment);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kMemoryPressureBasedSourceBufferGC);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseWritePixelsYUV);
-MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseMultiPlaneFormatForHardwareVideo);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseMultiPlaneFormatForSoftwareVideo);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kOverlayFullscreenVideo);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kPauseBackgroundMutedAudio);
diff --git a/media/capture/video/win/gpu_memory_buffer_tracker_win.cc b/media/capture/video/win/gpu_memory_buffer_tracker_win.cc
index 1b72995..13846b3f9 100644
--- a/media/capture/video/win/gpu_memory_buffer_tracker_win.cc
+++ b/media/capture/video/win/gpu_memory_buffer_tracker_win.cc
@@ -4,8 +4,11 @@
 
 #include "media/capture/video/win/gpu_memory_buffer_tracker_win.h"
 
+#include <dxgi1_2.h>
+
 #include "base/check.h"
 #include "base/logging.h"
+#include "base/memory/raw_span.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/notreached.h"
 #include "base/trace_event/trace_event.h"
@@ -16,8 +19,6 @@
 #include "media/capture/video/video_capture_buffer_handle.h"
 #include "ui/gfx/geometry/size.h"
 
-#include <dxgi1_2.h>
-
 namespace media {
 
 namespace {
@@ -38,7 +39,7 @@
   }
 
  private:
-  base::span<uint8_t> data_;
+  base::raw_span<uint8_t> data_;
   HANDLE dxgi_handle_;
   raw_ptr<ID3D11Device> d3d11_device_;
 };
diff --git a/media/cdm/aes_cbc_crypto_unittest.cc b/media/cdm/aes_cbc_crypto_unittest.cc
index 97ec5c0..13244fb 100644
--- a/media/cdm/aes_cbc_crypto_unittest.cc
+++ b/media/cdm/aes_cbc_crypto_unittest.cc
@@ -8,6 +8,7 @@
 #include <optional>
 
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "crypto/encryptor.h"
 #include "crypto/symmetric_key.h"
 #include "media/base/decoder_buffer.h"
@@ -94,7 +95,7 @@
   // Constants for testing.
   std::unique_ptr<crypto::SymmetricKey> key1_;
   std::unique_ptr<crypto::SymmetricKey> key2_;
-  base::span<const uint8_t> iv_;
+  base::raw_span<const uint8_t> iv_;
   const std::vector<uint8_t> one_block_;
 };
 
diff --git a/media/formats/hls/types.cc b/media/formats/hls/types.cc
index 8792935..5bc346e 100644
--- a/media/formats/hls/types.cc
+++ b/media/formats/hls/types.cc
@@ -414,6 +414,8 @@
   }
 }
 
+AttributeMap::~AttributeMap() = default;
+
 // static
 ParseStatus::Or<VariableName> VariableName::Parse(SourceString source_str) {
   static const base::NoDestructor<re2::RE2> variable_name_regex(
diff --git a/media/formats/hls/types.h b/media/formats/hls/types.h
index e9863f7..4d9da914 100644
--- a/media/formats/hls/types.h
+++ b/media/formats/hls/types.h
@@ -9,6 +9,7 @@
 #include <optional>
 
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "base/time/time.h"
 #include "media/formats/hls/parse_status.h"
 #include "media/formats/hls/source_string.h"
@@ -361,8 +362,10 @@
     return {{{keys, std::nullopt}...}};
   }
 
+  ~AttributeMap();
+
  private:
-  base::span<Item> items_;
+  base::raw_span<Item> items_;
 };
 
 // Represents a string that is guaranteed to be a non-empty, and consisting only
diff --git a/media/formats/mp4/box_reader.cc b/media/formats/mp4/box_reader.cc
index 3bdea990..893e312 100644
--- a/media/formats/mp4/box_reader.cc
+++ b/media/formats/mp4/box_reader.cc
@@ -18,6 +18,16 @@
 
 Box::~Box() = default;
 
+BufferReader::BufferReader(const uint8_t* buf, const size_t buf_size)
+    :  // TODO(crbug.com/40284755): BufferReader should be receiving a span,
+       // the construction of the span here is unsound as there's no way to
+       // tell the size is correct from here.
+      UNSAFE_BUFFERS(buf_(buf, buf_size)) {}
+
+BufferReader::~BufferReader() = default;
+
+BufferReader::BufferReader(const BufferReader& other) = default;
+
 bool BufferReader::Read1(uint8_t* v) {
   RCHECK(HasBytes(1));
   *v = base::numerics::U8FromBigEndian(buf_.subspan(pos_).first<1u>());
diff --git a/media/formats/mp4/box_reader.h b/media/formats/mp4/box_reader.h
index fdeac25..03235545 100644
--- a/media/formats/mp4/box_reader.h
+++ b/media/formats/mp4/box_reader.h
@@ -15,6 +15,7 @@
 #include "base/containers/span.h"
 #include "base/logging.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_span.h"
 #include "base/numerics/safe_conversions.h"
 #include "media/base/media_export.h"
 #include "media/base/media_log.h"
@@ -46,12 +47,9 @@
 
 class MEDIA_EXPORT BufferReader {
  public:
-  BufferReader(const uint8_t* buf, const size_t buf_size)
-      :  // TODO(crbug.com/40284755): BufferReader should be receiving a span,
-         // the construction of the span here is unsound as there's no way to
-         // tell the size is correct from here.
-        UNSAFE_BUFFERS(buf_(buf, buf_size)) {}
-
+  BufferReader(const uint8_t* buf, const size_t buf_size);
+  BufferReader(const BufferReader& other);
+  virtual ~BufferReader();
   bool HasBytes(size_t count) {
     // As the size of a box is implementation limited to 2^31, fail if
     // attempting to check for too many bytes.
@@ -95,7 +93,7 @@
   size_t pos() const { return pos_; }
 
  protected:
-  base::span<const uint8_t> buf_;
+  base::raw_span<const uint8_t> buf_;
   // The position in `buf_` where the next read is from.
   size_t pos_ = 0u;
 };
@@ -103,7 +101,7 @@
 class MEDIA_EXPORT BoxReader : public BufferReader {
  public:
   BoxReader(const BoxReader& other);
-  ~BoxReader();
+  ~BoxReader() override;
 
   // Create a BoxReader from a buffer. If the result is kOk, then |out_reader|
   // will be set, otherwise |out_reader| will be unchanged.
diff --git a/media/gpu/h264_decoder.h b/media/gpu/h264_decoder.h
index 978732f..7d9d14c4 100644
--- a/media/gpu/h264_decoder.h
+++ b/media/gpu/h264_decoder.h
@@ -13,6 +13,7 @@
 
 #include "base/containers/span.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_span.h"
 #include "base/memory/scoped_refptr.h"
 #include "media/base/limits.h"
 #include "media/base/subsample_entry.h"
@@ -414,7 +415,8 @@
   // Encrypted NALUs preceding a fully encrypted (CENCv1) slice NALU. We need to
   // save these that are part of a single sample so they can all be decrypted
   // together.
-  std::vector<base::span<const uint8_t>> prior_cencv1_nalus_;
+  std::vector<base::raw_span<const uint8_t, DanglingUntriaged>>
+      prior_cencv1_nalus_;
   std::vector<SubsampleEntry> prior_cencv1_subsamples_;
 
   // These are std::nullopt unless get recovery point SEI message after Reset.
diff --git a/media/gpu/windows/scoped_d3d_buffers.cc b/media/gpu/windows/scoped_d3d_buffers.cc
index d8691a63..8846981 100644
--- a/media/gpu/windows/scoped_d3d_buffers.cc
+++ b/media/gpu/windows/scoped_d3d_buffers.cc
@@ -8,6 +8,9 @@
 
 namespace media {
 
+ScopedD3DBuffer::ScopedD3DBuffer(base::span<uint8_t> data) : data_(data) {}
+ScopedD3DBuffer::~ScopedD3DBuffer() = default;
+
 D3DInputBuffer::D3DInputBuffer(std::unique_ptr<ScopedD3DBuffer> buffer)
     : buffer_(std::move(buffer)) {}
 
diff --git a/media/gpu/windows/scoped_d3d_buffers.h b/media/gpu/windows/scoped_d3d_buffers.h
index a2605c12..ecc630d 100644
--- a/media/gpu/windows/scoped_d3d_buffers.h
+++ b/media/gpu/windows/scoped_d3d_buffers.h
@@ -6,9 +6,11 @@
 #define MEDIA_GPU_WINDOWS_SCOPED_D3D_BUFFERS_H_
 
 #include <Windows.h>
+
 #include <memory>
 
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "media/gpu/media_gpu_export.h"
 
 namespace media {
@@ -16,10 +18,10 @@
 // The base class for a scoped buffer, which do buffer allocation in the
 // constructor and release the buffer in Commit() or destructor. In case of
 // any failure, the empty() should be true.
-class ScopedD3DBuffer {
+class MEDIA_GPU_EXPORT ScopedD3DBuffer {
  public:
-  explicit ScopedD3DBuffer(base::span<uint8_t> data = {}) : data_(data) {}
-  virtual ~ScopedD3DBuffer() = default;
+  explicit ScopedD3DBuffer(base::span<uint8_t> data = {});
+  virtual ~ScopedD3DBuffer();
   uint8_t* data() { return data_.data(); }
   size_t size() const { return data_.size(); }
   bool empty() const { return data_.empty(); }
@@ -35,7 +37,7 @@
   virtual bool Commit(uint32_t written_size) = 0;
 
  protected:
-  base::span<uint8_t> data_;
+  base::raw_span<uint8_t, DanglingUntriaged> data_;
 };
 
 // This class provides basic interface for getting the buffer's attribute.
diff --git a/mojo/core/ipcz_driver/mojo_message.h b/mojo/core/ipcz_driver/mojo_message.h
index aac686b..4c6bfc9 100644
--- a/mojo/core/ipcz_driver/mojo_message.h
+++ b/mojo/core/ipcz_driver/mojo_message.h
@@ -13,6 +13,7 @@
 #include "base/containers/span.h"
 #include "base/memory/nonscannable_memory.h"
 #include "base/memory/ptr_util.h"
+#include "base/memory/raw_span.h"
 #include "mojo/core/scoped_ipcz_handle.h"
 #include "mojo/public/c/system/message_pipe.h"
 #include "mojo/public/c/system/types.h"
@@ -135,7 +136,7 @@
 
   // A view into the message data, whether it's backed by `parcel_` or stored in
   // `data_storage_`.
-  base::span<uint8_t> data_;
+  base::raw_span<uint8_t, DanglingUntriaged> data_;
 
   std::vector<IpczHandle> handles_;
   bool handles_consumed_ = false;
diff --git a/mojo/public/cpp/base/big_buffer.h b/mojo/public/cpp/base/big_buffer.h
index c155d019..e8e9269 100644
--- a/mojo/public/cpp/base/big_buffer.h
+++ b/mojo/public/cpp/base/big_buffer.h
@@ -12,6 +12,7 @@
 #include "base/component_export.h"
 #include "base/containers/heap_array.h"
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "mojo/public/cpp/bindings/struct_traits.h"
 #include "mojo/public/cpp/system/buffer.h"
 
@@ -210,7 +211,7 @@
 
  private:
   BigBuffer::StorageType storage_type_ = BigBuffer::StorageType::kBytes;
-  base::span<const uint8_t> bytes_;
+  base::raw_span<const uint8_t> bytes_;
   std::optional<internal::BigBufferSharedMemoryRegion> shared_memory_;
 };
 
diff --git a/mojo/public/cpp/bindings/interface_endpoint_client.h b/mojo/public/cpp/bindings/interface_endpoint_client.h
index 0e8a3bc5..ed0f7c6 100644
--- a/mojo/public/cpp/bindings/interface_endpoint_client.h
+++ b/mojo/public/cpp/bindings/interface_endpoint_client.h
@@ -20,6 +20,7 @@
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/raw_ptr_exclusion.h"
+#include "base/memory/raw_span.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
@@ -289,7 +290,7 @@
 
   bool HandleValidatedMessage(Message* message);
 
-  const base::span<const uint32_t> sync_method_ordinals_;
+  const base::raw_span<const uint32_t> sync_method_ordinals_;
 
   // The callback to invoke when our peer endpoint sends us NotifyIdle and we
   // have no outstanding unacked messages. If null, no callback has been set and
diff --git a/net/cert/x509_util.h b/net/cert/x509_util.h
index 30d18af0..25be9fe 100644
--- a/net/cert/x509_util.h
+++ b/net/cert/x509_util.h
@@ -13,6 +13,7 @@
 #include <vector>
 
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/time/time.h"
 #include "crypto/signature_verifier.h"
@@ -96,9 +97,9 @@
   ~Extension();
   Extension(const Extension&);
 
-  base::span<const uint8_t> oid;
+  base::raw_span<const uint8_t> oid;
   bool critical;
-  base::span<const uint8_t> contents;
+  base::raw_span<const uint8_t> contents;
 };
 
 // Create a certificate signed by |issuer_key| and write it to |der_encoded|.
diff --git a/net/cert/x509_util_unittest.cc b/net/cert/x509_util_unittest.cc
index 8956ba9..ec08f6a 100644
--- a/net/cert/x509_util_unittest.cc
+++ b/net/cert/x509_util_unittest.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <memory>
 
+#include "base/memory/raw_span.h"
 #include "base/memory/ref_counted.h"
 #include "base/time/time.h"
 #include "crypto/rsa_private_key.h"
@@ -724,7 +725,7 @@
   struct Test {
     const char* cert;
     crypto::SignatureVerifier::SignatureAlgorithm algorithm;
-    base::span<const uint8_t> signature;
+    base::raw_span<const uint8_t> signature;
     bool ok;
   } kTests[] = {
       // The certificate must support the digitalSignature key usage.
diff --git a/net/dns/dns_response.cc b/net/dns/dns_response.cc
index de2221cd..7a4f3b5 100644
--- a/net/dns/dns_response.cc
+++ b/net/dns/dns_response.cc
@@ -125,6 +125,16 @@
 
 DnsRecordParser::DnsRecordParser() = default;
 
+DnsRecordParser::~DnsRecordParser() = default;
+
+DnsRecordParser::DnsRecordParser(const DnsRecordParser&) = default;
+
+DnsRecordParser::DnsRecordParser(DnsRecordParser&&) = default;
+
+DnsRecordParser& DnsRecordParser::operator=(const DnsRecordParser&) = default;
+
+DnsRecordParser& DnsRecordParser::operator=(DnsRecordParser&&) = default;
+
 DnsRecordParser::DnsRecordParser(base::span<const uint8_t> packet,
                                  size_t offset,
                                  size_t num_records)
diff --git a/net/dns/dns_response.h b/net/dns/dns_response.h
index 501546c..b6ce4de 100644
--- a/net/dns/dns_response.h
+++ b/net/dns/dns_response.h
@@ -16,6 +16,7 @@
 #include "base/compiler_specific.h"
 #include "base/containers/span.h"
 #include "base/containers/span_writer.h"
+#include "base/memory/raw_span.h"
 #include "base/memory/scoped_refptr.h"
 #include "net/base/net_export.h"
 #include "net/dns/dns_response_result_extractor.h"
@@ -83,6 +84,13 @@
                                       size_t offset,
                                       size_t num_records);
 
+  DnsRecordParser(const DnsRecordParser&);
+  DnsRecordParser(DnsRecordParser&&);
+  DnsRecordParser& operator=(const DnsRecordParser&);
+  DnsRecordParser& operator=(DnsRecordParser&&);
+
+  ~DnsRecordParser();
+
   // Returns |true| if initialized.
   bool IsValid() const { return !packet_.empty(); }
 
@@ -110,7 +118,7 @@
   bool ReadQuestion(std::string& out_dotted_qname, uint16_t& out_qtype);
 
  private:
-  base::span<const uint8_t> packet_;
+  base::raw_span<const uint8_t> packet_;
   size_t num_records_ = 0u;
   size_t num_records_parsed_ = 0u;
   // Current offset within the packet.
diff --git a/net/dns/host_resolver_dns_task.cc b/net/dns/host_resolver_dns_task.cc
index 77b56a0..2c14414 100644
--- a/net/dns/host_resolver_dns_task.cc
+++ b/net/dns/host_resolver_dns_task.cc
@@ -631,8 +631,9 @@
     // Sort() potentially calls OnTransactionSorted() synchronously.
     client_->GetAddressSorter()->Sort(
         endpoints_to_sort,
-        base::BindOnce(&HostResolverDnsTask::OnTransactionSorted, AsWeakPtr(),
-                       insertion_result.first, std::move(transaction_results)));
+        base::BindOnce(&HostResolverDnsTask::OnTransactionSorted,
+                       weak_ptr_factory_.GetWeakPtr(), insertion_result.first,
+                       std::move(transaction_results)));
   } else {
     HandleTransactionResults(std::move(transaction_info),
                              std::move(transaction_results));
@@ -831,7 +832,8 @@
       // Sort addresses if needed.  Sort could complete synchronously.
       client_->GetAddressSorter()->Sort(
           ip_endpoints,
-          base::BindOnce(&HostResolverDnsTask::OnSortComplete, AsWeakPtr(),
+          base::BindOnce(&HostResolverDnsTask::OnSortComplete,
+                         weak_ptr_factory_.GetWeakPtr(),
                          tick_clock_->NowTicks(), std::move(results), secure_));
       return;
     }
diff --git a/net/dns/host_resolver_dns_task.h b/net/dns/host_resolver_dns_task.h
index 48c1a2f..388546a 100644
--- a/net/dns/host_resolver_dns_task.h
+++ b/net/dns/host_resolver_dns_task.h
@@ -40,8 +40,7 @@
 // a DNS stub resolver. One DnsTransaction is created for each resolution
 // needed, which for AF_UNSPEC resolutions includes both A and AAAA. The
 // transactions are scheduled separately and started separately.
-class NET_EXPORT_PRIVATE HostResolverDnsTask
-    : public base::SupportsWeakPtr<HostResolverDnsTask> {
+class NET_EXPORT_PRIVATE HostResolverDnsTask final {
  public:
   using Results = std::set<std::unique_ptr<HostResolverInternalResult>>;
 
@@ -114,6 +113,10 @@
 
   void StartNextTransaction();
 
+  base::WeakPtr<HostResolverDnsTask> AsWeakPtr() {
+    return weak_ptr_factory_.GetWeakPtr();
+  }
+
  private:
   enum class TransactionErrorBehavior {
     // Errors lead to task fallback (immediately unless another pending/started
@@ -258,6 +261,8 @@
   bool fallback_available_;
 
   const HostResolver::HttpsSvcbOptions https_svcb_options_;
+
+  base::WeakPtrFactory<HostResolverDnsTask> weak_ptr_factory_{this};
 };
 
 }  // namespace net
diff --git a/net/dns/mdns_client_impl.cc b/net/dns/mdns_client_impl.cc
index 9d6d8b9..8ad8398 100644
--- a/net/dns/mdns_client_impl.cc
+++ b/net/dns/mdns_client_impl.cc
@@ -423,7 +423,7 @@
     // happens while iterating over the observer list.
     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
         FROM_HERE, base::BindOnce(&MDnsClientImpl::Core::CleanupObserverList,
-                                  AsWeakPtr(), key));
+                                  weak_ptr_factory_.GetWeakPtr(), key));
   }
 }
 
@@ -628,8 +628,8 @@
     return;
   }
 
-  next_refresh_.Reset(
-      base::BindRepeating(&MDnsListenerImpl::DoRefresh, AsWeakPtr()));
+  next_refresh_.Reset(base::BindRepeating(&MDnsListenerImpl::DoRefresh,
+                                          weak_ptr_factory_.GetWeakPtr()));
 
   // Schedule refreshes at both 85% and 95% of the original TTL. These will both
   // be canceled and rescheduled if the record's TTL is updated due to a
@@ -680,7 +680,7 @@
   DCHECK(!started_);
   started_ = true;
 
-  base::WeakPtr<MDnsTransactionImpl> weak_this = AsWeakPtr();
+  base::WeakPtr<MDnsTransactionImpl> weak_this = weak_ptr_factory_.GetWeakPtr();
   if (flags_ & MDnsTransaction::QUERY_CACHE) {
     ServeRecordsFromCache();
 
@@ -754,7 +754,7 @@
 
 void MDnsTransactionImpl::ServeRecordsFromCache() {
   std::vector<const RecordParsed*> records;
-  base::WeakPtr<MDnsTransactionImpl> weak_this = AsWeakPtr();
+  base::WeakPtr<MDnsTransactionImpl> weak_this = weak_ptr_factory_.GetWeakPtr();
 
   if (client_->core()) {
     client_->core()->QueryCache(rrtype_, name_, &records);
@@ -788,8 +788,8 @@
   if (!client_->core()->SendQuery(rrtype_, name_))
     return false;
 
-  timeout_.Reset(
-      base::BindOnce(&MDnsTransactionImpl::SignalTransactionOver, AsWeakPtr()));
+  timeout_.Reset(base::BindOnce(&MDnsTransactionImpl::SignalTransactionOver,
+                                weak_ptr_factory_.GetWeakPtr()));
   base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
       FROM_HERE, timeout_.callback(), kTransactionTimeout);
 
diff --git a/net/dns/mdns_client_impl.h b/net/dns/mdns_client_impl.h
index bc98f70..1b0b0a5 100644
--- a/net/dns/mdns_client_impl.h
+++ b/net/dns/mdns_client_impl.h
@@ -17,6 +17,7 @@
 #include "base/containers/queue.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "base/time/time.h"
 #include "net/base/io_buffer.h"
@@ -131,7 +132,7 @@
   // whenever the number of listeners reaches zero. The deletion happens
   // asychronously, so destroying the last listener does not immediately
   // invalidate the core.
-  class Core : public base::SupportsWeakPtr<Core>, MDnsConnection::Delegate {
+  class Core final : public MDnsConnection::Delegate {
    public:
     Core(base::Clock* clock, base::OneShotTimer* timer);
 
@@ -210,6 +211,7 @@
     base::Time scheduled_cleanup_;
 
     std::unique_ptr<MDnsConnection> connection_;
+    base::WeakPtrFactory<Core> weak_ptr_factory_{this};
   };
 
   MDnsClientImpl();
@@ -248,8 +250,7 @@
   std::unique_ptr<Core> core_;
 };
 
-class MDnsListenerImpl : public MDnsListener,
-                         public base::SupportsWeakPtr<MDnsListenerImpl> {
+class MDnsListenerImpl final : public MDnsListener {
  public:
   MDnsListenerImpl(uint16_t rrtype,
                    const std::string& name,
@@ -297,11 +298,11 @@
   bool active_refresh_ = false;
 
   base::CancelableRepeatingClosure next_refresh_;
+  base::WeakPtrFactory<MDnsListenerImpl> weak_ptr_factory_{this};
 };
 
-class MDnsTransactionImpl : public base::SupportsWeakPtr<MDnsTransactionImpl>,
-                            public MDnsTransaction,
-                            public MDnsListener::Delegate {
+class MDnsTransactionImpl final : public MDnsTransaction,
+                                  public MDnsListener::Delegate {
  public:
   MDnsTransactionImpl(uint16_t rrtype,
                       const std::string& name,
@@ -362,6 +363,7 @@
 
   bool started_ = false;
   int flags_;
+  base::WeakPtrFactory<MDnsTransactionImpl> weak_ptr_factory_{this};
 };
 
 }  // namespace net
diff --git a/net/http/transport_security_state_static.pins b/net/http/transport_security_state_static.pins
index 0518df19..02b0a26 100644
--- a/net/http/transport_security_state_static.pins
+++ b/net/http/transport_security_state_static.pins
@@ -43,9 +43,9 @@
 #   hash function for preloaded entries again (we have already done so once).
 #
 
-# Last updated: 2024-06-15 12:55 UTC
+# Last updated: 2024-06-17 12:54 UTC
 PinsListTimestamp
-1718456109
+1718628877
 
 TestSPKI
 sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/net/http/transport_security_state_static_pins.json b/net/http/transport_security_state_static_pins.json
index 377b412..27357862 100644
--- a/net/http/transport_security_state_static_pins.json
+++ b/net/http/transport_security_state_static_pins.json
@@ -31,7 +31,7 @@
 // the 'static_spki_hashes' and 'bad_static_spki_hashes' fields in 'pinsets'
 // refer to, and the timestamp at which the pins list was last updated.
 //
-// Last updated: 2024-06-15 12:55 UTC
+// Last updated: 2024-06-17 12:54 UTC
 //
 {
   "pinsets": [
diff --git a/net/ntlm/ntlm_buffer_reader.h b/net/ntlm/ntlm_buffer_reader.h
index 5c8dbb2..3c9f965 100644
--- a/net/ntlm/ntlm_buffer_reader.h
+++ b/net/ntlm/ntlm_buffer_reader.h
@@ -17,6 +17,7 @@
 
 #include "base/check.h"
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "net/base/net_export.h"
 #include "net/ntlm/ntlm_constants.h"
 
@@ -218,7 +219,7 @@
     return *(GetBufferAtCursor());
   }
 
-  base::span<const uint8_t> buffer_;
+  base::raw_span<const uint8_t> buffer_;
   size_t cursor_ = 0;
 };
 
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index db52f31..11d2c21 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -22,6 +22,7 @@
 #include "base/functional/callback.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_span.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "build/build_config.h"
@@ -436,9 +437,9 @@
   // fails if no data is available.
   const MockWrite& PeekRealWrite() const;
 
-  const base::span<const MockRead> reads_;
+  const base::raw_span<const MockRead, DanglingUntriaged> reads_;
   size_t read_index_ = 0;
-  const base::span<const MockWrite> writes_;
+  const base::raw_span<const MockWrite, DanglingUntriaged> writes_;
   size_t write_index_ = 0;
 };
 
diff --git a/net/socket/transport_client_socket_pool_test_util.h b/net/socket/transport_client_socket_pool_test_util.h
index 58295d3..643ab81 100644
--- a/net/socket/transport_client_socket_pool_test_util.h
+++ b/net/socket/transport_client_socket_pool_test_util.h
@@ -18,6 +18,7 @@
 #include "base/containers/span.h"
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_span.h"
 #include "base/time/time.h"
 #include "net/base/address_list.h"
 #include "net/socket/client_socket_factory.h"
@@ -147,7 +148,7 @@
   raw_ptr<NetLog> net_log_;
   int allocation_count_ = 0;
   Type client_socket_type_ = Type::kSynchronous;
-  base::span<const Rule> rules_;
+  base::raw_span<const Rule, DanglingUntriaged> rules_;
   base::TimeDelta delay_;
   base::queue<base::OnceClosure> triggerable_sockets_;
   base::OnceClosure run_loop_quit_closure_;
diff --git a/pdf/loader/url_loader.h b/pdf/loader/url_loader.h
index 55150aa..28edf718 100644
--- a/pdf/loader/url_loader.h
+++ b/pdf/loader/url_loader.h
@@ -14,6 +14,7 @@
 #include "base/containers/circular_deque.h"
 #include "base/containers/span.h"
 #include "base/functional/callback.h"
+#include "base/memory/raw_span.h"
 #include "base/memory/weak_ptr.h"
 #include "third_party/blink/public/web/web_associated_url_loader_client.h"
 
@@ -191,7 +192,7 @@
   base::circular_deque<char> buffer_;
 
   base::OnceCallback<void(int)> read_callback_;
-  base::span<char> client_buffer_;
+  base::raw_span<char> client_buffer_;
 };
 
 }  // namespace chrome_pdf
diff --git a/pdf/loader/url_loader_wrapper_impl.h b/pdf/loader/url_loader_wrapper_impl.h
index 8f8efd6..c71afd2 100644
--- a/pdf/loader/url_loader_wrapper_impl.h
+++ b/pdf/loader/url_loader_wrapper_impl.h
@@ -12,6 +12,7 @@
 
 #include "base/containers/span.h"
 #include "base/functional/callback_forward.h"
+#include "base/memory/raw_span.h"
 #include "base/memory/weak_ptr.h"
 #include "base/timer/timer.h"
 #include "pdf/loader/url_loader_wrapper.h"
@@ -64,7 +65,7 @@
   std::string multipart_boundary_;
   gfx::Range byte_range_ = gfx::Range::InvalidRange();
   bool is_multipart_ = false;
-  base::span<char> buffer_;
+  base::raw_span<char, DanglingUntriaged> buffer_;
   bool multi_part_processed_ = false;
 
   base::OneShotTimer read_starter_;
diff --git a/pdf/pdfium/pdfium_engine_exports.cc b/pdf/pdfium/pdfium_engine_exports.cc
index 5894130..a587fe1 100644
--- a/pdf/pdfium/pdfium_engine_exports.cc
+++ b/pdf/pdfium/pdfium_engine_exports.cc
@@ -9,6 +9,7 @@
 #include <utility>
 
 #include "base/functional/bind.h"
+#include "base/memory/raw_span.h"
 #include "base/no_destructor.h"
 #include "base/numerics/checked_math.h"
 #include "build/build_config.h"
@@ -85,7 +86,7 @@
   void ClearPendingRequests() override {}
 
  private:
-  const base::span<const uint8_t> pdf_data_;
+  const base::raw_span<const uint8_t> pdf_data_;
 };
 
 int CalculatePosition(FPDF_PAGE page,
diff --git a/ppapi/proxy/file_io_resource.cc b/ppapi/proxy/file_io_resource.cc
index d05f192..bc9e01b 100644
--- a/ppapi/proxy/file_io_resource.cc
+++ b/ppapi/proxy/file_io_resource.cc
@@ -7,6 +7,7 @@
 #include <limits>
 #include <utility>
 
+#include "base/containers/heap_array.h"
 #include "base/functional/bind.h"
 #include "ipc/ipc_message.h"
 #include "ppapi/c/pp_errors.h"
@@ -74,20 +75,18 @@
 }
 
 int32_t FileIOResource::ReadOp::DoWork() {
-  DCHECK(!buffer_.get());
-  buffer_.reset(new char[bytes_to_read_]);
-  return file_holder_->file()->Read(offset_, buffer_.get(), bytes_to_read_);
+  DCHECK(buffer_.empty());
+  buffer_ = base::HeapArray<char>::Uninit(bytes_to_read_);
+  return file_holder_->file()->Read(offset_, buffer_.data(), bytes_to_read_);
 }
 
 FileIOResource::WriteOp::WriteOp(scoped_refptr<FileHolder> file_holder,
                                  int64_t offset,
-                                 std::unique_ptr<char[]> buffer,
-                                 int32_t bytes_to_write,
+                                 base::HeapArray<char> buffer,
                                  bool append)
     : file_holder_(file_holder),
       offset_(offset),
       buffer_(std::move(buffer)),
-      bytes_to_write_(bytes_to_write),
       append_(append) {}
 
 FileIOResource::WriteOp::~WriteOp() {
@@ -97,10 +96,10 @@
   // In append mode, we can't call Write, since NaCl doesn't implement fcntl,
   // causing the function to call pwrite, which is incorrect.
   if (append_) {
-    return file_holder_->file()->WriteAtCurrentPos(buffer_.get(),
-                                                   bytes_to_write_);
+    return file_holder_->file()->WriteAtCurrentPos(buffer_.data(),
+                                                   buffer_.size());
   } else {
-    return file_holder_->file()->Write(offset_, buffer_.get(), bytes_to_write_);
+    return file_holder_->file()->Write(offset_, buffer_.data(), buffer_.size());
   }
 }
 
@@ -296,13 +295,13 @@
     if (increase > 0) {
       // Request a quota reservation. This makes the Write asynchronous, so we
       // must copy the plugin's buffer.
-      std::unique_ptr<char[]> copy(new char[bytes_to_write]);
-      memcpy(copy.get(), buffer, bytes_to_write);
+      auto copy = base::HeapArray<char>::Uninit(bytes_to_write);
+      memcpy(copy.data(), buffer, bytes_to_write);
       int64_t result =
           file_system_resource_->AsPPB_FileSystem_API()->RequestQuota(
-              increase, base::BindOnce(
-                            &FileIOResource::OnRequestWriteQuotaComplete, this,
-                            offset, std::move(copy), bytes_to_write, callback));
+              increase,
+              base::BindOnce(&FileIOResource::OnRequestWriteQuotaComplete, this,
+                             offset, std::move(copy), callback));
       if (result == PP_OK_COMPLETIONPENDING)
         return PP_OK_COMPLETIONPENDING;
       DCHECK(result == increase);
@@ -503,10 +502,10 @@
 
   // For the non-blocking case, post a task to the file thread. We must copy the
   // plugin's buffer at this point.
-  std::unique_ptr<char[]> copy(new char[bytes_to_write]);
-  memcpy(copy.get(), buffer, bytes_to_write);
-  scoped_refptr<WriteOp> write_op(new WriteOp(
-      file_holder_, offset, std::move(copy), bytes_to_write, append));
+  auto copy = base::HeapArray<char>::Uninit(bytes_to_write);
+  memcpy(copy.data(), buffer, bytes_to_write);
+  scoped_refptr<WriteOp> write_op(
+      new WriteOp(file_holder_, offset, std::move(copy), append));
   PpapiGlobals::Get()->GetFileTaskRunner()->PostTaskAndReplyWithResult(
       FROM_HERE, base::BindOnce(&FileIOResource::WriteOp::DoWork, write_op),
       RunWhileLocked(base::BindOnce(&TrackedCallback::Run, callback)));
@@ -569,10 +568,10 @@
 
 void FileIOResource::OnRequestWriteQuotaComplete(
     int64_t offset,
-    std::unique_ptr<char[]> buffer,
-    int32_t bytes_to_write,
+    base::HeapArray<char> buffer,
     scoped_refptr<TrackedCallback> callback,
     int64_t granted) {
+  const int64_t bytes_to_write = buffer.size();
   DCHECK(granted >= 0);
   if (granted == 0) {
     callback->Run(PP_ERROR_NOQUOTA);
@@ -591,13 +590,13 @@
 
   if (callback->is_blocking()) {
     int32_t result =
-        WriteValidated(offset, buffer.get(), bytes_to_write, callback);
+        WriteValidated(offset, buffer.data(), bytes_to_write, callback);
     DCHECK(result != PP_OK_COMPLETIONPENDING);
     callback->Run(result);
   } else {
     bool append = (open_flags_ & PP_FILEOPENFLAG_APPEND) != 0;
-    scoped_refptr<WriteOp> write_op(new WriteOp(
-        file_holder_, offset, std::move(buffer), bytes_to_write, append));
+    scoped_refptr<WriteOp> write_op(
+        new WriteOp(file_holder_, offset, std::move(buffer), append));
     PpapiGlobals::Get()->GetFileTaskRunner()->PostTaskAndReplyWithResult(
         FROM_HERE, base::BindOnce(&FileIOResource::WriteOp::DoWork, write_op),
         RunWhileLocked(base::BindOnce(&TrackedCallback::Run, callback)));
diff --git a/ppapi/proxy/file_io_resource.h b/ppapi/proxy/file_io_resource.h
index d723a2f..045ee56 100644
--- a/ppapi/proxy/file_io_resource.h
+++ b/ppapi/proxy/file_io_resource.h
@@ -7,8 +7,7 @@
 
 #include <stdint.h>
 
-#include <memory>
-
+#include "base/containers/heap_array.h"
 #include "base/files/file.h"
 #include "base/memory/ref_counted.h"
 #include "ppapi/c/private/pp_file_handle.h"
@@ -140,7 +139,7 @@
     // thread (blocking). This should not be called when we hold the proxy lock.
     int32_t DoWork();
 
-    char* buffer() const { return buffer_.get(); }
+    const char* buffer() const { return buffer_.data(); }
 
    private:
     friend class base::RefCountedThreadSafe<ReadOp>;
@@ -149,7 +148,7 @@
     scoped_refptr<FileHolder> file_holder_;
     int64_t offset_;
     int32_t bytes_to_read_;
-    std::unique_ptr<char[]> buffer_;
+    base::HeapArray<char> buffer_;
   };
 
   // Class to perform file write operations across multiple threads.
@@ -157,8 +156,7 @@
    public:
     WriteOp(scoped_refptr<FileHolder> file_holder,
             int64_t offset,
-            std::unique_ptr<char[]> buffer,
-            int32_t bytes_to_write,
+            base::HeapArray<char> buffer,
             bool append);
 
     // Writes the file. Called on the file thread (non-blocking) or the plugin
@@ -171,14 +169,12 @@
 
     scoped_refptr<FileHolder> file_holder_;
     int64_t offset_;
-    std::unique_ptr<char[]> buffer_;
-    int32_t bytes_to_write_;
+    base::HeapArray<char> buffer_;
     bool append_;
   };
 
   void OnRequestWriteQuotaComplete(int64_t offset,
-                                   std::unique_ptr<char[]> buffer,
-                                   int32_t bytes_to_write,
+                                   base::HeapArray<char> buffer,
                                    scoped_refptr<TrackedCallback> callback,
                                    int64_t granted);
   void OnRequestSetLengthQuotaComplete(int64_t length,
diff --git a/remoting/host/keyboard_layout_monitor_chromeos.cc b/remoting/host/keyboard_layout_monitor_chromeos.cc
index 6d1281b..0bded89 100644
--- a/remoting/host/keyboard_layout_monitor_chromeos.cc
+++ b/remoting/host/keyboard_layout_monitor_chromeos.cc
@@ -7,6 +7,7 @@
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/location.h"
+#include "base/memory/raw_span.h"
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
 #include "base/strings/utf_string_conversion_utils.h"
@@ -54,7 +55,7 @@
   LayoutKeyFunction GetFunctionFromKeyboardCode(
       ui::KeyboardCode key_code) const;
 
-  const base::span<const ui::DomCode> supported_keys_;
+  const base::raw_span<const ui::DomCode> supported_keys_;
   base::RepeatingCallback<void(const protocol::KeyboardLayout&)> callback_;
   base::ScopedObservation<ash::input_method::ImeKeyboard,
                           ash::input_method::ImeKeyboard::Observer>
diff --git a/remoting/resources/remoting_strings_en-GB.xtb b/remoting/resources/remoting_strings_en-GB.xtb
index 2221234..5643f29a 100644
--- a/remoting/resources/remoting_strings_en-GB.xtb
+++ b/remoting/resources/remoting_strings_en-GB.xtb
@@ -155,7 +155,7 @@
 <translation id="7970576581263377361">Authentication failed. Please sign in to Chromium again.</translation>
 <translation id="7981525049612125370">The remote session has expired.</translation>
 <translation id="8038111231936746805">(default)</translation>
-<translation id="8041089156583427627">Send Feedback</translation>
+<translation id="8041089156583427627">Send feedback</translation>
 <translation id="8060029310790625334">Help Centre</translation>
 <translation id="806699900641041263">Connecting to <ph name="HOSTNAME" /></translation>
 <translation id="8073845705237259513">To use Chrome Remote Desktop, you'll need to add a Google Account to your device.</translation>
diff --git a/sandbox/policy/win/sandbox_win.cc b/sandbox/policy/win/sandbox_win.cc
index a26c541..be91251 100644
--- a/sandbox/policy/win/sandbox_win.cc
+++ b/sandbox/policy/win/sandbox_win.cc
@@ -561,7 +561,6 @@
 }
 
 ResultCode GenerateConfigForSandboxedProcess(const base::CommandLine& cmd_line,
-                                             const std::string& process_type,
                                              SandboxDelegate* delegate,
                                              TargetConfig* config) {
   DCHECK(!config->IsConfigured());
@@ -611,7 +610,7 @@
   if (result != SBOX_ALL_OK)
     return result;
 
-  if (process_type == switches::kRendererProcess) {
+  if (sandbox_type == Sandbox::kRenderer) {
     // TODO(crbug.com/40088338) Remove if we can reliably not load
     // cryptbase.dll.
     config->AddKernelObjectToClose(HandleToClose::kKsecDD);
@@ -632,7 +631,7 @@
   if (result != SBOX_ALL_OK)
     return result;
 
-  if (process_type == switches::kGpuProcess) {
+  if (sandbox_type == Sandbox::kGpu) {
     config->SetLockdownDefaultDacl();
     config->AddRestrictingRandomSid();
   }
@@ -928,7 +927,6 @@
 // static
 ResultCode SandboxWin::GeneratePolicyForSandboxedProcess(
     const base::CommandLine& cmd_line,
-    const std::string& process_type,
     const base::HandlesToInheritVector& handles_to_inherit,
     SandboxDelegate* delegate,
     TargetPolicy* policy) {
@@ -947,8 +945,8 @@
     policy->AddHandleToShare(handle);
 
   if (!policy->GetConfig()->IsConfigured()) {
-    ResultCode result = GenerateConfigForSandboxedProcess(
-        cmd_line, process_type, delegate, policy->GetConfig());
+    ResultCode result = GenerateConfigForSandboxedProcess(cmd_line, delegate,
+                                                          policy->GetConfig());
     if (result != SBOX_ALL_OK)
       return result;
   }
@@ -969,7 +967,6 @@
 // static
 ResultCode SandboxWin::StartSandboxedProcess(
     const base::CommandLine& cmd_line,
-    const std::string& process_type,
     const base::HandlesToInheritVector& handles_to_inherit,
     SandboxDelegate* delegate,
     base::Process* process) {
@@ -986,7 +983,7 @@
   timer.OnPolicyCreated();
 
   ResultCode result = GeneratePolicyForSandboxedProcess(
-      cmd_line, process_type, handles_to_inherit, delegate, policy.get());
+      cmd_line, handles_to_inherit, delegate, policy.get());
   if (SBOX_ALL_OK != result)
     return result;
   timer.OnPolicyGenerated();
diff --git a/sandbox/policy/win/sandbox_win.h b/sandbox/policy/win/sandbox_win.h
index 54d808d..271e80f5 100644
--- a/sandbox/policy/win/sandbox_win.h
+++ b/sandbox/policy/win/sandbox_win.h
@@ -43,16 +43,15 @@
 
 class SANDBOX_POLICY_EXPORT SandboxWin {
  public:
-  // Create a sandboxed process `process` with the specified `cmd_line` of type
-  // `process_type` (e.g. 'renderer' or 'utility'). `handles_to_inherit`
-  // specifies a set of handles to inherit. `delegate` specifies the sandbox
-  // delegate to use when resolving specific sandbox policy.
+  // Create a sandboxed process `process` with the specified `cmd_line`.
+  // `handles_to_inherit` specifies a set of handles to inherit.
+  // `delegate` specifies the sandbox delegate to use when resolving specific
+  // sandbox policy.
   //
   // Returns SBOX_ALL_OK if the process was successfully created.
   // Otherwise, returns one of sandbox::ResultCode for any other error.
   static ResultCode StartSandboxedProcess(
       const base::CommandLine& cmd_line,
-      const std::string& process_type,
       const base::HandlesToInheritVector& handles_to_inherit,
       SandboxDelegate* delegate,
       base::Process* process);
@@ -66,7 +65,6 @@
   // of sandbox::ResultCode for any other error while constructing the policy.
   static ResultCode GeneratePolicyForSandboxedProcess(
       const base::CommandLine& cmd_line,
-      const std::string& process_type,
       const base::HandlesToInheritVector& handles_to_inherit,
       SandboxDelegate* delegate,
       TargetPolicy* policy);
diff --git a/sandbox/policy/win/sandbox_win_unittest.cc b/sandbox/policy/win/sandbox_win_unittest.cc
index 52a149b..88f7f41 100644
--- a/sandbox/policy/win/sandbox_win_unittest.cc
+++ b/sandbox/policy/win/sandbox_win_unittest.cc
@@ -485,8 +485,7 @@
   // PreSpawn should get called, but not modifying the policy for this test.
   EXPECT_CALL(test_renderer_delegate, PreSpawnTarget(_)).WillOnce(Return(true));
   ResultCode result = SandboxWin::GeneratePolicyForSandboxedProcess(
-      cmd_line, switches::kRendererProcess, handles_to_inherit,
-      &test_renderer_delegate, policy.get());
+      cmd_line, handles_to_inherit, &test_renderer_delegate, policy.get());
   ASSERT_EQ(ResultCode::SBOX_ALL_OK, result);
   // Check some default values come back. No need to check the exact policy in
   // detail, but just that GeneratePolicyForSandboxedProcess generated some kind
@@ -514,13 +513,11 @@
       .Times(2)
       .WillRepeatedly(Return(true));
   ResultCode result = SandboxWin::GeneratePolicyForSandboxedProcess(
-      cmd_line, switches::kRendererProcess, handles_to_inherit,
-      &test_renderer_delegate, policy.get());
+      cmd_line, handles_to_inherit, &test_renderer_delegate, policy.get());
   ASSERT_EQ(ResultCode::SBOX_ALL_OK, result);
   BrokerServicesBase::FreezeTargetConfigForTesting(policy->GetConfig());
   result = SandboxWin::GeneratePolicyForSandboxedProcess(
-      cmd_line, switches::kRendererProcess, handles_to_inherit,
-      &test_renderer_delegate, policy.get());
+      cmd_line, handles_to_inherit, &test_renderer_delegate, policy.get());
   ASSERT_EQ(ResultCode::SBOX_ALL_OK, result);
 }
 
@@ -537,8 +534,7 @@
   EXPECT_CALL(test_unsandboxed_delegate, PreSpawnTarget(_)).Times(0);
 
   ResultCode result = SandboxWin::GeneratePolicyForSandboxedProcess(
-      cmd_line, switches::kRendererProcess, handles_to_inherit,
-      &test_unsandboxed_delegate, policy.get());
+      cmd_line, handles_to_inherit, &test_unsandboxed_delegate, policy.get());
   ASSERT_EQ(ResultCode::SBOX_ERROR_UNSANDBOXED_PROCESS, result);
 }
 
diff --git a/services/device/serial/bluetooth_serial_device_enumerator_unittests.cc b/services/device/serial/bluetooth_serial_device_enumerator_unittests.cc
index 0fc450d..9432e52 100644
--- a/services/device/serial/bluetooth_serial_device_enumerator_unittests.cc
+++ b/services/device/serial/bluetooth_serial_device_enumerator_unittests.cc
@@ -250,10 +250,7 @@
 
   // Add the device. The observer is notified that a new port was added.
   TestFuture<const mojom::SerialPortInfo&> port_future;
-  EXPECT_CALL(observer, OnPortAdded)
-      .WillOnce([&port_future](const mojom::SerialPortInfo& port) {
-        port_future.SetValue(port);
-      });
+  EXPECT_CALL(observer, OnPortAdded).WillOnce(InvokeFuture(port_future));
   EXPECT_CALL(observer, OnPortConnectedStateChanged).Times(0);
   enumerator.DeviceAddedForTesting(mock_adapter.get(), mock_device.get());
   EXPECT_TRUE(port_future.Get().connected);
@@ -261,9 +258,7 @@
   // Disconnect the Bluetooth device and wait for the observer to be notified.
   TestFuture<const mojom::SerialPortInfo&> disconnect_future;
   EXPECT_CALL(observer, OnPortConnectedStateChanged)
-      .WillOnce([&disconnect_future](const mojom::SerialPortInfo& port) {
-        disconnect_future.SetValue(port);
-      });
+      .WillOnce(InvokeFuture(disconnect_future));
   mock_device->SetConnected(false);
   enumerator.DeviceChangedForTesting(mock_adapter.get(), mock_device.get());
   EXPECT_EQ(disconnect_future.Get().token, port_future.Get().token);
@@ -272,9 +267,7 @@
   // Reconnect the Bluetooth device and wait for the observer to be notified.
   TestFuture<const mojom::SerialPortInfo&> reconnect_future;
   EXPECT_CALL(observer, OnPortConnectedStateChanged)
-      .WillOnce([&reconnect_future](const mojom::SerialPortInfo& port) {
-        reconnect_future.SetValue(port);
-      });
+      .WillOnce(InvokeFuture(reconnect_future));
   mock_device->SetConnected(true);
   enumerator.DeviceChangedForTesting(mock_adapter.get(), mock_device.get());
   EXPECT_EQ(reconnect_future.Get().token, port_future.Get().token);
diff --git a/services/device/serial/bluetooth_serial_port_impl.h b/services/device/serial/bluetooth_serial_port_impl.h
index e7e7fed..31bd5dd 100644
--- a/services/device/serial/bluetooth_serial_port_impl.h
+++ b/services/device/serial/bluetooth_serial_port_impl.h
@@ -6,6 +6,7 @@
 #define SERVICES_DEVICE_SERIAL_BLUETOOTH_SERIAL_PORT_IMPL_H_
 
 #include "base/containers/span.h"
+#include "base/memory/raw_span.h"
 #include "base/sequence_checker.h"
 #include "base/task/single_thread_task_runner.h"
 #include "device/bluetooth/bluetooth_adapter.h"
@@ -99,7 +100,7 @@
 
   // Used for pending writes to |out_stream_|. When empty this indicates that
   // |out_stream_| has been closed (and possibly replaced).
-  base::span<char> pending_write_buffer_;
+  base::raw_span<char> pending_write_buffer_;
 
   // Holds the callback for a drain until pending operations have been
   // completed.
diff --git a/services/device/serial/serial_io_handler.h b/services/device/serial/serial_io_handler.h
index 4bedfc3..ccf0c5ef 100644
--- a/services/device/serial/serial_io_handler.h
+++ b/services/device/serial/serial_io_handler.h
@@ -12,6 +12,7 @@
 
 #include "base/files/file.h"
 #include "base/functional/callback.h"
+#include "base/memory/raw_span.h"
 #include "base/memory/ref_counted.h"
 #include "base/sequence_checker.h"
 #include "base/task/single_thread_task_runner.h"
@@ -209,12 +210,12 @@
   // Currently applied connection options.
   mojom::SerialConnectionOptions options_;
 
-  base::span<uint8_t> pending_read_buffer_;
+  base::raw_span<uint8_t> pending_read_buffer_;
   ReadCompleteCallback pending_read_callback_;
   mojom::SerialReceiveError read_cancel_reason_;
   bool read_canceled_;
 
-  base::span<const uint8_t> pending_write_buffer_;
+  base::raw_span<const uint8_t> pending_write_buffer_;
   WriteCompleteCallback pending_write_callback_;
   mojom::SerialSendError write_cancel_reason_;
   bool write_canceled_;
diff --git a/services/preferences/tracked/dictionary_hash_store_contents.cc b/services/preferences/tracked/dictionary_hash_store_contents.cc
index ca9e4ce5..bb8927f4 100644
--- a/services/preferences/tracked/dictionary_hash_store_contents.cc
+++ b/services/preferences/tracked/dictionary_hash_store_contents.cc
@@ -10,8 +10,6 @@
 #include "base/functional/callback.h"
 #include "base/notreached.h"
 #include "base/values.h"
-#include "components/pref_registry/pref_registry_syncable.h"
-#include "components/prefs/persistent_pref_store.h"
 
 namespace {
 const char kPreferenceMACs[] = "protection.macs";
@@ -22,13 +20,6 @@
     base::Value::Dict& storage)
     : storage_(storage) {}
 
-// static
-void DictionaryHashStoreContents::RegisterProfilePrefs(
-    user_prefs::PrefRegistrySyncable* registry) {
-  registry->RegisterDictionaryPref(kPreferenceMACs);
-  registry->RegisterStringPref(kSuperMACPref, std::string());
-}
-
 bool DictionaryHashStoreContents::IsCopyable() const {
   return false;
 }
diff --git a/services/preferences/tracked/dictionary_hash_store_contents.h b/services/preferences/tracked/dictionary_hash_store_contents.h
index 90b0b7e15..8e79d03 100644
--- a/services/preferences/tracked/dictionary_hash_store_contents.h
+++ b/services/preferences/tracked/dictionary_hash_store_contents.h
@@ -11,10 +11,6 @@
 #include "base/values.h"
 #include "services/preferences/tracked/hash_store_contents.h"
 
-namespace user_prefs {
-class PrefRegistrySyncable;
-}  // namespace user_prefs
-
 // Implements HashStoreContents by storing MACs in a DictionaryValue. The
 // DictionaryValue is presumed to be the contents of a PrefStore.
 // RegisterProfilePrefs() may be used to register all of the preferences used by
@@ -29,9 +25,6 @@
   DictionaryHashStoreContents& operator=(const DictionaryHashStoreContents&) =
       delete;
 
-  // Registers required preferences.
-  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
-
   // HashStoreContents implementation
   bool IsCopyable() const override;
   std::unique_ptr<HashStoreContents> MakeCopy() const override;
diff --git a/services/screen_ai/public/cpp/utilities.cc b/services/screen_ai/public/cpp/utilities.cc
index a420fa7..dfb440c 100644
--- a/services/screen_ai/public/cpp/utilities.cc
+++ b/services/screen_ai/public/cpp/utilities.cc
@@ -12,7 +12,6 @@
 #include "base/version.h"
 #include "build/build_config.h"
 #include "components/component_updater/component_updater_paths.h"
-#include "services/screen_ai/buildflags/buildflags.h"
 #include "ui/accessibility/accessibility_features.h"
 
 namespace screen_ai {
@@ -110,6 +109,7 @@
 #endif
 }
 
+#if BUILDFLAG(ENABLE_SCREEN_AI_BROWSERTESTS)
 base::FilePath GetComponentBinaryPathForTests() {
   base::FilePath component_path = GetComponentDir();
 
@@ -124,6 +124,7 @@
 
   return component_path;
 }
+#endif
 
 const char* GetBinaryPathSwitch() {
   // This is only used on Linux and ChromeOS.
diff --git a/services/screen_ai/public/cpp/utilities.h b/services/screen_ai/public/cpp/utilities.h
index 0b30fc4..04e1b4b 100644
--- a/services/screen_ai/public/cpp/utilities.h
+++ b/services/screen_ai/public/cpp/utilities.h
@@ -6,12 +6,15 @@
 #define SERVICES_SCREEN_AI_PUBLIC_CPP_UTILITIES_H_
 
 #include "base/files/file_path.h"
+#include "services/screen_ai/buildflags/buildflags.h"
 
 namespace screen_ai {
 
+#if BUILDFLAG(ENABLE_SCREEN_AI_BROWSERTESTS)
 // Get the absolute path of the ScreenAI component binary for tests. This
 // function verifies that the binary exists on disk and can be opened.
 base::FilePath GetComponentBinaryPathForTests();
+#endif
 
 // Returns the install directory relative to components folder.
 base::FilePath GetRelativeInstallDir();
diff --git a/services/webnn/coreml/graph_builder_coreml.cc b/services/webnn/coreml/graph_builder_coreml.cc
index 9ac55d4..07c0869 100644
--- a/services/webnn/coreml/graph_builder_coreml.cc
+++ b/services/webnn/coreml/graph_builder_coreml.cc
@@ -263,67 +263,67 @@
 static_assert(sizeof(WeightMetadata) == 64, "WeightMetadata must be 64 bytes");
 
 std::optional<BlobDataType> OperandTypeToDataTypeInWeightFile(
-    mojom::DataType data_type) {
+    OperandDataType data_type) {
   switch (data_type) {
-    case mojom::DataType::kFloat16:
+    case OperandDataType::kFloat16:
       return BlobDataType::Float16;
-    case mojom::DataType::kFloat32:
+    case OperandDataType::kFloat32:
       return BlobDataType::Float32;
-    case mojom::DataType::kUint8:
+    case OperandDataType::kUint8:
       return BlobDataType::UInt8;
-    case mojom::DataType::kInt8:
+    case OperandDataType::kInt8:
       return BlobDataType::Int8;
-    case mojom::DataType::kInt32:
-    case mojom::DataType::kUint32:
-    case mojom::DataType::kInt64:
-    case mojom::DataType::kUint64:
+    case OperandDataType::kInt32:
+    case OperandDataType::kUint32:
+    case OperandDataType::kInt64:
+    case OperandDataType::kUint64:
       return std::nullopt;
   }
 }
 
 CoreML::Specification::MILSpec::DataType OperandTypeToMILDataType(
-    mojom::DataType data_type) {
+    OperandDataType data_type) {
   switch (data_type) {
-    case mojom::DataType::kFloat32:
+    case OperandDataType::kFloat32:
       return CoreML::Specification::MILSpec::DataType::FLOAT32;
-    case mojom::DataType::kFloat16:
+    case OperandDataType::kFloat16:
       return CoreML::Specification::MILSpec::DataType::FLOAT16;
-    case mojom::DataType::kInt32:
+    case OperandDataType::kInt32:
       return CoreML::Specification::MILSpec::DataType::INT32;
-    case mojom::DataType::kUint32:
+    case OperandDataType::kUint32:
       return CoreML::Specification::MILSpec::DataType::UINT32;
-    case mojom::DataType::kInt64:
+    case OperandDataType::kInt64:
       return CoreML::Specification::MILSpec::DataType::INT64;
-    case mojom::DataType::kUint64:
+    case OperandDataType::kUint64:
       return CoreML::Specification::MILSpec::DataType::UINT64;
-    case mojom::DataType::kInt8:
+    case OperandDataType::kInt8:
       return CoreML::Specification::MILSpec::DataType::INT8;
-    case mojom::DataType::kUint8:
+    case OperandDataType::kUint8:
       return CoreML::Specification::MILSpec::DataType::UINT8;
   }
 }
 
 // CoreML has more data types than WebNN. This should only be called with valid
 // WebNN mapped types.
-mojom::DataType MILDataTypeToOperandType(
+OperandDataType MILDataTypeToOperandType(
     CoreML::Specification::MILSpec::DataType mil_data_type) {
   switch (mil_data_type) {
     case CoreML::Specification::MILSpec::DataType::FLOAT32:
-      return mojom::DataType::kFloat32;
+      return OperandDataType::kFloat32;
     case CoreML::Specification::MILSpec::DataType::FLOAT16:
-      return mojom::DataType::kFloat16;
+      return OperandDataType::kFloat16;
     case CoreML::Specification::MILSpec::DataType::INT32:
-      return mojom::DataType::kInt32;
+      return OperandDataType::kInt32;
     case CoreML::Specification::MILSpec::DataType::UINT32:
-      return mojom::DataType::kUint32;
+      return OperandDataType::kUint32;
     case CoreML::Specification::MILSpec::DataType::INT64:
-      return mojom::DataType::kInt64;
+      return OperandDataType::kInt64;
     case CoreML::Specification::MILSpec::DataType::UINT64:
-      return mojom::DataType::kUint64;
+      return OperandDataType::kUint64;
     case CoreML::Specification::MILSpec::DataType::INT8:
-      return mojom::DataType::kInt8;
+      return OperandDataType::kInt8;
     case CoreML::Specification::MILSpec::DataType::UINT8:
-      return mojom::DataType::kUint8;
+      return OperandDataType::kUint8;
     default:
       NOTREACHED_NORETURN() << "Unsupported data type.";
   }
@@ -473,9 +473,10 @@
 }
 
 void PopulateValueTypeFromOperandInfo(
-    const GraphBuilderCoreml::OperandInfo& operand,
+    const GraphBuilderCoreml::OperandInfo& operand_info,
     CoreML::Specification::MILSpec::ValueType& value_type) {
-  PopulateValueType(operand.mil_data_type, operand.dimensions, value_type);
+  PopulateValueType(operand_info.mil_data_type, operand_info.dimensions,
+                    value_type);
 }
 
 template <typename DataType>
@@ -863,13 +864,13 @@
 
   for (auto& [key, buffer] : graph_info_->constant_id_to_buffer_map) {
     const mojom::Operand& operand = GetOperand(key);
-    if (operand.dimensions.empty()) {
+    if (operand.descriptor.shape().empty()) {
       RETURN_IF_ERROR(AddConstantImmediateValue(key, block));
       continue;
     }
 
     std::optional<BlobDataType> weight_type =
-        OperandTypeToDataTypeInWeightFile(operand.data_type);
+        OperandTypeToDataTypeInWeightFile(operand.descriptor.data_type());
     if (!weight_type.has_value()) {
       return NewNotSupportedError("Unsupported constant type.");
     }
@@ -955,10 +956,11 @@
             .try_emplace(operand.name.value(), input_id)
             .second);
 
-  if (operand.dimensions.empty()) {
-    ASSIGN_OR_RETURN(uint64_t internal_operand_id,
-                     GenerateInternalOperandInfo(
-                         OperandTypeToMILDataType(operand.data_type), {}));
+  if (operand.descriptor.shape().empty()) {
+    ASSIGN_OR_RETURN(
+        uint64_t internal_operand_id,
+        GenerateInternalOperandInfo(
+            OperandTypeToMILDataType(operand.descriptor.data_type()), {}));
     RETURN_IF_ERROR(
         AddOperationForReshape(input_id, internal_operand_id, block));
     id_to_operand_info_map()[input_id].coreml_name =
@@ -2354,42 +2356,42 @@
   base::span<const uint8_t> value(
       graph_info_->constant_id_to_buffer_map.at(constant_id));
   const mojom::Operand& operand = GetOperand(constant_id);
-  switch (operand.data_type) {
-    case mojom::DataType::kFloat32: {
+  switch (operand.descriptor.data_type()) {
+    case OperandDataType::kFloat32: {
       std::vector<float> floats(value.size() / sizeof(float));
       for (size_t i = 0u; i < floats.size(); ++i) {
         floats[i] = base::FloatFromNativeEndian(
             value.subspan(i * sizeof(float)).first<4u>());
       }
       attributes["val"] =
-          CreateTensorImmediateValue<float>(operand.dimensions, floats);
+          CreateTensorImmediateValue<float>(operand.descriptor.shape(), floats);
       break;
     }
-    case mojom::DataType::kFloat16: {
+    case OperandDataType::kFloat16: {
       std::vector<Float16> float16s(value.size() / sizeof(Float16));
       for (size_t i = 0u; i < float16s.size(); ++i) {
         float16s[i].data = base::U16FromNativeEndian(
             value.subspan(i * sizeof(Float16)).first<2u>());
       }
-      attributes["val"] =
-          CreateTensorImmediateValue<Float16>(operand.dimensions, float16s);
+      attributes["val"] = CreateTensorImmediateValue<Float16>(
+          operand.descriptor.shape(), float16s);
       break;
     }
-    case mojom::DataType::kInt32: {
+    case OperandDataType::kInt32: {
       std::vector<int32_t> ints(value.size() / sizeof(int32_t));
       for (size_t i = 0u; i < ints.size(); ++i) {
         ints[i] = base::I32FromNativeEndian(
             value.subspan(i * sizeof(int32_t)).first<4u>());
       }
       attributes["val"] =
-          CreateTensorImmediateValue<int32_t>(operand.dimensions, ints);
+          CreateTensorImmediateValue<int32_t>(operand.descriptor.shape(), ints);
       break;
     }
-    case mojom::DataType::kUint32:
-    case mojom::DataType::kInt64:
-    case mojom::DataType::kUint64:
-    case mojom::DataType::kInt8:
-    case mojom::DataType::kUint8: {
+    case OperandDataType::kUint32:
+    case OperandDataType::kInt64:
+    case OperandDataType::kUint64:
+    case OperandDataType::kInt8:
+    case OperandDataType::kUint8: {
       NOTREACHED_NORETURN() << "Unsupported data type.";
     }
   }
@@ -2467,46 +2469,46 @@
   const mojom::Operand& operand = GetOperand(operand_id);
   auto* feature_type = feature_description.mutable_type();
   auto* array_feature_type = feature_type->mutable_multiarraytype();
-  switch (operand.data_type) {
-    case mojom::DataType::kFloat32:
+  switch (operand.descriptor.data_type()) {
+    case OperandDataType::kFloat32:
       array_feature_type->set_datatype(
           CoreML::Specification::ArrayFeatureType_ArrayDataType::
               ArrayFeatureType_ArrayDataType_FLOAT32);
       break;
-    case mojom::DataType::kFloat16:
+    case OperandDataType::kFloat16:
       array_feature_type->set_datatype(
           CoreML::Specification::ArrayFeatureType_ArrayDataType::
               ArrayFeatureType_ArrayDataType_FLOAT16);
       break;
-    case mojom::DataType::kInt32:
+    case OperandDataType::kInt32:
       array_feature_type->set_datatype(
           CoreML::Specification::ArrayFeatureType_ArrayDataType::
               ArrayFeatureType_ArrayDataType_INT32);
       break;
-    case mojom::DataType::kUint32:
-    case mojom::DataType::kInt64:
-    case mojom::DataType::kUint64:
-    case mojom::DataType::kInt8:
-    case mojom::DataType::kUint8:
+    case OperandDataType::kUint32:
+    case OperandDataType::kInt64:
+    case OperandDataType::kUint64:
+    case OperandDataType::kInt8:
+    case OperandDataType::kUint8:
       CHECK(operand.name);
       // CoreML only supports limited data types as input/output for a
       // model. Within the model wider set of data types are supported.
-      return NewNotSupportedError(
-          NotSupportedInputTypeError(operand.name.value(), operand.data_type));
+      return NewNotSupportedError(NotSupportedInputTypeError(
+          operand.name.value(), operand.descriptor.data_type()));
   }
   // FeatureDescriptions are about input and output features, WebNN allows
   // scalar operands to have empty dimensions. At the input and output layers
   // these can be treated as a 1D tensor to satisfy CoreML's requirement of
-  // having atleast 1 dimension.
-  if (operand.dimensions.empty()) {
+  // having at least 1 dimension.
+  if (operand.descriptor.shape().empty()) {
     array_feature_type->add_shape(1);
   } else {
-    for (int dimension : operand.dimensions) {
+    for (int dimension : operand.descriptor.shape()) {
       array_feature_type->add_shape(dimension);
     }
   }
 
-  if (operand.dimensions.size() > 5) {
+  if (operand.descriptor.shape().size() > 5) {
     return NewNotSupportedError(
         "Unsupported rank for input. It should be between 0 to 5.");
   }
@@ -2563,7 +2565,7 @@
   // WebNN allows 0D scalar operands to have empty dimensions.
   // At the input nodes, these can be treated as a 1D tensor to
   // satisfy CoreML's requirement of having at least 1 dimension.
-  if (GetOperand(operand_id).dimensions.empty()) {
+  if (GetOperand(operand_id).descriptor.Rank() == 0) {
     auto* tensor_type = named_value_type.mutable_type()->mutable_tensortype();
     tensor_type->set_rank(1);
     tensor_type->add_dimensions()->mutable_constant()->set_size(1);
@@ -2572,13 +2574,13 @@
 
 void GraphBuilderCoreml::UpdateCoreMLInputInfoMap(uint64_t operand_id) {
   const mojom::Operand& operand = GetOperand(operand_id);
-  CHECK(
-      id_to_operand_info_map()
-          .try_emplace(operand_id,
-                       OperandInfo(GetCoreMLNameFromOperand(operand_id),
-                                   operand.dimensions,
-                                   OperandTypeToMILDataType(operand.data_type)))
-          .second);
+  CHECK(id_to_operand_info_map()
+            .try_emplace(operand_id,
+                         OperandInfo(GetCoreMLNameFromOperand(operand_id),
+                                     operand.descriptor.shape(),
+                                     OperandTypeToMILDataType(
+                                         operand.descriptor.data_type())))
+            .second);
 }
 
 base::expected<void, mojom::ErrorPtr>
@@ -2675,7 +2677,7 @@
 GraphBuilderCoreml::InputOperandInfo::InputOperandInfo(
     std::string name,
     std::vector<uint32_t> dimensions,
-    mojom::DataType data_type)
+    OperandDataType data_type)
     : coreml_name(std::move(name)),
       dimensions(std::move(dimensions)),
       data_type(data_type) {}
@@ -2695,14 +2697,14 @@
 GraphBuilderCoreml::Result::FindModelInputOperandInfo(
     const std::string& input_name) const {
   auto it = input_name_to_id_map.find(input_name);
-  const OperandInfo& input_operand = GetOperandInfo(it->second);
+  const OperandInfo& input_operand_info = GetOperandInfo(it->second);
   // Some internally generated operands don't have a matching mojom data type,
   // but model inputs all should have valid mojom data types.
   return InputOperandInfo{
-      input_operand.external_coreml_name,
-      input_operand.dimensions.empty() ? std::vector<uint32_t>({1})
-                                       : input_operand.dimensions,
-      MILDataTypeToOperandType(input_operand.mil_data_type)};
+      input_operand_info.external_coreml_name,
+      input_operand_info.dimensions.empty() ? std::vector<uint32_t>({1})
+                                            : input_operand_info.dimensions,
+      MILDataTypeToOperandType(input_operand_info.mil_data_type)};
 }
 
 const base::FilePath& GraphBuilderCoreml::Result::GetModelFilePath() {
diff --git a/services/webnn/coreml/graph_builder_coreml.h b/services/webnn/coreml/graph_builder_coreml.h
index 18ca0c3..702dac8 100644
--- a/services/webnn/coreml/graph_builder_coreml.h
+++ b/services/webnn/coreml/graph_builder_coreml.h
@@ -15,6 +15,7 @@
 #include "base/memory/stack_allocated.h"
 #include "base/numerics/checked_math.h"
 #include "base/types/expected.h"
+#include "services/webnn/public/cpp/operand_descriptor.h"
 #include "services/webnn/public/mojom/webnn_context_provider.mojom.h"
 #include "services/webnn/public/mojom/webnn_error.mojom-forward.h"
 #include "services/webnn/public/mojom/webnn_graph.mojom.h"
@@ -85,7 +86,7 @@
     InputOperandInfo();
     InputOperandInfo(std::string name,
                      std::vector<uint32_t> dimensions,
-                     mojom::DataType data_type);
+                     OperandDataType data_type);
     InputOperandInfo(InputOperandInfo&);
     InputOperandInfo(InputOperandInfo&&);
     ~InputOperandInfo();
@@ -93,7 +94,7 @@
     // Identifier for this operand in coreml model file.
     std::string coreml_name;
     std::vector<uint32_t> dimensions;
-    mojom::DataType data_type;
+    OperandDataType data_type;
   };
 
   struct Result {
diff --git a/services/webnn/coreml/graph_impl_coreml.mm b/services/webnn/coreml/graph_impl_coreml.mm
index 59836c2..930e38c 100644
--- a/services/webnn/coreml/graph_impl_coreml.mm
+++ b/services/webnn/coreml/graph_impl_coreml.mm
@@ -75,9 +75,31 @@
   }
 }
 
+std::optional<MLMultiArrayDataType> ToMLMultiArrayDataType(
+    OperandDataType data_type) {
+  switch (data_type) {
+    case OperandDataType::kFloat32:
+      return MLMultiArrayDataTypeFloat32;
+    case OperandDataType::kFloat16:
+      if (__builtin_available(macOS 14, *)) {
+        return MLMultiArrayDataTypeFloat16;
+      }
+      NOTREACHED_NORETURN();
+    case OperandDataType::kInt32:
+      return MLMultiArrayDataTypeInt32;
+    case OperandDataType::kUint32:
+    case OperandDataType::kInt64:
+    case OperandDataType::kUint64:
+    case OperandDataType::kInt8:
+    case OperandDataType::kUint8:
+      // Unsupported data types in coreml.
+      return std::nullopt;
+  }
+}
+
 void ExtractOutputRecursively(base::span<const uint8_t> bytes,
-                              base::span<const size_t> dimensions,
-                              base::span<const size_t> strides,
+                              base::span<const uint32_t> dimensions,
+                              base::span<const uint32_t> strides,
                               uint32_t item_byte_size,
                               base::span<uint8_t> output) {
   // Data is packed, copy the whole thing.
@@ -95,7 +117,7 @@
 
   base::SpanReader<const uint8_t> reader(bytes);
   base::SpanWriter<uint8_t> writer(output);
-  for (size_t i = 0; i < dimensions[0]; i++) {
+  for (uint32_t i = 0; i < dimensions[0]; i++) {
     auto output_subspan = writer.Skip(subspan_size);
     CHECK(output_subspan);
     auto subspan = reader.Read(strides[0] * item_byte_size);
@@ -114,8 +136,8 @@
     base::span<const uint8_t> bytes,
     uint32_t expected_byte_size,
     uint32_t item_byte_size,
-    base::span<const size_t> dimensions,
-    base::span<const size_t> strides) {
+    base::span<const uint32_t> dimensions,
+    base::span<const uint32_t> strides) {
   mojo_base::BigBuffer output(expected_byte_size);
 
   // Bytes size should match with the layout from the strides.
@@ -336,24 +358,10 @@
 std::optional<GraphImplCoreml::CoreMLFeatureInfo>
 GraphImplCoreml::GetCoreMLFeatureInfo(
     const GraphBuilderCoreml::InputOperandInfo& operand_info) {
-  enum MLMultiArrayDataType data_type;
-  switch (operand_info.data_type) {
-    case webnn::mojom::DataType::kFloat32:
-      data_type = MLMultiArrayDataTypeFloat32;
-      break;
-    case webnn::mojom::DataType::kFloat16:
-      data_type = MLMultiArrayDataTypeFloat16;
-      break;
-    case webnn::mojom::DataType::kInt32:
-      data_type = MLMultiArrayDataTypeInt32;
-      break;
-    case webnn::mojom::DataType::kUint32:
-    case webnn::mojom::DataType::kInt64:
-    case webnn::mojom::DataType::kUint64:
-    case webnn::mojom::DataType::kInt8:
-    case webnn::mojom::DataType::kUint8:
-      // Unsupported data types in coreml.
-      return std::nullopt;
+  std::optional<MLMultiArrayDataType> data_type =
+      ToMLMultiArrayDataType(operand_info.data_type);
+  if (!data_type.has_value()) {
+    return std::nullopt;
   }
   NSMutableArray* shape =
       [[NSMutableArray alloc] initWithCapacity:operand_info.dimensions.size()];
@@ -376,8 +384,8 @@
     current_stride = current_stride / dimension;
     [stride addObject:@(current_stride)];
   }
-  return GraphImplCoreml::CoreMLFeatureInfo(data_type, shape, stride,
-                                      operand_info.coreml_name);
+  return GraphImplCoreml::CoreMLFeatureInfo(*data_type, shape, stride,
+                                            operand_info.coreml_name);
 }
 
 GraphImplCoreml::GraphImplCoreml(
@@ -507,12 +515,12 @@
       CHECK_EQ(item_byte_size, OperandDescriptor::GetBytesPerElement(
                                    expected_descriptor.data_type()));
 
-      std::vector<size_t> dimensions(multiarray_value.shape.count);
-      for (size_t i = 0; i < multiarray_value.shape.count; ++i) {
+      std::vector<uint32_t> dimensions(multiarray_value.shape.count);
+      for (uint32_t i = 0; i < multiarray_value.shape.count; ++i) {
         dimensions[i] = multiarray_value.shape[i].integerValue;
       }
-      std::vector<size_t> strides(multiarray_value.strides.count);
-      for (size_t i = 0; i < multiarray_value.strides.count; ++i) {
+      std::vector<uint32_t> strides(multiarray_value.strides.count);
+      for (uint32_t i = 0; i < multiarray_value.strides.count; ++i) {
         strides[i] = multiarray_value.strides[i].integerValue;
       }
       CHECK_EQ(dimensions.size(), strides.size());
diff --git a/services/webnn/dml/context_impl_dml_test.cc b/services/webnn/dml/context_impl_dml_test.cc
index 76f0105..854320a 100644
--- a/services/webnn/dml/context_impl_dml_test.cc
+++ b/services/webnn/dml/context_impl_dml_test.cc
@@ -69,9 +69,9 @@
   // Build a simple graph with relu operator.
   GraphInfoBuilder builder;
   uint64_t input_operand_id =
-      builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {1, 2, 3, 4}, OperandDataType::kFloat32);
   builder.BuildRelu(input_operand_id, output_operand_id);
 
   // The GraphImplDml should be built successfully.
diff --git a/services/webnn/dml/graph_impl_dml.cc b/services/webnn/dml/graph_impl_dml.cc
index c7ea4f4a..0bfa764 100644
--- a/services/webnn/dml/graph_impl_dml.cc
+++ b/services/webnn/dml/graph_impl_dml.cc
@@ -83,23 +83,23 @@
 constexpr const uint32_t kNhwcToNchwPermutation[] = {0, 3, 1, 2};
 constexpr const uint32_t kNchwToNhwcPermutation[] = {0, 2, 3, 1};
 
-DML_TENSOR_DATA_TYPE GetTensorDataType(mojom::DataType type) {
+DML_TENSOR_DATA_TYPE GetTensorDataType(OperandDataType type) {
   switch (type) {
-    case mojom::DataType::kFloat32:
+    case OperandDataType::kFloat32:
       return DML_TENSOR_DATA_TYPE_FLOAT32;
-    case mojom::DataType::kFloat16:
+    case OperandDataType::kFloat16:
       return DML_TENSOR_DATA_TYPE_FLOAT16;
-    case mojom::DataType::kInt8:
+    case OperandDataType::kInt8:
       return DML_TENSOR_DATA_TYPE_INT8;
-    case mojom::DataType::kUint8:
+    case OperandDataType::kUint8:
       return DML_TENSOR_DATA_TYPE_UINT8;
-    case mojom::DataType::kInt64:
+    case OperandDataType::kInt64:
       return DML_TENSOR_DATA_TYPE_INT64;
-    case mojom::DataType::kUint64:
+    case OperandDataType::kUint64:
       return DML_TENSOR_DATA_TYPE_UINT64;
-    case mojom::DataType::kInt32:
+    case OperandDataType::kInt32:
       return DML_TENSOR_DATA_TYPE_INT32;
-    case mojom::DataType::kUint32:
+    case OperandDataType::kUint32:
       return DML_TENSOR_DATA_TYPE_UINT32;
     default:
       DLOG(ERROR) << "This data type is not supported.";
@@ -358,8 +358,9 @@
   DML_TENSOR_FLAGS flags = operand->kind == Operand::Kind::kConstant
                                ? DML_TENSOR_FLAG_OWNED_BY_DML
                                : DML_TENSOR_FLAG_NONE;
-  TensorDesc input_tensor_desc(GetTensorDataType(operand->data_type), flags,
-                               operand->dimensions);
+  TensorDesc input_tensor_desc(
+      GetTensorDataType(operand->descriptor.data_type()), flags,
+      operand->descriptor.shape());
   const InputNode* input_node = graph_builder.CreateInputNode();
   CHECK(input_node);
   const NodeOutput* node_output =
@@ -396,13 +397,13 @@
 // dimensions would be {1, 1, 1}.
 uint64_t BuildConstantOperandForFloatValue(mojom::GraphInfoPtr& graph_info,
                                            uint64_t& next_operand_id,
-                                           mojom::DataType data_type,
+                                           OperandDataType data_type,
                                            size_t rank,
                                            float value) {
   OperandPtr constant_operand = Operand::New();
   constant_operand->kind = Operand::Kind::kConstant;
-  constant_operand->dimensions = std::vector<uint32_t>(rank, 1);
-  constant_operand->data_type = data_type;
+  constant_operand->descriptor =
+      *OperandDescriptor::Create(data_type, std::vector<uint32_t>(rank, 1));
 
   uint64_t constant_id = next_operand_id++;
   CHECK(graph_info->id_to_operand_map
@@ -412,12 +413,12 @@
   mojo_base::BigBuffer buffer;
 
   switch (data_type) {
-    case mojom::DataType::kFloat32: {
+    case OperandDataType::kFloat32: {
       buffer = mojo_base::BigBuffer(base::make_span(
           reinterpret_cast<const uint8_t*>(&value), sizeof(value)));
       break;
     }
-    case mojom::DataType::kFloat16: {
+    case OperandDataType::kFloat16: {
       uint16_t fp16_value = fp16_ieee_from_fp32_value(value);
       buffer = mojo_base::BigBuffer(base::make_span(
           reinterpret_cast<const uint8_t*>(&fp16_value), sizeof(fp16_value)));
@@ -439,8 +440,8 @@
 const TensorDesc CreateOutputTensorDesc(const IdToOperandMap& id_to_operand_map,
                                         uint64_t output_id) {
   const OperandPtr& output_operand = id_to_operand_map.at(output_id);
-  return TensorDesc(GetTensorDataType(output_operand->data_type),
-                    output_operand->dimensions);
+  return TensorDesc(GetTensorDataType(output_operand->descriptor.data_type()),
+                    output_operand->descriptor.shape());
 }
 
 base::expected<void, mojom::ErrorPtr> CreateOperatorNodeForArgMinMax(
@@ -647,10 +648,10 @@
     const IdToOperandMap& id_to_operand_map) {
   const OperandPtr& output_operand =
       id_to_operand_map.at(binary->output_operand_id);
-  mojom::DataType output_data_type = output_operand->data_type;
+  OperandDataType output_data_type = output_operand->descriptor.data_type();
   return binary->kind == mojom::ElementWiseBinary::Kind::kAdd &&
-         (output_data_type == mojom::DataType::kFloat32 ||
-          output_data_type == mojom::DataType::kFloat16);
+         (output_data_type == OperandDataType::kFloat32 ||
+          output_data_type == OperandDataType::kFloat16);
 }
 
 // Return true if the operation can be fused with any of the following
@@ -1305,7 +1306,7 @@
         const mojom::TransposePtr& transpose = operation->get_transpose();
         const mojom::OperandPtr& input_operand =
             graph_info->id_to_operand_map.at(transpose->input_operand_id);
-        uint32_t input_rank = input_operand->dimensions.size();
+        uint32_t input_rank = input_operand->descriptor.shape().size();
         if (input_rank < 2) {
           break;
         }
@@ -1353,9 +1354,9 @@
   auto& id_to_operand_map = graph_info->id_to_operand_map;
   uint64_t output_id = batch_normalization->output_operand_id;
   const OperandPtr& output_operand = id_to_operand_map.at(output_id);
-  mojom::DataType data_type = output_operand->data_type;
+  OperandDataType data_type = output_operand->descriptor.data_type();
   const TensorDesc output_tensor_desc(GetTensorDataType(data_type),
-                                      output_operand->dimensions);
+                                      output_operand->descriptor.shape());
 
   const NodeOutput* mean = GetNodeOutputForOperand(
       id_to_node_output_map, batch_normalization->mean_operand_id);
@@ -2625,7 +2626,7 @@
       GetNodeOutputForOperand(id_to_node_output_map, reshape->input_operand_id);
   uint64_t output_id = reshape->output_operand_id;
   const OperandPtr& output_operand = id_to_operand_map.at(output_id);
-  base::span<const uint32_t> new_shape = output_operand->dimensions;
+  base::span<const uint32_t> new_shape = output_operand->descriptor.shape();
 
   const NodeOutput* output = CreateReshapeNode(graph_builder, input, new_shape);
   if (!output) {
@@ -3017,7 +3018,7 @@
   std::vector<const NodeOutput*> inputs{input, weight, recurrent_weight};
 
   const OperandPtr& input_operand = id_to_operand_map.at(gru->input_operand_id);
-  const mojom::DataType data_type = input_operand->data_type;
+  const OperandDataType data_type = input_operand->descriptor.data_type();
 
   std::optional<TensorDesc> concatenated_bias_tensor_desc;
   if (!gru->bias_operand_id.has_value() &&
@@ -3377,9 +3378,9 @@
   auto& id_to_operand_map = graph_info->id_to_operand_map;
   uint64_t output_id = normalization->output_operand_id;
   const OperandPtr& output_operand = id_to_operand_map.at(output_id);
-  mojom::DataType data_type = output_operand->data_type;
+  OperandDataType data_type = output_operand->descriptor.data_type();
   const TensorDesc output_tensor_desc(GetTensorDataType(data_type),
-                                      output_operand->dimensions);
+                                      output_operand->descriptor.shape());
 
   const NodeOutput* scale = GetOptionalNodeOutputForOperand(
       id_to_node_output_map, normalization->scale_operand_id);
@@ -3673,11 +3674,11 @@
   const uint64_t output_hidden_state_id = output_ids[0];
   const OperandPtr& output_hidden_state_operand =
       id_to_operand_map.at(output_hidden_state_id);
-  const mojom::DataType output_data_type =
-      output_hidden_state_operand->data_type;
+  const OperandDataType output_data_type =
+      output_hidden_state_operand->descriptor.data_type();
   TensorDesc output_hidden_state_tensor_desc(
       GetTensorDataType(output_data_type),
-      output_hidden_state_operand->dimensions);
+      output_hidden_state_operand->descriptor.shape());
   // The output hidden state tensor is 2-D for lstmCell and 3-D for lstm, while
   // DirectML expects a 4-D tensor.
   output_hidden_state_tensor_desc.EnsureMinimumRank(
@@ -4410,7 +4411,7 @@
   // For DirectML feature levels before 5.1, we need to compose triangular
   // from smaller operators: identity, slice, bitwise and.
   const OperandPtr& output_operand = id_to_operand_map.at(output_id);
-  mojom::DataType data_type = output_operand->data_type;
+  OperandDataType data_type = output_operand->descriptor.data_type();
   const uint32_t height = input_dimensions[input_rank - 2];
   const uint32_t width = input_dimensions[input_rank - 1];
   uint32_t longest_dimension_length = std::max(height, width);
@@ -4503,31 +4504,31 @@
     std::swap(lower_mask, upper_mask);
   }
 
-  mojom::DataType webnn_mask_data_type;
+  OperandDataType webnn_mask_data_type;
   DML_TENSOR_DATA_TYPE dml_mask_data_type;
   mojo_base::BigBuffer buffer;
   switch (data_type) {
-    case mojom::DataType::kInt8:
-    case mojom::DataType::kUint8: {
-      webnn_mask_data_type = mojom::DataType::kUint8;
+    case OperandDataType::kInt8:
+    case OperandDataType::kUint8: {
+      webnn_mask_data_type = OperandDataType::kUint8;
       dml_mask_data_type = DML_TENSOR_DATA_TYPE_UINT8;
       std::array<uint8_t, 2> values = {static_cast<uint8_t>(lower_mask),
                                        static_cast<uint8_t>(upper_mask)};
       buffer = mojo_base::BigBuffer(base::as_bytes(base::make_span(values)));
       break;
     }
-    case mojom::DataType::kFloat16: {
-      webnn_mask_data_type = mojom::DataType::kFloat16;
+    case OperandDataType::kFloat16: {
+      webnn_mask_data_type = OperandDataType::kFloat16;
       dml_mask_data_type = DML_TENSOR_DATA_TYPE_UINT16;
       std::array<uint16_t, 2> values = {static_cast<uint16_t>(lower_mask),
                                         static_cast<uint16_t>(upper_mask)};
       buffer = mojo_base::BigBuffer(base::as_bytes(base::make_span(values)));
       break;
     }
-    case mojom::DataType::kFloat32:
-    case mojom::DataType::kInt32:
-    case mojom::DataType::kUint32: {
-      webnn_mask_data_type = mojom::DataType::kUint32;
+    case OperandDataType::kFloat32:
+    case OperandDataType::kInt32:
+    case OperandDataType::kUint32: {
+      webnn_mask_data_type = OperandDataType::kUint32;
       dml_mask_data_type = DML_TENSOR_DATA_TYPE_UINT32;
       std::array<uint32_t, 2> values = {static_cast<uint32_t>(lower_mask),
                                         static_cast<uint32_t>(upper_mask)};
@@ -4539,8 +4540,8 @@
     // https://github.com/webmachinelearning/webnn/issues/654.
     // TODO(crbug.com/336841827): Delete the cases of uint64 and int64 after
     // the spec drops the support of int64 and uint64 for triangular.
-    case mojom::DataType::kInt64:
-    case mojom::DataType::kUint64: {
+    case OperandDataType::kInt64:
+    case OperandDataType::kUint64: {
       // DML_ELEMENT_WISE_BIT_AND_OPERATOR_DESC can't support uint64 when
       // DML_FEATURE_LEVEL is less than DML_FEATURE_LEVEL_4_1:
       // https://learn.microsoft.com/en-us/windows/win32/api/directml/ns-directml-dml_element_wise_bit_and_operator_desc#dml_feature_level_4_1-and-above
@@ -4553,8 +4554,8 @@
 
   OperandPtr constant_operand = Operand::New();
   constant_operand->kind = Operand::Kind::kConstant;
-  constant_operand->dimensions = {1, 2, 1};
-  constant_operand->data_type = webnn_mask_data_type;
+  constant_operand->descriptor = *OperandDescriptor::Create(
+      webnn_mask_data_type, std::array<uint32_t, 3>{1, 2, 1});
 
   uint64_t constant_operand_id = next_operand_id++;
   CHECK(graph_info->id_to_operand_map
diff --git a/services/webnn/public/mojom/webnn_graph.mojom b/services/webnn/public/mojom/webnn_graph.mojom
index bbb3b84..5076fd8 100644
--- a/services/webnn/public/mojom/webnn_graph.mojom
+++ b/services/webnn/public/mojom/webnn_graph.mojom
@@ -28,8 +28,6 @@
 
 // Represents the `MLOperand` which describes not only input and constant
 // operand, but also the output operand of operator.
-//
-// TODO(crbug.com/325598628): De-duplicate with `OperandDescriptor`.
 struct Operand {
   enum Kind {
     kInput,
@@ -38,10 +36,7 @@
   };
 
   Kind kind;
-  // The data type of the operand.
-  DataType data_type;
-  // The dimensions of the operand.
-  array<uint32> dimensions;
+  OperandDescriptor descriptor;
   // The name field is only required for input/output operands of graph.
   string? name;
 };
diff --git a/services/webnn/tflite/graph_builder_tflite.cc b/services/webnn/tflite/graph_builder_tflite.cc
index 6b0fab5c..2708776 100644
--- a/services/webnn/tflite/graph_builder_tflite.cc
+++ b/services/webnn/tflite/graph_builder_tflite.cc
@@ -55,16 +55,16 @@
       ::tflite::TensorType::TensorType_UINT32;
 };
 
-static constexpr auto kFloatDataTypes = base::MakeFixedFlatSet<mojom::DataType>(
-    {mojom::DataType::kFloat16, mojom::DataType::kFloat32});
+static constexpr auto kFloatDataTypes = base::MakeFixedFlatSet<OperandDataType>(
+    {OperandDataType::kFloat16, OperandDataType::kFloat32});
 
 static constexpr auto k32BitIntegerDataTypes =
-    base::MakeFixedFlatSet<mojom::DataType>(
-        {mojom::DataType::kInt32, mojom::DataType::kUint32});
+    base::MakeFixedFlatSet<OperandDataType>(
+        {OperandDataType::kInt32, OperandDataType::kUint32});
 
 static constexpr auto k64BitIntegerDataTypes =
-    base::MakeFixedFlatSet<mojom::DataType>(
-        {mojom::DataType::kInt64, mojom::DataType::kUint64});
+    base::MakeFixedFlatSet<OperandDataType>(
+        {OperandDataType::kInt64, OperandDataType::kUint64});
 
 // Useful for converting dimension arrays coming from mojo as uint32 to the
 // int32 vectors used by TFLite.
@@ -82,23 +82,23 @@
   return output_dimensions;
 }
 
-::tflite::TensorType MojoOperandTypeToTFLite(mojom::DataType data_type) {
+::tflite::TensorType OperandDataTypeToTFLite(OperandDataType data_type) {
   switch (data_type) {
-    case mojom::DataType::kFloat32:
+    case OperandDataType::kFloat32:
       return ::tflite::TensorType_FLOAT32;
-    case mojom::DataType::kFloat16:
+    case OperandDataType::kFloat16:
       return ::tflite::TensorType_FLOAT16;
-    case mojom::DataType::kInt32:
+    case OperandDataType::kInt32:
       return ::tflite::TensorType_INT32;
-    case mojom::DataType::kUint32:
+    case OperandDataType::kUint32:
       return ::tflite::TensorType_UINT32;
-    case mojom::DataType::kInt64:
+    case OperandDataType::kInt64:
       return ::tflite::TensorType_INT64;
-    case mojom::DataType::kUint64:
+    case OperandDataType::kUint64:
       return ::tflite::TensorType_UINT64;
-    case mojom::DataType::kInt8:
+    case OperandDataType::kInt8:
       return ::tflite::TensorType_INT8;
-    case mojom::DataType::kUint8:
+    case OperandDataType::kUint8:
       return ::tflite::TensorType_UINT8;
   }
 }
@@ -272,10 +272,11 @@
 
   // Create `Tensor` with operand shape, the index of buffer and the name.
   ASSIGN_OR_RETURN(std::vector<int32_t> signed_operand_dimensions,
-                   ToSignedDimensions(operand.dimensions));
+                   ToSignedDimensions(operand.descriptor.shape()));
   const flatbuffers::Offset<flatbuffers::Vector<int32_t>> dimensions =
       builder_.CreateVector<int32_t>(std::move(signed_operand_dimensions));
-  const auto operand_type = MojoOperandTypeToTFLite(operand.data_type);
+  const auto operand_type =
+      OperandDataTypeToTFLite(operand.descriptor.data_type());
   const StringOffset operand_name =
       operand.name.has_value() ? builder_.CreateString(*operand.name) : 0;
   tensors_.emplace_back(::tflite::CreateTensor(builder_, std::move(dimensions),
@@ -760,12 +761,12 @@
 
   // Create `tflite::Tensor` for the output operand of explicit padding operator
   // with the dimensions and data type.
-  const std::vector<uint32_t>& input_shape = input_operand.dimensions;
-  CHECK_EQ(input_shape.size(), 4u);
+  CHECK_EQ(input_operand.descriptor.Rank(), 4u);
   std::vector<int32_t> output_shape;
   output_shape.reserve(padding_rank);
   for (size_t i = 0; i < padding_rank; ++i) {
-    auto checked_dimension = base::MakeCheckedNum<int32_t>(input_shape[i]);
+    auto checked_dimension =
+        base::MakeCheckedNum<int32_t>(input_operand.descriptor.shape()[i]);
     // Calculate output height with padding beginning and ending height.
     if (i == 1) {
       checked_dimension +=
@@ -782,7 +783,7 @@
   }
 
   const ::tflite::TensorType input_tensor_type =
-      MojoOperandTypeToTFLite(input_operand.data_type);
+      OperandDataTypeToTFLite(input_operand.descriptor.data_type());
   const int32_t output_tensor_index =
       base::checked_cast<int32_t>(tensors_.size());
   tensors_.emplace_back(::tflite::CreateTensor(
@@ -902,17 +903,17 @@
       GetOperand(batch_normalization.input_operand_id);
   // TODO(crbug.com/339654398): Support 16-bit float with dequantize operator
   // https://www.tensorflow.org/mlir/tfl_ops#tfldequantize_tfldequantizeop.
-  if (input_operand.data_type == mojom::DataType::kFloat16) {
+  if (input_operand.descriptor.data_type() == OperandDataType::kFloat16) {
     return base::unexpected("The 16-bit float data type is not supported.");
   }
-  CHECK_EQ(input_operand.data_type, mojom::DataType::kFloat32);
+  CHECK_EQ(input_operand.descriptor.data_type(), OperandDataType::kFloat32);
   // The input shape has been validated to not overflow before creating tensor.
   const auto signed_input_dimensions =
-      ToSignedDimensions(input_operand.dimensions);
+      ToSignedDimensions(input_operand.descriptor.shape());
   CHECK(signed_input_dimensions.has_value());
   CHECK_LT(batch_normalization.axis, signed_input_dimensions->size());
   const ::tflite::TensorType input_tensor_type =
-      MojoOperandTypeToTFLite(input_operand.data_type);
+      OperandDataTypeToTFLite(input_operand.descriptor.data_type());
   const int32_t dimension_on_axis =
       (*signed_input_dimensions)[batch_normalization.axis];
   std::vector<int32_t> new_shape(signed_input_dimensions->size(), 1);
@@ -921,7 +922,7 @@
   // Reshape the 1-D tensor of the mean operand to the new shape.
   const mojom::Operand& mean_operand =
       GetOperand(batch_normalization.mean_operand_id);
-  CHECK_EQ(mean_operand.dimensions.size(), 1u);
+  CHECK_EQ(mean_operand.descriptor.Rank(), 1u);
   const int32_t reshape_mean_tensor_index =
       SerializeTemporaryTensor(new_shape, input_tensor_type);
   operators_.emplace_back(SerializeReshapeOperation(
@@ -931,7 +932,7 @@
   // Reshape the 1-D tensor of the variance operand to the new shape.
   const mojom::Operand& variance_operand =
       GetOperand(batch_normalization.variance_operand_id);
-  CHECK_EQ(variance_operand.dimensions.size(), 1u);
+  CHECK_EQ(variance_operand.descriptor.Rank(), 1u);
   const int32_t reshape_variance_tensor_index =
       SerializeTemporaryTensor(new_shape, input_tensor_type);
   operators_.emplace_back(SerializeReshapeOperation(
@@ -943,7 +944,7 @@
   if (batch_normalization.scale_operand_id) {
     const mojom::Operand& scale_operand =
         GetOperand(*batch_normalization.scale_operand_id);
-    CHECK_EQ(scale_operand.dimensions.size(), 1u);
+    CHECK_EQ(scale_operand.descriptor.Rank(), 1u);
     reshape_scale_tensor_index =
         SerializeTemporaryTensor(new_shape, input_tensor_type);
     operators_.emplace_back(SerializeReshapeOperation(
@@ -956,7 +957,7 @@
   if (batch_normalization.bias_operand_id) {
     const mojom::Operand& bias_operand =
         GetOperand(*batch_normalization.bias_operand_id);
-    CHECK_EQ(bias_operand.dimensions.size(), 1u);
+    CHECK_EQ(bias_operand.descriptor.Rank(), 1u);
     reshape_bias_tensor_index =
         SerializeTemporaryTensor(new_shape, input_tensor_type);
     operators_.emplace_back(SerializeReshapeOperation(
@@ -1029,15 +1030,15 @@
 
   const mojom::Operand& input_operand = GetOperand(conv2d.input_operand_id);
   // TODO(crbug.com/328733319): Support other tensor data types.
-  if (input_operand.data_type != mojom::DataType::kFloat32) {
+  if (input_operand.descriptor.data_type() != OperandDataType::kFloat32) {
     return base::unexpected("The data type of input is not supported.");
   }
 
-  const auto& input_shape = input_operand.dimensions;
+  const auto& input_shape = input_operand.descriptor.shape();
   CHECK_EQ(input_shape.size(), 4u);
   const uint32_t input_channels = input_shape[3];
   const mojom::Operand& output_operand = GetOperand(conv2d.output_operand_id);
-  const auto& output_shape = output_operand.dimensions;
+  const auto& output_shape = output_operand.descriptor.shape();
   CHECK_EQ(output_shape.size(), 4u);
   const uint32_t output_channels = output_shape[3];
   const bool depthwise =
@@ -1049,8 +1050,8 @@
   // For nhwc input layout, the default filter layout is ohwi for regular conv2d
   // and ihwo for depthwise conv2d.
   const mojom::Operand& filter_operand = GetOperand(conv2d.filter_operand_id);
-  CHECK_EQ(filter_operand.dimensions.size(), 4u);
-  const auto& filter_shape = filter_operand.dimensions;
+  CHECK_EQ(filter_operand.descriptor.Rank(), 4u);
+  const auto& filter_shape = filter_operand.descriptor.shape();
   CHECK_EQ(filter_shape.size(), 4u);
   const webnn::Size2d<uint32_t> filter_size2d = {.height = filter_shape[1],
                                                  .width = filter_shape[2]};
@@ -1176,13 +1177,13 @@
       operand_to_index_map_.at(op.input_operand_id);
   const int32_t output_tensor_index =
       operand_to_index_map_.at(op.output_operand_id);
-  const mojom::DataType input_data_type =
-      GetOperand(op.input_operand_id).data_type;
+  const OperandDataType input_data_type =
+      GetOperand(op.input_operand_id).descriptor.data_type();
   switch (op.kind) {
     case mojom::ElementWiseUnary::Kind::kAbs:
       CHECK(kFloatDataTypes.contains(input_data_type) ||
-            input_data_type == mojom::DataType::kInt32 ||
-            input_data_type == mojom::DataType::kInt8);
+            input_data_type == OperandDataType::kInt32 ||
+            input_data_type == OperandDataType::kInt8);
       return SerializeUnaryOperation(::tflite::BuiltinOperator_ABS,
                                      input_tensor_index, output_tensor_index);
     case mojom::ElementWiseUnary::Kind::kCeil:
@@ -1207,8 +1208,8 @@
                                      input_tensor_index, output_tensor_index);
     case mojom::ElementWiseUnary::Kind::kNeg:
       CHECK(kFloatDataTypes.contains(input_data_type) ||
-            input_data_type == mojom::DataType::kInt32 ||
-            input_data_type == mojom::DataType::kInt8);
+            input_data_type == OperandDataType::kInt32 ||
+            input_data_type == OperandDataType::kInt8);
       return SerializeUnaryOperation(::tflite::BuiltinOperator_NEG,
                                      input_tensor_index, output_tensor_index);
     case mojom::ElementWiseUnary::Kind::kSin:
@@ -1222,11 +1223,13 @@
     case mojom::ElementWiseUnary::Kind::kCast:
       return SerializeCastOperation(
           input_tensor_index,
-          MojoOperandTypeToTFLite(GetOperand(op.input_operand_id).data_type),
+          OperandDataTypeToTFLite(
+              GetOperand(op.input_operand_id).descriptor.data_type()),
           output_tensor_index,
-          MojoOperandTypeToTFLite(GetOperand(op.output_operand_id).data_type));
+          OperandDataTypeToTFLite(
+              GetOperand(op.output_operand_id).descriptor.data_type()));
     case mojom::ElementWiseUnary::Kind::kLogicalNot:
-      CHECK_EQ(input_data_type, mojom::DataType::kUint8);
+      CHECK_EQ(input_data_type, OperandDataType::kUint8);
       return SerializeLogicalNot(op);
     case mojom::ElementWiseUnary::Kind::kIdentity:
       // Implement WebNN identity operation with TFLite reshape operator, the
@@ -1268,9 +1271,9 @@
   int32_t indices_tensor_index =
       operand_to_index_map_.at(gather.indices_operand_id);
   const mojom::Operand& indices_operand = GetOperand(gather.indices_operand_id);
-  if (indices_operand.data_type == mojom::DataType::kUint32) {
+  if (indices_operand.descriptor.data_type() == OperandDataType::kUint32) {
     ASSIGN_OR_RETURN(const std::vector<int32_t> signed_indices_dimensions,
-                     ToSignedDimensions(indices_operand.dimensions));
+                     ToSignedDimensions(indices_operand.descriptor.shape()));
     indices_tensor_index = SerializeTemporaryTensor(signed_indices_dimensions,
                                                     ::tflite::TensorType_INT64);
 
@@ -1279,8 +1282,8 @@
         /*input_tensor_type=*/::tflite::TensorType_UINT32, indices_tensor_index,
         /*output_tensor_type=*/::tflite::TensorType_INT64));
   } else {
-    CHECK(indices_operand.data_type == mojom::DataType::kInt64 ||
-          indices_operand.data_type == mojom::DataType::kInt32);
+    CHECK(indices_operand.descriptor.data_type() == OperandDataType::kInt64 ||
+          indices_operand.descriptor.data_type() == OperandDataType::kInt32);
   }
 
   // The WebNN axis option is uint32 data type, but TFLite axis needs int32
@@ -1308,15 +1311,15 @@
     -> base::expected<OperatorOffset, std::string> {
   // Check for unsupported inputs.
   const mojom::Operand& output_operand = GetOperand(gemm.output_operand_id);
-  CHECK_EQ(output_operand.dimensions.size(), 2u);
-  CHECK(kFloatDataTypes.contains(output_operand.data_type));
-  const uint32_t output_channels = output_operand.dimensions[1];
+  CHECK_EQ(output_operand.descriptor.Rank(), 2u);
+  CHECK(kFloatDataTypes.contains(output_operand.descriptor.data_type()));
+  const uint32_t output_channels = output_operand.descriptor.shape()[1];
   if (gemm.c_operand_id.has_value()) {
     // The TFLite fully connected operator only supports a 1-D bias tensor with
     // `output_channels` dimensions.
     const mojom::Operand& bias_operand = GetOperand(*gemm.c_operand_id);
-    if (bias_operand.dimensions.size() != 1u ||
-        bias_operand.dimensions[0] != output_channels) {
+    if (bias_operand.descriptor.Rank() != 1u ||
+        bias_operand.descriptor.shape()[0] != output_channels) {
       // TODO(crbug.com/328652105): Support the bias with other dimensions by
       // element-wise addition operator.
       return base::unexpected(base::StringPrintf(
@@ -1350,15 +1353,16 @@
   const int32_t filter_index = operand_to_index_map_.at(filter_operand_id);
   if (!gemm.b_transpose) {
     const mojom::Operand& filter_operand = GetOperand(filter_operand_id);
-    CHECK_EQ(filter_operand.dimensions.size(), 2u);
+    CHECK_EQ(filter_operand.descriptor.Rank(), 2u);
     // The shape has been validated to not overflow before creating tensor.
     const auto filter_dimensions =
-        ToSignedDimensions(filter_operand.dimensions);
+        ToSignedDimensions(filter_operand.descriptor.shape());
     CHECK(filter_dimensions.has_value());
 
     const std::array<uint32_t, 2> permutation = {1u, 0u};
     transposed_filter_index = InsertTransposeOperation(
-        *filter_dimensions, MojoOperandTypeToTFLite(filter_operand.data_type),
+        *filter_dimensions,
+        OperandDataTypeToTFLite(filter_operand.descriptor.data_type()),
         filter_index, permutation);
   }
 
@@ -1387,14 +1391,14 @@
   // The subset expression `alpha * x + beta` is considered a linear operation.
   const mojom::Operand& input_operand =
       GetOperand(hard_sigmoid.input_operand_id);
-  CHECK(input_operand.data_type == mojom::DataType::kFloat16 ||
-        input_operand.data_type == mojom::DataType::kFloat32);
+  CHECK(input_operand.descriptor.data_type() == OperandDataType::kFloat16 ||
+        input_operand.descriptor.data_type() == OperandDataType::kFloat32);
   // The input shape has been validated to not overflow before creating tensor.
   const auto signed_input_dimensions =
-      ToSignedDimensions(input_operand.dimensions);
+      ToSignedDimensions(input_operand.descriptor.shape());
   CHECK(signed_input_dimensions.has_value());
   const ::tflite::TensorType input_tensor_type =
-      MojoOperandTypeToTFLite(input_operand.data_type);
+      OperandDataTypeToTFLite(input_operand.descriptor.data_type());
   const int32_t output_tensor_index_of_linear =
       SerializeTemporaryTensor(*signed_input_dimensions, input_tensor_type);
   operators_.emplace_back(SerializeLinearOperation(
@@ -1467,10 +1471,10 @@
       GetOperand(scale_or_bias_operand_id);
   // The shape has been validated to not overflow before creating tensor.
   const auto scale_or_bias_dimensions =
-      ToSignedDimensions(scale_or_bias_operand.dimensions);
+      ToSignedDimensions(scale_or_bias_operand.descriptor.shape());
   CHECK(scale_or_bias_dimensions.has_value());
   const ::tflite::TensorType scale_or_bias_tensor_type =
-      MojoOperandTypeToTFLite(scale_or_bias_operand.data_type);
+      OperandDataTypeToTFLite(scale_or_bias_operand.descriptor.data_type());
   const int32_t scale_or_bias_tensor_index =
       operand_to_index_map_.at(scale_or_bias_operand_id);
   std::vector<int32_t> compatible_shape(input_dimensions.size(), 1);
@@ -1511,17 +1515,17 @@
       GetOperand(instance_normalization.input_operand_id);
   // TODO(crbug.com/339654398): Support 16-bit float with dequantize operator
   // https://www.tensorflow.org/mlir/tfl_ops#tfldequantize_tfldequantizeop.
-  if (input_operand.data_type == mojom::DataType::kFloat16) {
+  if (input_operand.descriptor.data_type() == OperandDataType::kFloat16) {
     return base::unexpected("The 16-bit float data type is not supported.");
   }
-  CHECK_EQ(input_operand.data_type, mojom::DataType::kFloat32);
+  CHECK_EQ(input_operand.descriptor.data_type(), OperandDataType::kFloat32);
   // The input shape has been validated to not overflow before creating tensor.
   const auto signed_input_dimensions =
-      ToSignedDimensions(input_operand.dimensions);
+      ToSignedDimensions(input_operand.descriptor.shape());
   CHECK(signed_input_dimensions.has_value());
   CHECK_EQ(signed_input_dimensions->size(), 4u);
   const ::tflite::TensorType input_tensor_type =
-      MojoOperandTypeToTFLite(input_operand.data_type);
+      OperandDataTypeToTFLite(input_operand.descriptor.data_type());
   std::array<int32_t, 2> spatial_dimensions;
   uint32_t channel_axis;
   switch (instance_normalization.layout) {
@@ -1550,7 +1554,7 @@
   if (instance_normalization.scale_operand_id) {
     const mojom::Operand& scale_operand =
         GetOperand(*instance_normalization.scale_operand_id);
-    CHECK_EQ(scale_operand.dimensions.size(), 1u);
+    CHECK_EQ(scale_operand.descriptor.Rank(), 1u);
     reshape_scale_tensor_index =
         SerializeTemporaryTensor(new_shape, input_tensor_type);
     operators_.emplace_back(SerializeReshapeOperation(
@@ -1563,7 +1567,7 @@
   if (instance_normalization.bias_operand_id) {
     const mojom::Operand& bias_operand =
         GetOperand(*instance_normalization.bias_operand_id);
-    CHECK_EQ(bias_operand.dimensions.size(), 1u);
+    CHECK_EQ(bias_operand.descriptor.Rank(), 1u);
     reshape_bias_tensor_index =
         SerializeTemporaryTensor(new_shape, input_tensor_type);
     operators_.emplace_back(SerializeReshapeOperation(
@@ -1585,16 +1589,16 @@
       GetOperand(layer_normalization.input_operand_id);
   // TODO(crbug.com/339654398): Support 16-bit float with dequantize operator
   // https://www.tensorflow.org/mlir/tfl_ops#tfldequantize_tfldequantizeop.
-  if (input_operand.data_type == mojom::DataType::kFloat16) {
+  if (input_operand.descriptor.data_type() == OperandDataType::kFloat16) {
     return base::unexpected("The 16-bit float data type is not supported.");
   }
-  CHECK_EQ(input_operand.data_type, mojom::DataType::kFloat32);
+  CHECK_EQ(input_operand.descriptor.data_type(), OperandDataType::kFloat32);
   // The input shape has been validated to not overflow before creating tensor.
   const auto signed_input_dimensions =
-      ToSignedDimensions(input_operand.dimensions);
+      ToSignedDimensions(input_operand.descriptor.shape());
   CHECK(signed_input_dimensions.has_value());
   const ::tflite::TensorType input_tensor_type =
-      MojoOperandTypeToTFLite(input_operand.data_type);
+      OperandDataTypeToTFLite(input_operand.descriptor.data_type());
 
   // Get mean and variance values with reduceMean on the fly across all the
   // input features of each individual sample in the batch.
@@ -1645,11 +1649,11 @@
   const auto& input_operand = GetOperand(linear.input_operand_id);
   // The input shape has been validated to not overflow before creating tensor.
   const auto signed_input_dimensions =
-      ToSignedDimensions(input_operand.dimensions);
+      ToSignedDimensions(input_operand.descriptor.shape());
   CHECK(signed_input_dimensions.has_value());
   return SerializeLinearOperation(
       *signed_input_dimensions,
-      MojoOperandTypeToTFLite(input_operand.data_type),
+      OperandDataTypeToTFLite(input_operand.descriptor.data_type()),
       operand_to_index_map_.at(linear.input_operand_id),
       operand_to_index_map_.at(linear.output_operand_id), linear.alpha,
       linear.beta);
@@ -1667,14 +1671,14 @@
   const auto& input_operand = GetOperand(logical_not.input_operand_id);
   // The input shape has been validated to not overflow before creating tensor.
   const auto signed_input_dimensions =
-      ToSignedDimensions(input_operand.dimensions);
+      ToSignedDimensions(input_operand.descriptor.shape());
   CHECK(signed_input_dimensions.has_value());
   for (auto& bool_tensor_index : bool_tensor_indexes) {
     bool_tensor_index = SerializeTemporaryTensor(*signed_input_dimensions,
                                                  ::tflite::TensorType_BOOL);
   }
 
-  CHECK_EQ(input_operand.data_type, mojom::DataType::kUint8);
+  CHECK_EQ(input_operand.descriptor.data_type(), OperandDataType::kUint8);
   operators_.emplace_back(SerializeCastOperation(
       operand_to_index_map_.at(logical_not.input_operand_id),
       /*input_tensor_type=*/::tflite::TensorType_UINT8, bool_tensor_indexes[0],
@@ -1698,8 +1702,8 @@
 
 auto GraphBuilderTflite::SerializeMatmul(const mojom::Matmul& matmul)
     -> OperatorOffset {
-  const mojom::DataType a_operand_data_type =
-      GetOperand(matmul.a_operand_id).data_type;
+  const OperandDataType a_operand_data_type =
+      GetOperand(matmul.a_operand_id).descriptor.data_type();
   CHECK(kFloatDataTypes.contains(a_operand_data_type));
 
   const auto matmul_options =
@@ -1818,7 +1822,7 @@
   }
 
   const mojom::Operand& input_operand = GetOperand(pool2d.input_operand_id);
-  const auto& input_shape = input_operand.dimensions;
+  const auto& input_shape = input_operand.descriptor.shape();
   CHECK_EQ(input_shape.size(), 4u);
   const webnn::Size2d<uint32_t> input_size2d = {.height = input_shape[1],
                                                 .width = input_shape[2]};
@@ -1841,14 +1845,14 @@
   ::tflite::BuiltinOperator operator_code;
   switch (pool2d.kind) {
     case mojom::Pool2d::Kind::kAveragePool2d:
-      CHECK(kFloatDataTypes.contains(input_operand.data_type));
+      CHECK(kFloatDataTypes.contains(input_operand.descriptor.data_type()));
       operator_code = ::tflite::BuiltinOperator_AVERAGE_POOL_2D;
       break;
     case mojom::Pool2d::Kind::kMaxPool2d:
       operator_code = ::tflite::BuiltinOperator_MAX_POOL_2D;
       break;
     case mojom::Pool2d::Kind::kL2Pool2d:
-      CHECK(kFloatDataTypes.contains(input_operand.data_type));
+      CHECK(kFloatDataTypes.contains(input_operand.descriptor.data_type()));
       return base::unexpected("L2Pool2d is not supported in tflite.");
   }
 
@@ -1874,17 +1878,19 @@
 auto GraphBuilderTflite::SerializePrelu(const mojom::Prelu& prelu)
     -> base::expected<OperatorOffset, std::string> {
   const mojom::Operand& input_operand = GetOperand(prelu.input_operand_id);
-  CHECK(input_operand.data_type == mojom::DataType::kFloat32 ||
-        input_operand.data_type == mojom::DataType::kFloat16 ||
-        input_operand.data_type == mojom::DataType::kInt32 ||
-        input_operand.data_type == mojom::DataType::kInt8);
+  CHECK(input_operand.descriptor.data_type() == OperandDataType::kFloat32 ||
+        input_operand.descriptor.data_type() == OperandDataType::kFloat16 ||
+        input_operand.descriptor.data_type() == OperandDataType::kInt32 ||
+        input_operand.descriptor.data_type() == OperandDataType::kInt8);
   const mojom::Operand& slope_operand = GetOperand(prelu.slope_operand_id);
   // `ValidatePreluAndInferOutput` function has checked broadcastable shapes
   // between input and slope operand, but TFLite XNNPACK delegate doesn't
   // support to broadcast last dimension.
   // TODO(crbug.com/335517470): Support last dimension broadcastable.
-  if (!input_operand.dimensions.empty() && !slope_operand.dimensions.empty() &&
-      input_operand.dimensions.back() != slope_operand.dimensions.back()) {
+  if (input_operand.descriptor.Rank() != 0 &&
+      slope_operand.descriptor.Rank() != 0 &&
+      input_operand.descriptor.shape().back() !=
+          slope_operand.descriptor.shape().back()) {
     return base::unexpected(
         "The input and slope should have the same last dimension.");
   }
@@ -1910,10 +1916,10 @@
   // TODO(crbug.com/339654398): Support 16-bit float with dequantize operator
   // https://www.tensorflow.org/mlir/tfl_ops#tfldequantize_tfldequantizeop.
   const mojom::Operand& input_operand = GetOperand(reciprocal.input_operand_id);
-  if (input_operand.data_type == mojom::DataType::kFloat16) {
+  if (input_operand.descriptor.data_type() == OperandDataType::kFloat16) {
     return base::unexpected("The 16-bit float data type isn't supported.");
   }
-  CHECK_EQ(input_operand.data_type, mojom::DataType::kFloat32);
+  CHECK_EQ(input_operand.descriptor.data_type(), OperandDataType::kFloat32);
   const int32_t constant_tensor_index = SerializeTensorWithBuffer<float>(
       /*buffer=*/std::array<float, 1>{1.0},
       /*dimensions=*/{});
@@ -1929,7 +1935,7 @@
   // TODO(crbug.com/339654398): Support 16-bit float with dequantize operator
   // https://www.tensorflow.org/mlir/tfl_ops#tfldequantize_tfldequantizeop.
   const mojom::Operand& input_operand = GetOperand(reduce.input_operand_id);
-  if (input_operand.data_type == mojom::DataType::kFloat16) {
+  if (input_operand.descriptor.data_type() == OperandDataType::kFloat16) {
     return base::unexpected("The 16-bit float data type isn't supported.");
   }
 
@@ -1940,10 +1946,10 @@
   ::tflite::BuiltinOperator operator_code;
   // The input shape has been validated to not overflow before creating tensor.
   const auto signed_input_dimensions =
-      ToSignedDimensions(input_operand.dimensions);
+      ToSignedDimensions(input_operand.descriptor.shape());
   CHECK(signed_input_dimensions.has_value());
   const ::tflite::TensorType input_tensor_type =
-      MojoOperandTypeToTFLite(input_operand.data_type);
+      OperandDataTypeToTFLite(input_operand.descriptor.data_type());
   int32_t input_tensor_index =
       operand_to_index_map_.at(reduce.input_operand_id);
   switch (reduce.kind) {
@@ -1951,26 +1957,30 @@
       operator_code = ::tflite::BuiltinOperator_REDUCE_MAX;
       break;
     case mojom::Reduce::Kind::kMean:
-      CHECK(kFloatDataTypes.contains(input_operand.data_type));
+      CHECK(kFloatDataTypes.contains(input_operand.descriptor.data_type()));
       operator_code = ::tflite::BuiltinOperator_MEAN;
       break;
     case mojom::Reduce::Kind::kMin:
       operator_code = ::tflite::BuiltinOperator_REDUCE_MIN;
       break;
     case mojom::Reduce::Kind::kProduct:
-      CHECK(kFloatDataTypes.contains(input_operand.data_type) ||
-            k32BitIntegerDataTypes.contains(input_operand.data_type) ||
-            k64BitIntegerDataTypes.contains(input_operand.data_type));
+      CHECK(kFloatDataTypes.contains(input_operand.descriptor.data_type()) ||
+            k32BitIntegerDataTypes.contains(
+                input_operand.descriptor.data_type()) ||
+            k64BitIntegerDataTypes.contains(
+                input_operand.descriptor.data_type()));
       operator_code = ::tflite::BuiltinOperator_REDUCE_PROD;
       break;
     case mojom::Reduce::Kind::kSum:
-      CHECK(kFloatDataTypes.contains(input_operand.data_type) ||
-            k32BitIntegerDataTypes.contains(input_operand.data_type) ||
-            k64BitIntegerDataTypes.contains(input_operand.data_type));
+      CHECK(kFloatDataTypes.contains(input_operand.descriptor.data_type()) ||
+            k32BitIntegerDataTypes.contains(
+                input_operand.descriptor.data_type()) ||
+            k64BitIntegerDataTypes.contains(
+                input_operand.descriptor.data_type()));
       operator_code = ::tflite::BuiltinOperator_SUM;
       break;
     case mojom::Reduce::Kind::kLogSum:
-      CHECK(kFloatDataTypes.contains(input_operand.data_type));
+      CHECK(kFloatDataTypes.contains(input_operand.descriptor.data_type()));
       // The reduceLogSum can be emulated with appending log operation after
       // reduceSum.
       operator_code = ::tflite::BuiltinOperator_SUM;
@@ -1978,7 +1988,7 @@
     case mojom::Reduce::Kind::kLogSumExp: {
       // The reduceLogSumExp can be emulated with adding exp operation before
       // reduceSum and appending log operation after the reduceSum.
-      CHECK(kFloatDataTypes.contains(input_operand.data_type));
+      CHECK(kFloatDataTypes.contains(input_operand.descriptor.data_type()));
       const int32_t output_tensor_index_of_exp =
           SerializeTemporaryTensor(*signed_input_dimensions, input_tensor_type);
       operators_.emplace_back(SerializeUnaryOperation(
@@ -1990,7 +2000,7 @@
       break;
     }
     case mojom::Reduce::Kind::kL2: {
-      CHECK(kFloatDataTypes.contains(input_operand.data_type));
+      CHECK(kFloatDataTypes.contains(input_operand.descriptor.data_type()));
       // The reduceL2 can be emulated with appending pow(x, 0.5) operation after
       // reduceSumSquare.
       const int32_t output_tensor_index_of_sum =
@@ -1999,7 +2009,7 @@
           OperatorOffset operator_offset,
           SerializeReduceSumSquare(reduce, output_tensor_index_of_sum));
       operators_.emplace_back(operator_offset);
-      CHECK_EQ(input_operand.data_type, mojom::DataType::kFloat32);
+      CHECK_EQ(input_operand.descriptor.data_type(), OperandDataType::kFloat32);
       const int32_t pow_constant_tensor_index =
           SerializeTensorWithBuffer<float>(
               /*buffer=*/std::array<float, 1>{0.5},
@@ -2012,20 +2022,25 @@
     case mojom::Reduce::Kind::kSumSquare: {
       // The reduceSumSquare can be emulated with adding pow operation before
       // reduceSum.
-      CHECK(kFloatDataTypes.contains(input_operand.data_type) ||
-            k32BitIntegerDataTypes.contains(input_operand.data_type) ||
-            k64BitIntegerDataTypes.contains(input_operand.data_type));
+      CHECK(kFloatDataTypes.contains(input_operand.descriptor.data_type()) ||
+            k32BitIntegerDataTypes.contains(
+                input_operand.descriptor.data_type()) ||
+            k64BitIntegerDataTypes.contains(
+                input_operand.descriptor.data_type()));
       return SerializeReduceSumSquare(
           reduce, operand_to_index_map_.at(reduce.output_operand_id));
     }
     case mojom::Reduce::Kind::kL1: {
-      CHECK(kFloatDataTypes.contains(input_operand.data_type) ||
-            k32BitIntegerDataTypes.contains(input_operand.data_type) ||
-            k64BitIntegerDataTypes.contains(input_operand.data_type));
-      if (input_operand.data_type == mojom::DataType::kUint32 ||
-          input_operand.data_type == mojom::DataType::kUint64) {
+      CHECK(kFloatDataTypes.contains(input_operand.descriptor.data_type()) ||
+            k32BitIntegerDataTypes.contains(
+                input_operand.descriptor.data_type()) ||
+            k64BitIntegerDataTypes.contains(
+                input_operand.descriptor.data_type()));
+      if (input_operand.descriptor.data_type() == OperandDataType::kUint32 ||
+          input_operand.descriptor.data_type() == OperandDataType::kUint64) {
         return base::unexpected(base::StrCat(
-            {DataTypeToString(input_operand.data_type), " is not supported."}));
+            {DataTypeToString(input_operand.descriptor.data_type()),
+             " is not supported."}));
       }
       // The reduceL1 can be emulated with adding abs operation before
       // reduceSum.
@@ -2070,22 +2085,23 @@
   // The input shape has been validated to not overflow before creating tensor.
   const mojom::Operand& input_operand = GetOperand(reduce.input_operand_id);
   const auto signed_input_dimensions =
-      ToSignedDimensions(input_operand.dimensions);
+      ToSignedDimensions(input_operand.descriptor.shape());
   CHECK(signed_input_dimensions.has_value());
   const ::tflite::TensorType input_tensor_type =
-      MojoOperandTypeToTFLite(input_operand.data_type);
+      OperandDataTypeToTFLite(input_operand.descriptor.data_type());
   int32_t pow_constant_tensor_index;
-  if (input_operand.data_type == mojom::DataType::kFloat32) {
+  if (input_operand.descriptor.data_type() == OperandDataType::kFloat32) {
     pow_constant_tensor_index = SerializeTensorWithBuffer<float>(
         /*buffer=*/std::array<float, 1>{2.0},
         /*dimensions=*/{});
-  } else if (input_operand.data_type == mojom::DataType::kInt32) {
+  } else if (input_operand.descriptor.data_type() == OperandDataType::kInt32) {
     pow_constant_tensor_index = SerializeTensorWithBuffer<int32_t>(
         /*buffer=*/std::array<int32_t, 1>{2},
         /*dimensions=*/{});
   } else {
-    return base::unexpected(base::StrCat(
-        {DataTypeToString(input_operand.data_type), " is not supported."}));
+    return base::unexpected(
+        base::StrCat({DataTypeToString(input_operand.descriptor.data_type()),
+                      " is not supported."}));
   }
   const int32_t output_tensor_index_of_pow =
       SerializeTemporaryTensor(*signed_input_dimensions, input_tensor_type);
@@ -2101,11 +2117,11 @@
 
 auto GraphBuilderTflite::SerializeRelu(const mojom::Relu& relu)
     -> OperatorOffset {
-  const mojom::DataType input_data_type =
-      GetOperand(relu.input_operand_id).data_type;
+  const OperandDataType input_data_type =
+      GetOperand(relu.input_operand_id).descriptor.data_type();
   CHECK(kFloatDataTypes.contains(input_data_type) ||
-        input_data_type == mojom::DataType::kInt32 ||
-        input_data_type == mojom::DataType::kInt8);
+        input_data_type == OperandDataType::kInt32 ||
+        input_data_type == OperandDataType::kInt8);
 
   return SerializeUnaryOperation(
       ::tflite::BuiltinOperator::BuiltinOperator_RELU,
@@ -2119,7 +2135,7 @@
   // TODO: crbug.com/329543543 - `resample2d.scales` is dropped on the floor.
 
   const mojom::Operand& input_operand = GetOperand(resample2d.input_operand_id);
-  CHECK(kFloatDataTypes.contains(input_operand.data_type));
+  CHECK(kFloatDataTypes.contains(input_operand.descriptor.data_type()));
   const std::array<uint32_t, 2> supported_axes = {1, 2};
   if (!base::ranges::equal(resample2d.axes, supported_axes)) {
     // TODO: crbug.com/329658123: Support axes of {0, 1} and {2, 3}.
@@ -2157,7 +2173,8 @@
   // Serialize the target sizes for the dimensions [OutputHeight, OutputWidth].
   ASSIGN_OR_RETURN(
       std::vector<int32_t> signed_output_dimensions,
-      ToSignedDimensions(GetOperand(resample2d.output_operand_id).dimensions));
+      ToSignedDimensions(
+          GetOperand(resample2d.output_operand_id).descriptor.shape()));
   CHECK_EQ(signed_output_dimensions.size(), 4u);
 
   int32_t output_height = signed_output_dimensions[resample2d.axes[0]];
@@ -2187,7 +2204,7 @@
   // input to it.
   const mojom::Operand& output_operand = GetOperand(output_operand_id);
   ASSIGN_OR_RETURN(std::vector<int32_t> signed_output_dimensions,
-                   ToSignedDimensions(output_operand.dimensions));
+                   ToSignedDimensions(output_operand.descriptor.shape()));
 
   return SerializeReshapeOperation(operand_to_index_map_.at(input_operand_id),
                                    operand_to_index_map_.at(output_operand_id),
@@ -2253,7 +2270,8 @@
     -> OperatorOffset {
   const auto& input_operand = GetOperand(softmax.input_operand_id);
   // The input shape has been validated to not overflow before creating tensor.
-  auto signed_input_dimensions = ToSignedDimensions(input_operand.dimensions);
+  auto signed_input_dimensions =
+      ToSignedDimensions(input_operand.descriptor.shape());
   CHECK(signed_input_dimensions.has_value());
   const size_t input_rank = signed_input_dimensions->size();
 
@@ -2270,7 +2288,7 @@
   }
   // Transpose the input tensor to make the axis to be the last dimension.
   const ::tflite::TensorType input_tensor_type =
-      MojoOperandTypeToTFLite(input_operand.data_type);
+      OperandDataTypeToTFLite(input_operand.descriptor.data_type());
   std::vector<uint32_t> permutation(input_rank);
   std::iota(permutation.begin(), permutation.end(), 0);
   std::swap(permutation[softmax.axis], permutation[input_rank - 1]);
@@ -2303,7 +2321,7 @@
   // TODO(crbug.com/339654398): Support 16-bit float with dequantize operator
   // https://www.tensorflow.org/mlir/tfl_ops#tfldequantize_tfldequantizeop.
   const mojom::Operand& input_operand = GetOperand(softplus.input_operand_id);
-  if (input_operand.data_type == mojom::DataType::kFloat16) {
+  if (input_operand.descriptor.data_type() == OperandDataType::kFloat16) {
     return base::unexpected("The 16-bit float data type isn't supported.");
   }
 
@@ -2311,10 +2329,10 @@
   // `ln(1 + exp(x))`.
   // The input shape has been validated to not overflow before creating tensor.
   const auto signed_input_dimensions =
-      ToSignedDimensions(input_operand.dimensions);
+      ToSignedDimensions(input_operand.descriptor.shape());
   CHECK(signed_input_dimensions.has_value());
   const ::tflite::TensorType input_tensor_type =
-      MojoOperandTypeToTFLite(input_operand.data_type);
+      OperandDataTypeToTFLite(input_operand.descriptor.data_type());
   const int32_t output_tensor_index_of_exp =
       SerializeTemporaryTensor(*signed_input_dimensions, input_tensor_type);
   operators_.emplace_back(SerializeUnaryOperation(
@@ -2326,7 +2344,7 @@
   // TODO(crbug.com/339654398): Convert the 32-bit floating-point data to 16-bit
   // floating-point data with fp16_ieee_from_fp32_value function if some
   // delegates support 16-bit float inference.
-  CHECK_EQ(input_operand.data_type, mojom::DataType::kFloat32);
+  CHECK_EQ(input_operand.descriptor.data_type(), OperandDataType::kFloat32);
   const int32_t constant_tensor_index = SerializeTensorWithBuffer<float>(
       /*buffer=*/std::array<float, 1>{1},
       /*dimensions=*/{});
@@ -2346,7 +2364,7 @@
   // TODO(crbug.com/339654398): Support 16-bit float with dequantize operator
   // https://www.tensorflow.org/mlir/tfl_ops#tfldequantize_tfldequantizeop.
   const mojom::Operand& input_operand = GetOperand(softsign.input_operand_id);
-  if (input_operand.data_type == mojom::DataType::kFloat16) {
+  if (input_operand.descriptor.data_type() == OperandDataType::kFloat16) {
     return base::unexpected("The 16-bit float data type isn't supported.");
   }
 
@@ -2354,10 +2372,10 @@
   // `x / (1 + |x|)`.
   // The input shape has been validated to not overflow before creating tensor.
   const auto signed_input_dimensions =
-      ToSignedDimensions(input_operand.dimensions);
+      ToSignedDimensions(input_operand.descriptor.shape());
   CHECK(signed_input_dimensions.has_value());
   const ::tflite::TensorType input_tensor_type =
-      MojoOperandTypeToTFLite(input_operand.data_type);
+      OperandDataTypeToTFLite(input_operand.descriptor.data_type());
   const int32_t output_tensor_index_of_abs =
       SerializeTemporaryTensor(*signed_input_dimensions, input_tensor_type);
   const int32_t input_tensor_index =
@@ -2370,7 +2388,7 @@
   // TODO(crbug.com/339654398): Convert the 32-bit floating-point data to 16-bit
   // floating-point data with fp16_ieee_from_fp32_value function if some
   // delegates support 16-bit float inference.
-  CHECK_EQ(input_operand.data_type, mojom::DataType::kFloat32);
+  CHECK_EQ(input_operand.descriptor.data_type(), OperandDataType::kFloat32);
   const int32_t constant_tensor_index = SerializeTensorWithBuffer<float>(
       /*buffer=*/std::array<float, 1>{1},
       /*dimensions=*/{});
@@ -2408,7 +2426,7 @@
     // The output shape has been validated to not overflow before creating
     // tensor.
     const std::vector<uint32_t>& output_shape =
-        GetOperand(output_id).dimensions;
+        GetOperand(output_id).descriptor.shape();
     CHECK_LT(split.axis, output_shape.size());
     split_sizes.push_back(output_shape[split.axis]);
 
@@ -2450,10 +2468,10 @@
   const mojom::Operand& input_operand = GetOperand(tan.input_operand_id);
   // The input shape has been validated to not overflow before creating tensor.
   const auto signed_input_dimensions =
-      ToSignedDimensions(input_operand.dimensions);
+      ToSignedDimensions(input_operand.descriptor.shape());
   CHECK(signed_input_dimensions.has_value());
   const ::tflite::TensorType input_tensor_type =
-      MojoOperandTypeToTFLite(input_operand.data_type);
+      OperandDataTypeToTFLite(input_operand.descriptor.data_type());
   const int32_t output_tensor_index_of_sin =
       SerializeTemporaryTensor(*signed_input_dimensions, input_tensor_type);
   const int32_t input_tensor_index =
@@ -2500,12 +2518,12 @@
   // The shape of condition operand has been validated to not overflow before
   // creating tensor.
   const auto signed_condition_dimensions =
-      ToSignedDimensions(condition_operand.dimensions);
+      ToSignedDimensions(condition_operand.descriptor.shape());
   CHECK(signed_condition_dimensions.has_value());
   const int32_t condition_bool_tensor_index = SerializeTemporaryTensor(
       *signed_condition_dimensions, ::tflite::TensorType_BOOL);
 
-  CHECK_EQ(condition_operand.data_type, mojom::DataType::kUint8);
+  CHECK_EQ(condition_operand.descriptor.data_type(), OperandDataType::kUint8);
   operators_.emplace_back(SerializeCastOperation(
       operand_to_index_map_.at(where.condition_operand_id),
       /*input_tensor_type=*/::tflite::TensorType_UINT8,
diff --git a/services/webnn/webnn_graph_impl.cc b/services/webnn/webnn_graph_impl.cc
index 6065928..8fa89750 100644
--- a/services/webnn/webnn_graph_impl.cc
+++ b/services/webnn/webnn_graph_impl.cc
@@ -35,30 +35,32 @@
 // Maps the id to its `mojo::Operand`.
 using IdToOperandMap = base::flat_map<uint64_t, mojom::OperandPtr>;
 
-webnn::Operand::DataType MojoOperandTypeToComponent(mojom::DataType data_type) {
+webnn::Operand::DataType OperandDataTypeToComponent(OperandDataType data_type) {
   switch (data_type) {
-    case mojom::DataType::kFloat32:
+    case OperandDataType::kFloat32:
       return webnn::Operand::DataType::kFloat32;
-    case mojom::DataType::kFloat16:
+    case OperandDataType::kFloat16:
       return webnn::Operand::DataType::kFloat16;
-    case mojom::DataType::kInt32:
+    case OperandDataType::kInt32:
       return webnn::Operand::DataType::kInt32;
-    case mojom::DataType::kUint32:
+    case OperandDataType::kUint32:
       return webnn::Operand::DataType::kUint32;
-    case mojom::DataType::kInt64:
+    case OperandDataType::kInt64:
       return webnn::Operand::DataType::kInt64;
-    case mojom::DataType::kUint64:
+    case OperandDataType::kUint64:
       return webnn::Operand::DataType::kUint64;
-    case mojom::DataType::kInt8:
+    case OperandDataType::kInt8:
       return webnn::Operand::DataType::kInt8;
-    case mojom::DataType::kUint8:
+    case OperandDataType::kUint8:
       return webnn::Operand::DataType::kUint8;
   }
 }
 
+// TODO(crbug.com/325598628): Remove all uses of this helper.
 webnn::Operand MojoOperandToComponent(const mojom::Operand* mojo_operand) {
-  return webnn::Operand(MojoOperandTypeToComponent(mojo_operand->data_type),
-                        mojo_operand->dimensions);
+  return webnn::Operand(
+      OperandDataTypeToComponent(mojo_operand->descriptor.data_type()),
+      mojo_operand->descriptor.shape());
 }
 
 webnn::InputOperandLayout MojoInputOperandLayoutToComponent(
@@ -259,15 +261,13 @@
       const auto* const input =
           GetMojoOperand(id_to_operand_map, conv2d->input_operand_id);
       CHECK(input);
-      const auto& input_shape = input->dimensions;
-      CHECK_EQ(input_shape.size(), 4u);
-      const uint32_t input_channels = input_shape[3];
+      CHECK_EQ(input->descriptor.Rank(), 4u);
+      const uint32_t input_channels = input->descriptor.shape()[3];
       const auto* const output =
           GetMojoOperand(id_to_operand_map, conv2d->output_operand_id);
       CHECK(output);
-      const auto& output_shape = output->dimensions;
-      CHECK_EQ(output_shape.size(), 4u);
-      const uint32_t output_channels = output_shape[3];
+      CHECK_EQ(output->descriptor.Rank(), 4u);
+      const uint32_t output_channels = output->descriptor.shape()[3];
       // Depthwise conv2d is "options.groups == input_channels ==
       // output_channels".
       const bool depthwise = webnn::IsDepthwiseConv2d(
@@ -356,18 +356,18 @@
 
   // Convert the output sizes that fetched from dimensions of output operand.
   auto* output = GetMojoOperand(id_to_operand_map, conv2d->output_operand_id);
-  CHECK_EQ(output->dimensions.size(), 4u);
+  CHECK_EQ(output->descriptor.Rank(), 4u);
   webnn::Size2d<uint32_t> output_sizes;
   switch (context_properties.conv2d_input_layout) {
     case webnn::mojom::InputOperandLayout::kChannelsFirst:
       // "channelsFirst": [batches, input_channels, height, width]
-      output_sizes.height = output->dimensions[2];
-      output_sizes.width = output->dimensions[3];
+      output_sizes.height = output->descriptor.shape()[2];
+      output_sizes.width = output->descriptor.shape()[3];
       break;
     case webnn::mojom::InputOperandLayout::kChannelsLast:
       // "channelsLast": [batches, height, width, input_channels]
-      output_sizes.height = output->dimensions[1];
-      output_sizes.width = output->dimensions[2];
+      output_sizes.height = output->descriptor.shape()[1];
+      output_sizes.width = output->descriptor.shape()[2];
       break;
   }
   component_attributes.output_sizes = std::move(output_sizes);
@@ -416,15 +416,17 @@
       .height = pool2d->dilations->height, .width = pool2d->dilations->width};
   component_attributes.layout =
       MojoInputOperandLayoutToComponent(pool2d->layout);
-  CHECK_EQ(output->dimensions.size(), 4u);
+  CHECK_EQ(output->descriptor.Rank(), 4u);
   switch (component_attributes.layout) {
     case webnn::InputOperandLayout::kNchw:
-      component_attributes.output_sizes = webnn::Size2d<uint32_t>{
-          .height = output->dimensions[2], .width = output->dimensions[3]};
+      component_attributes.output_sizes =
+          webnn::Size2d<uint32_t>{.height = output->descriptor.shape()[2],
+                                  .width = output->descriptor.shape()[3]};
       break;
     case webnn::InputOperandLayout::kNhwc:
-      component_attributes.output_sizes = webnn::Size2d<uint32_t>{
-          .height = output->dimensions[1], .width = output->dimensions[2]};
+      component_attributes.output_sizes =
+          webnn::Size2d<uint32_t>{.height = output->descriptor.shape()[1],
+                                  .width = output->descriptor.shape()[2]};
       break;
   }
   return component_attributes;
@@ -551,20 +553,12 @@
     return false;
   }
 
-  const auto input_data_type = input->data_type;
-  if (!input_constraint.Has(MojoOperandTypeToComponent(input_data_type))) {
+  const auto input_data_type = input->descriptor.data_type();
+  if (!input_constraint.Has(OperandDataTypeToComponent(input_data_type))) {
     // The data type is not in the constraint.
     return false;
   }
-  if (output->data_type != input_data_type) {
-    // The output data type doesn't match input data type.
-    return false;
-  }
-  if (output->dimensions != input->dimensions) {
-    // The output shape is not expected.
-    return false;
-  }
-  return true;
+  return output->descriptor == input->descriptor;
 }
 
 bool ValidateCastOperation(const IdToOperandMap& id_to_operand_map,
@@ -583,7 +577,8 @@
     // The unary operator is invalid.
     return false;
   }
-  if (output->dimensions != input->dimensions) {
+  if (!base::ranges::equal(output->descriptor.shape(),
+                           input->descriptor.shape())) {
     // The output shape is not expected.
     return false;
   }
@@ -744,7 +739,7 @@
 
   // The input and output rank need to be validated before converting to
   // `webnn::Conv2dAttributes`.
-  if (input->dimensions.size() != 4 || output->dimensions.size() != 4) {
+  if (input->descriptor.Rank() != 4 || output->descriptor.Rank() != 4) {
     // The element of input and output dimensions should be 4.
     return false;
   }
@@ -807,19 +802,19 @@
     const mojom::Operand* rhs,
     const mojom::Operand* output,
     const mojom::ElementWiseBinaryPtr& operation) {
-  if (lhs->data_type != rhs->data_type) {
+  if (lhs->descriptor.data_type() != rhs->descriptor.data_type()) {
     // The input types don't match.
     return false;
   }
 
   if (IsLogicalElementWiseBinary(operation->kind)) {
-    if (output->data_type != mojom::DataType::kUint8) {
+    if (output->descriptor.data_type() != OperandDataType::kUint8) {
       // For logical operations, the output data type must be uint8.
       return false;
     }
   } else {
     // For all other operations, the input and output data types must match.
-    if (output->data_type != lhs->data_type) {
+    if (output->descriptor.data_type() != lhs->descriptor.data_type()) {
       return false;
     }
   }
@@ -850,12 +845,13 @@
     return false;
   }
 
-  auto dims_output = BroadcastShapes(a->dimensions, b->dimensions);
+  auto dims_output =
+      BroadcastShapes(a->descriptor.shape(), b->descriptor.shape());
   if (!dims_output) {
     // The input shapes are not broadcastable.
     return false;
   }
-  if (output->dimensions != dims_output.value()) {
+  if (!base::ranges::equal(output->descriptor.shape(), dims_output.value())) {
     // The output shape is not expected.
     return false;
   }
@@ -931,18 +927,18 @@
     // The expand operator is invalid.
     return false;
   }
-  if (output->data_type != input->data_type) {
+  if (output->descriptor.data_type() != input->descriptor.data_type()) {
     // The output data type doesn't match input data type.
     return false;
   }
 
-  auto output_shape =
-      BroadcastShapes(input->dimensions, output->dimensions, false);
+  auto output_shape = BroadcastShapes(input->descriptor.shape(),
+                                      output->descriptor.shape(), false);
   if (!output_shape) {
     // The input shape is not broadcastable to the output shape.
     return false;
   }
-  CHECK(output_shape.value() == output->dimensions);
+  CHECK(base::ranges::equal(output_shape.value(), output->descriptor.shape()));
 
   return true;
 }
@@ -1564,14 +1560,13 @@
 
   if (pool2d->kind == mojom::Pool2d::Kind::kAveragePool2d ||
       pool2d->kind == mojom::Pool2d::Kind::kL2Pool2d) {
-    if (!(input->data_type == mojom::DataType::kFloat32 ||
-          input->data_type == mojom::DataType::kFloat16)) {
+    if (!(input->descriptor.data_type() == OperandDataType::kFloat32 ||
+          input->descriptor.data_type() == OperandDataType::kFloat16)) {
       return false;
     }
   }
 
-  if (output->dimensions.size() != 4) {
-    // The element of output dimensions should be 4.
+  if (output->descriptor.Rank() != 4) {
     return false;
   }
   auto validated_output = ValidatePool2dAndInferOutput(
@@ -1640,7 +1635,7 @@
   if (resample2d->scales) {
     scales_or_sizes = resample2d->scales.value();
   } else {
-    const auto& output_dimensions = output->dimensions;
+    const auto& output_dimensions = output->descriptor.shape();
     if (axes.size() != 2 || axes[0] >= output_dimensions.size() ||
         axes[1] >= output_dimensions.size()) {
       return false;
@@ -1675,20 +1670,12 @@
     // The reshape operator is invalid.
     return false;
   }
-  if (output->data_type != input->data_type) {
-    // The output data type doesn't match input data type.
+  if (output->descriptor.data_type() != input->descriptor.data_type()) {
     return false;
   }
 
-  base::expected<size_t, std::string> output_number_of_elements =
-      ValidateAndCalculateElementsNumber(output->dimensions);
-  // The dimensions of input and output operand are valid which were already
-  // validated before calling this function.
-  CHECK(output_number_of_elements.has_value());
-  base::expected<size_t, std::string> input_number_of_elements =
-      ValidateAndCalculateElementsNumber(input->dimensions);
-  CHECK(input_number_of_elements.has_value());
-  if (output_number_of_elements.value() != input_number_of_elements.value()) {
+  if (input->descriptor.NumberOfElements() !=
+      output->descriptor.NumberOfElements()) {
     // The output shape is not expected.
     return false;
   }
@@ -1769,10 +1756,10 @@
       return false;
     }
 
-    if (split->axis >= output->dimensions.size()) {
+    if (split->axis >= output->descriptor.Rank()) {
       return false;
     }
-    splits.push_back(output->dimensions[split->axis]);
+    splits.push_back(output->descriptor.shape()[split->axis]);
     processed_operands.insert(output_id);
   }
 
@@ -1933,10 +1920,7 @@
     CHECK(operand);
     CHECK(operand->name.has_value());
 
-    names_to_descriptors.emplace(
-        *operand->name,
-        *OperandDescriptor::Create(ToOperandDataType(operand->data_type),
-                                   operand->dimensions));
+    names_to_descriptors.emplace(*operand->name, operand->descriptor);
   }
   return names_to_descriptors;
 }
@@ -2197,15 +2181,6 @@
   graph_outputs.reserve(graph_info->output_operands.size());
   base::flat_map<uint64_t, size_t> constant_id_to_byte_length_map;
   for (auto& [id, operand] : graph_info->id_to_operand_map) {
-    base::expected<size_t, std::string> byte_length =
-        ValidateAndCalculateByteLength(
-            OperandDescriptor::GetBytesPerElement(
-                ToOperandDataType(operand->data_type)),
-            operand->dimensions);
-    if (!byte_length.has_value()) {
-      return false;
-    }
-
     const std::optional<std::string>& name = operand->name;
     switch (operand->kind) {
       case mojom::Operand::Kind::kInput: {
@@ -2239,7 +2214,8 @@
           // Constant operand should not have a name.
           return false;
         }
-        constant_id_to_byte_length_map[id] = byte_length.value();
+        constant_id_to_byte_length_map[id] =
+            operand->descriptor.PackedByteLength();
         processed_operands.insert(id);
         break;
       }
diff --git a/services/webnn/webnn_graph_impl_backend_test.cc b/services/webnn/webnn_graph_impl_backend_test.cc
index f22d990..6137783 100644
--- a/services/webnn/webnn_graph_impl_backend_test.cc
+++ b/services/webnn/webnn_graph_impl_backend_test.cc
@@ -181,32 +181,32 @@
 // Get the output data from a `mojo_base::BigBuffer` as 32-bit floating-point
 // number.
 std::vector<float> GetFloatOutputData(mojo_base::BigBuffer big_buffer,
-                                      mojom::DataType type) {
+                                      OperandDataType type) {
   switch (type) {
-    case mojom::DataType::kFloat32:
+    case OperandDataType::kFloat32:
       return BigBufferToVector<float>(std::move(big_buffer));
-    case mojom::DataType::kFloat16:
+    case OperandDataType::kFloat16:
       return Float16ToFloat32(
           BigBufferToVector<float16>(std::move(big_buffer)));
-    case mojom::DataType::kInt32:
-    case mojom::DataType::kUint32:
-    case mojom::DataType::kInt64:
-    case mojom::DataType::kUint64:
-    case mojom::DataType::kInt8:
-    case mojom::DataType::kUint8:
+    case OperandDataType::kInt32:
+    case OperandDataType::kUint32:
+    case OperandDataType::kInt64:
+    case OperandDataType::kUint64:
+    case OperandDataType::kInt8:
+    case OperandDataType::kUint8:
       NOTREACHED_NORETURN();
   }
 }
 
 template <typename T>
 struct OperandInfo {
-  mojom::DataType type;
+  OperandDataType type;
   std::vector<uint32_t> dimensions;
   std::vector<T> values;
 #if BUILDFLAG(IS_MAC)
   OperandInfo<int32_t> ToInt32() {
     return OperandInfo<int32_t>{
-        .type = mojom::DataType::kInt32,
+        .type = OperandDataType::kInt32,
         .dimensions = dimensions,
         .values = std::vector<int32_t>(values.begin(), values.end())};
   }
@@ -455,14 +455,14 @@
 TEST_F(WebNNGraphImplBackendTest, BuildAndComputeSingleOperatorArgMinMax) {
   // Test argMax with axes = {0} and select_last_index = false.
   {
-    ArgMinMaxTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ArgMinMaxTester<float>{.input = {.type = OperandDataType::kFloat32,
                                      .dimensions = {2, 3},
                                      .values = {1, 2, 3, 4, 5, 6}},
                            .axes = {0},
                            .keep_dimensions = true,
                            .select_last_index = false,
                            .kind = mojom::ArgMinMax::Kind::kMax,
-                           .output = {.type = mojom::DataType::kInt64,
+                           .output = {.type = OperandDataType::kInt64,
                                       .dimensions = {1, 3},
                                       .values = {1, 1, 1}}}
         .Test();
@@ -470,28 +470,28 @@
   // Test argMax with axes = {0, 1} and select_last_index = false. The index is
   // into the flattened array: [1, 2, 3, 4, 5, 6].
   {
-    ArgMinMaxTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ArgMinMaxTester<float>{.input = {.type = OperandDataType::kFloat32,
                                      .dimensions = {2, 3},
                                      .values = {1, 2, 3, 4, 5, 6}},
                            .axes = {0, 1},
                            .keep_dimensions = true,
                            .select_last_index = false,
                            .kind = mojom::ArgMinMax::Kind::kMax,
-                           .output = {.type = mojom::DataType::kInt64,
+                           .output = {.type = OperandDataType::kInt64,
                                       .dimensions = {1, 1},
                                       .values = {5}}}
         .Test();
   }
   // Test argMax with axes = {1} and select_last_index = false.
   {
-    ArgMinMaxTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ArgMinMaxTester<float>{.input = {.type = OperandDataType::kFloat32,
                                      .dimensions = {3, 3},
                                      .values = {1, 2, 3, 4, 3, 4, 3, 2, 1}},
                            .axes = {1},
                            .keep_dimensions = true,
                            .select_last_index = false,
                            .kind = mojom::ArgMinMax::Kind::kMax,
-                           .output = {.type = mojom::DataType::kInt64,
+                           .output = {.type = OperandDataType::kInt64,
                                       .dimensions = {3, 1},
                                       .values = {2, 0, 0}}}
         .Test();
@@ -499,28 +499,28 @@
   // Test argMax with axes = {1}, keep_dimensions = false and select_last_index
   // = true.
   {
-    ArgMinMaxTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ArgMinMaxTester<float>{.input = {.type = OperandDataType::kFloat32,
                                      .dimensions = {3, 3},
                                      .values = {1, 2, 3, 4, 3, 4, 3, 2, 1}},
                            .axes = {1},
                            .keep_dimensions = false,
                            .select_last_index = true,
                            .kind = mojom::ArgMinMax::Kind::kMax,
-                           .output = {.type = mojom::DataType::kInt64,
+                           .output = {.type = OperandDataType::kInt64,
                                       .dimensions = {3},
                                       .values = {2, 2, 0}}}
         .Test();
   }
   // Test argMin with axes = {1} and select_last_index = false.
   {
-    ArgMinMaxTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ArgMinMaxTester<float>{.input = {.type = OperandDataType::kFloat32,
                                      .dimensions = {3, 3},
                                      .values = {1, 2, 3, 4, 3, 4, 3, 2, 1}},
                            .axes = {1},
                            .keep_dimensions = true,
                            .select_last_index = false,
                            .kind = mojom::ArgMinMax::Kind::kMin,
-                           .output = {.type = mojom::DataType::kInt64,
+                           .output = {.type = OperandDataType::kInt64,
                                       .dimensions = {3, 1},
                                       .values = {0, 1, 2}}}
         .Test();
@@ -528,14 +528,14 @@
   // Test argMin with axes = {1, 2} and select_last_index = false. The indexes
   // are into the partially flattened array: [[ 1, 2, 3, 4] ], [1, 2, 3, 4]].
   {
-    ArgMinMaxTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ArgMinMaxTester<float>{.input = {.type = OperandDataType::kFloat32,
                                      .dimensions = {2, 2, 2},
                                      .values = {1, 2, 3, 4, 1, 2, 3, 4}},
                            .axes = {1, 2},
                            .keep_dimensions = true,
                            .select_last_index = false,
                            .kind = mojom::ArgMinMax::Kind::kMin,
-                           .output = {.type = mojom::DataType::kInt64,
+                           .output = {.type = OperandDataType::kInt64,
                                       .dimensions = {2, 1, 1},
                                       .values = {0, 0}}}
         .Test();
@@ -543,14 +543,14 @@
   // Test argMin with axes = {0, 2} and select_last_index = true. The indexes
   // are into the partially flattened array: [[1, 2, 1, 2], [3, 4, 3, 4]].
   {
-    ArgMinMaxTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ArgMinMaxTester<float>{.input = {.type = OperandDataType::kFloat32,
                                      .dimensions = {2, 2, 2},
                                      .values = {1, 2, 3, 4, 1, 2, 3, 4}},
                            .axes = {0, 2},
                            .keep_dimensions = false,
                            .select_last_index = true,
                            .kind = mojom::ArgMinMax::Kind::kMin,
-                           .output = {.type = mojom::DataType::kInt64,
+                           .output = {.type = OperandDataType::kInt64,
                                       .dimensions = {2},
                                       .values = {2, 2}}}
         .Test();
@@ -558,14 +558,14 @@
   // Test argMin with axes = {0}, keep_dimensions = false and select_last_index
   // = true.
   {
-    ArgMinMaxTester<float16>{.input = {.type = mojom::DataType::kFloat16,
+    ArgMinMaxTester<float16>{.input = {.type = OperandDataType::kFloat16,
                                        .dimensions = {3, 3},
                                        .values = {1, 2, 3, 4, 3, 4, 3, 2, 1}},
                              .axes = {0},
                              .keep_dimensions = false,
                              .select_last_index = true,
                              .kind = mojom::ArgMinMax::Kind::kMin,
-                             .output = {.type = mojom::DataType::kInt64,
+                             .output = {.type = OperandDataType::kInt64,
                                         .dimensions = {3},
                                         .values = {0, 2, 2}}}
         .Test();
@@ -758,22 +758,22 @@
   {  // Test batchNormalization with 4-D input, default axis and activation =
     // linear.
     BatchNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 1, 3},
                   .values = {-1, 0, 1, 2, 3, 4}},
-        .mean = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kFloat32,
                  .dimensions = {2},
                  .values = {0, 3}},
-        .variance = {.type = mojom::DataType::kFloat32,
+        .variance = {.type = OperandDataType::kFloat32,
                      .dimensions = {2},
                      .values = {1.0, 1.5}},
-        .scale = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .scale = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                     .dimensions = {2},
                                     .values = {1.0, 1.5}},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {2},
                                    .values = {0, 1}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 1, 3},
                    .values = {-8.999950000374997, 1, 10.999950000374997,
                               -1.2474078892909666, 11, 23.24740788929097}}}
@@ -785,22 +785,22 @@
   {
     // Test batchNormalization with 4-D input with activation = hardsigmoid.
     BatchNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 1, 3},
                   .values = {-1, 0, 1, 2, 3, 4}},
-        .mean = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kFloat32,
                  .dimensions = {2},
                  .values = {0, 3}},
-        .variance = {.type = mojom::DataType::kFloat32,
+        .variance = {.type = OperandDataType::kFloat32,
                      .dimensions = {2},
                      .values = {1.0, 1.5}},
-        .scale = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .scale = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                     .dimensions = {2},
                                     .values = {1.0, 1.5}},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {2},
                                    .values = {0, 1}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 1, 3},
                    .values = {1, 1, 1, 1, 1, 1}}}
         .TestFusingStandaloneActivation(
@@ -811,22 +811,22 @@
   {
     // Test batchNormalization with 4-D input with activation = relu.
     BatchNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 1, 3},
                   .values = {-1, 0, 1, 2, 3, 4}},
-        .mean = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kFloat32,
                  .dimensions = {2},
                  .values = {0, 3}},
-        .variance = {.type = mojom::DataType::kFloat32,
+        .variance = {.type = OperandDataType::kFloat32,
                      .dimensions = {2},
                      .values = {1.0, 1.5}},
-        .scale = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .scale = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                     .dimensions = {2},
                                     .values = {1.0, 1.5}},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {2},
                                    .values = {0, 1}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 1, 3},
                    .values = {0, 0, 0.9999950000374997, 0, 1,
                               2.224740788929097}}}
@@ -836,23 +836,23 @@
   {
     // Test batchNormalization with 4-D input with activation = softplus.
     BatchNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 1, 3},
                   .values = {-100, -50, 100, 101, 102, 103}},
-        .mean = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kFloat32,
                  .dimensions = {2},
                  .values = {0, 3}},
-        .variance = {.type = mojom::DataType::kFloat32,
+        .variance = {.type = OperandDataType::kFloat32,
                      .dimensions = {2},
                      .values = {1, 4}},
-        .scale = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .scale = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                     .dimensions = {2},
                                     .values = {1, 2}},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {2},
                                    .values = {0, 1}},
         .attributes = {.epsilon = 0},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 1, 3},
                    .values = {0, 0, 100, 99, 100, 101}}}
         .TestFusingStandaloneActivation(
@@ -861,23 +861,23 @@
   {
     // Test batchNormalization with 1-D input with activation = softsign.
     BatchNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2},
                   .values = {-1, 1}},
-        .mean = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kFloat32,
                  .dimensions = {2},
                  .values = {-1, 1}},
-        .variance = {.type = mojom::DataType::kFloat32,
+        .variance = {.type = OperandDataType::kFloat32,
                      .dimensions = {2},
                      .values = {1.0, 1.5}},
-        .scale = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .scale = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                     .dimensions = {2},
                                     .values = {1.0, 1.5}},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {2},
                                    .values = {0, 1}},
         .attributes = {.axis = 0},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2},
                    .values = {0, 0.5}}}
         .TestFusingStandaloneActivation(
@@ -890,22 +890,22 @@
   {
     // Test batchNormalization with 4-D input with default axis.
     BatchNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 1, 3},
                   .values = {-1, 0, 1, 2, 3, 4}},
-        .mean = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kFloat32,
                  .dimensions = {2},
                  .values = {0, 3}},
-        .variance = {.type = mojom::DataType::kFloat32,
+        .variance = {.type = OperandDataType::kFloat32,
                      .dimensions = {2},
                      .values = {1.0, 1.5}},
-        .scale = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .scale = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                     .dimensions = {2},
                                     .values = {1.0, 1.5}},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {2},
                                    .values = {0, 1}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 1, 3},
                    .values = {-0.9999950000374997, 0, 0.9999950000374997,
                               -0.22474078892909666, 1, 2.224740788929097}}}
@@ -914,23 +914,23 @@
   {
     // Test batchNormalization with 4-D input with axis = 3.
     BatchNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 3, 2},
                   .values = {-1, 2, 0, 3, 1, 4}},
-        .mean = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kFloat32,
                  .dimensions = {2},
                  .values = {0, 3}},
-        .variance = {.type = mojom::DataType::kFloat32,
+        .variance = {.type = OperandDataType::kFloat32,
                      .dimensions = {2},
                      .values = {1.0, 1.5}},
-        .scale = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .scale = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                     .dimensions = {2},
                                     .values = {1.0, 1.5}},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {2},
                                    .values = {0, 1}},
         .attributes = {.axis = 3},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 2},
                    .values = {-0.9999950000374997, -0.22474078892909666, 0, 1,
                               0.9999950000374997, 2.224740788929097}}}
@@ -939,23 +939,23 @@
   {
     // Test batchNormalization with 1-D input with axis = 0.
     BatchNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2},
                   .values = {-1, 1}},
-        .mean = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kFloat32,
                  .dimensions = {2},
                  .values = {-1, 1}},
-        .variance = {.type = mojom::DataType::kFloat32,
+        .variance = {.type = OperandDataType::kFloat32,
                      .dimensions = {2},
                      .values = {1.0, 1.5}},
-        .scale = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .scale = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                     .dimensions = {2},
                                     .values = {1.0, 1.5}},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {2},
                                    .values = {0, 1}},
         .attributes = {.axis = 0},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2},
                    .values = {0, 1}}}
         .Test();
@@ -963,23 +963,23 @@
   {
     // Test batchNormalization with 3-D input with axis = 2, epsilon = 1e-3.
     BatchNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 1, 3},
                   .values = {-1, 0, 1, 2, 3, 4}},
-        .mean = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kFloat32,
                  .dimensions = {3},
                  .values = {0, 3, 6}},
-        .variance = {.type = mojom::DataType::kFloat32,
+        .variance = {.type = OperandDataType::kFloat32,
                      .dimensions = {3},
                      .values = {1.0, 1.5, 2.0}},
-        .scale = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .scale = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                     .dimensions = {3},
                                     .values = {1.0, 1.5, 2.0}},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {3},
                                    .values = {0, 1, 2}},
         .attributes = {.axis = 2, .epsilon = 1e-3},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 1, 3},
                    .values =
                        {
@@ -996,20 +996,20 @@
     // Test batchNormalization with 1-D input with axis = 0 when scale operand
     // is missing.
     BatchNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2},
                   .values = {-1, 1}},
-        .mean = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kFloat32,
                  .dimensions = {2},
                  .values = {-1, 1}},
-        .variance = {.type = mojom::DataType::kFloat32,
+        .variance = {.type = OperandDataType::kFloat32,
                      .dimensions = {2},
                      .values = {1.0, 1.5}},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {2},
                                    .values = {0, 1}},
         .attributes = {.axis = 0},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2},
                    .values = {0, 1}}}
         .Test();
@@ -1018,20 +1018,20 @@
     // Test batchNormalization with 1-D input with axis = 0 when bias operand is
     // missing.
     BatchNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2},
                   .values = {-1, 1}},
-        .mean = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kFloat32,
                  .dimensions = {2},
                  .values = {-1, 1}},
-        .variance = {.type = mojom::DataType::kFloat32,
+        .variance = {.type = OperandDataType::kFloat32,
                      .dimensions = {2},
                      .values = {1.0, 1.5}},
-        .scale = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .scale = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                     .dimensions = {2},
                                     .values = {1.0, 1.5}},
         .attributes = {.axis = 0},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2},
                    .values = {0, 0}}}
         .Test();
@@ -1040,17 +1040,17 @@
     // Test batchNormalization with 1-D input with axis = 0 and float16 data
     // type when scale and bias operands are both missing.
     BatchNormalizationTester<float16>{
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {2},
                   .values = Float16FromFloat32({-1, 1})},
-        .mean = {.type = mojom::DataType::kFloat16,
+        .mean = {.type = OperandDataType::kFloat16,
                  .dimensions = {2},
                  .values = Float16FromFloat32({-1, 1})},
-        .variance = {.type = mojom::DataType::kFloat16,
+        .variance = {.type = OperandDataType::kFloat16,
                      .dimensions = {2},
                      .values = Float16FromFloat32({1.0, 1.5})},
         .attributes = {.axis = 0},
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {2},
                    .values = Float16FromFloat32({0, 0})}}
         .Test();
@@ -1156,17 +1156,17 @@
   {
     Conv2dTester<float>{
         .type = mojom::Conv2d::Kind::kDirect,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 3, 3},
                   .values = {0, 1, 2, 3, 4, 5, 6, 7, 8}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 1, 1},
                    .values = {1}},
         .attributes = {.bias =
-                           OperandInfo<float>{.type = mojom::DataType::kFloat32,
+                           OperandInfo<float>{.type = OperandDataType::kFloat32,
                                               .dimensions = {1},
                                               .values = {-5}}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3},
                    .values = {-0.7946096424007316, -0.7853474888890126,
                               -0.7601703453057089, -0.6917317734107099,
@@ -1179,18 +1179,18 @@
   {
     Conv2dTester<float>{
         .type = mojom::Conv2d::Kind::kDirect,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 4, 4},
                   .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
                              15}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3},
                    .values = std::vector<float>(9, 1)},
         .attributes = {.bias =
-                           OperandInfo<float>{.type = mojom::DataType::kFloat32,
+                           OperandInfo<float>{.type = OperandDataType::kFloat32,
                                               .dimensions = {1},
                                               .values = {-60}}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 2, 2},
                    .values = {-0.3, -0.12, 21, 30}}}
         .TestFusingStandaloneActivation(
@@ -1202,19 +1202,19 @@
   {
     Conv2dTester<float>{
         .type = mojom::Conv2d::Kind::kDirect,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 5, 5},
                   .values = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12,
                              13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3},
                    .values = std::vector<float>(9, 1)},
         .attributes = {.padding = {1, 1, 1, 1},
                        .bias =
-                           OperandInfo<float>{.type = mojom::DataType::kFloat32,
+                           OperandInfo<float>{.type = OperandDataType::kFloat32,
                                               .dimensions = {1},
                                               .values = {1}}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 5, 5},
                    .values = {1.13, 1.22, 1.28, 1.34, 1.25, 1.34, 1.55,
                               1.64, 1.73, 1.52, 1.64, 2,    2.09, 2.18,
@@ -1229,19 +1229,19 @@
   {
     Conv2dTester<float>{
         .type = mojom::Conv2d::Kind::kDirect,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 5, 5},
                   .values = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12,
                              13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3},
                    .values = std::vector<float>(9, 1)},
         .attributes = {.padding = {1, 1, 1, 1},
                        .bias =
-                           OperandInfo<float>{.type = mojom::DataType::kFloat32,
+                           OperandInfo<float>{.type = OperandDataType::kFloat32,
                                               .dimensions = {1},
                                               .values = {1}}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 5, 5},
                    .values = {0,    0,    0, 0,    0,    0,    0, 0,    0,
                               0,    0,    0, 0.09, 0.18, 0,    0, 0.45, 0.54,
@@ -1255,7 +1255,7 @@
   {
     Conv2dTester<float>{
         .type = mojom::Conv2d::Kind::kDirect,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 1, 3, 3},
                   .values = {0.7529087201709872, 0.7520291960017611,
                              0.594952773514815, 0.21631854011984264,
@@ -1266,7 +1266,7 @@
                              0.22727376737331384, 0.5414123970044269,
                              0.0844534212564596, 0.6765284772046276,
                              0.619325655574763, 0.39292160755260475}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {3, 1, 2, 2},
                    .values = {0.14543837927656278, 0.9671129790291346,
                               0.10836050336762582, 0.320230810822804,
@@ -1274,7 +1274,7 @@
                               0.0813970738017622, 0.5303338853508432,
                               0.30721364807734, 0.4324123448833208,
                               0.9849002194630809, 0.4281076188358701}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 3, 2, 2},
                    .values = {0.7077627182006836, 0.6772933602333069,
                               0.5719422101974487, 0.5999819040298462,
@@ -1295,13 +1295,13 @@
   // softplus activation.
   {
     Conv2dTester<float>{.type = mojom::Conv2d::Kind::kDirect,
-                        .input = {.type = mojom::DataType::kFloat32,
+                        .input = {.type = OperandDataType::kFloat32,
                                   .dimensions = {1, 1, 2, 2},
                                   .values = {40, 48, 56, 64}},
-                        .filter = {.type = mojom::DataType::kFloat32,
+                        .filter = {.type = OperandDataType::kFloat32,
                                    .dimensions = {1, 1, 1, 1},
                                    .values = {1}},
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {1, 1, 2, 2},
                                    .values = {40, 48, 56, 64}}}
         .TestFusingStandaloneActivation(
@@ -1311,13 +1311,13 @@
   // activation.
   {
     Conv2dTester<float>{.type = mojom::Conv2d::Kind::kDirect,
-                        .input = {.type = mojom::DataType::kFloat32,
+                        .input = {.type = OperandDataType::kFloat32,
                                   .dimensions = {1, 1, 3, 3},
                                   .values = {-3, -2, -1, -4, 0, 2, 1, 3, 4}},
-                        .filter = {.type = mojom::DataType::kFloat32,
+                        .filter = {.type = OperandDataType::kFloat32,
                                    .dimensions = {1, 1, 2, 2},
                                    .values = std::vector<float>(4, 1)},
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {1, 1, 2, 2},
                                    .values = {-0.9, -0.5, 0, 0.9}}}
         .TestFusingStandaloneActivation(
@@ -1327,15 +1327,15 @@
   {
     Conv2dTester<float>{
         .type = mojom::Conv2d::Kind::kDirect,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 5, 5},
                   .values = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12,
                              13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3},
                    .values = std::vector<float>(9, 0.05)},
         .attributes = {.padding = {1, 1, 1, 1}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 5, 5},
                    .values = {0.5370495669980353, 0.7818063576087741,
                               0.874053287886007,  0.9288576214547277,
@@ -1362,19 +1362,19 @@
   {
     Conv2dTester<float>{
         .type = mojom::Conv2d::Kind::kDirect,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 5, 5},
                   .values = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12,
                              13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3},
                    .values = std::vector<float>(9, 1)},
         .attributes = {.padding = {1, 1, 1, 1},
                        .bias =
-                           OperandInfo<float>{.type = mojom::DataType::kFloat32,
+                           OperandInfo<float>{.type = OperandDataType::kFloat32,
                                               .dimensions = {1},
                                               .values = {1}}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 5, 5},
                    .values = {13,  22,  28,  34,  25,  34,  55, 64,  73,
                               52,  64,  100, 109, 118, 82,  94, 145, 154,
@@ -1386,21 +1386,21 @@
   {
     Conv2dTester<float16>{
         .type = mojom::Conv2d::Kind::kDirect,
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 1, 5, 5},
                   .values = Float16FromFloat32(
                       {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12,
                        13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24})},
-        .filter = {.type = mojom::DataType::kFloat16,
+        .filter = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 1, 3, 3},
                    .values = Float16FromFloat32(std::vector<float>(9, 1))},
         .attributes = {.padding = {1, 1, 1, 1},
                        .bias =
                            OperandInfo<float16>{
-                               .type = mojom::DataType::kFloat16,
+                               .type = OperandDataType::kFloat16,
                                .dimensions = {1},
                                .values = Float16FromFloat32({1})}},
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 1, 5, 5},
                    .values = {13,  22,  28,  34,  25,  34,  55, 64,  73,
                               52,  64,  100, 109, 118, 82,  94, 145, 154,
@@ -1412,15 +1412,15 @@
   {
     Conv2dTester<float>{
         .type = mojom::Conv2d::Kind::kDirect,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 5, 5},
                   .values = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12,
                              13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3},
                    .values = std::vector<float>(9, 1)},
         .attributes = {.padding = {1, 1, 1, 1}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 5, 5},
                    .values = {12,  21,  27, 33,  24,  33,  54, 63,  72,
                               51,  63,  99, 108, 117, 81,  93, 144, 153,
@@ -1436,13 +1436,13 @@
   {
     Conv2dTester<float>{
         .type = mojom::Conv2d::Kind::kTransposed,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 3, 3},
                   .values = {0, 1, 2, 3, 4, 5, 6, 7, 8}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3},
                    .values = std::vector<float>(18, 1)},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 5, 5},
                    .values = {0., 1.,  3.,  3.,  2.,  3., 8.,  15., 12., 7.,
                               9., 21., 36., 27., 15., 9., 20., 33., 24., 13.,
@@ -1454,14 +1454,14 @@
   // Test convTranspose2d with padding = {1, 1, 1, 1}.
   {
     Conv2dTester<float>{.type = mojom::Conv2d::Kind::kTransposed,
-                        .input = {.type = mojom::DataType::kFloat32,
+                        .input = {.type = OperandDataType::kFloat32,
                                   .dimensions = {1, 1, 2, 2},
                                   .values = {0, 1, 2, 3}},
-                        .filter = {.type = mojom::DataType::kFloat32,
+                        .filter = {.type = OperandDataType::kFloat32,
                                    .dimensions = {1, 1, 2, 2},
                                    .values = {0, 1, 2, 3}},
                         .attributes = {.padding = {1, 1, 1, 1}},
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {1, 1, 1, 1},
                                    .values = {4.}}}
         .Test();
@@ -1470,14 +1470,14 @@
   {
     Conv2dTester<float>{
         .type = mojom::Conv2d::Kind::kTransposed,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 2, 2},
                   .values = {2, 4, 0, 1, 2, 4, 0, 1}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 1, 2, 2},
                    .values = {3, 1, 1, 5, 3, 1, 1, 5}},
         .attributes = {.groups = 2},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3},
                    .values = {6., 14., 4., 2., 17., 21., 0., 1., 5., 6., 14.,
                               4., 2., 17., 21., 0., 1., 5.}}}
@@ -1487,14 +1487,14 @@
   {
     Conv2dTester<float>{
         .type = mojom::Conv2d::Kind::kTransposed,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 3, 3},
                   .values = {0, 1, 2, 3, 4, 5, 6, 7, 8}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3},
                    .values = std::vector<float>(18, 1)},
         .attributes = {.strides = {3, 2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 9, 7},
                    .values = {0.,  0.,  1., 1.,  3.,  2., 2.,  0.,  0.,  1.,
                               1.,  3.,  2., 2.,  0.,  0., 1.,  1.,  3.,  2.,
@@ -1516,14 +1516,14 @@
   {
     Conv2dTester<float>{
         .type = mojom::Conv2d::Kind::kTransposed,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 3, 3},
                   .values = {0, 1, 2, 3, 4, 5, 6, 7, 8}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3},
                    .values = std::vector<float>(18, 1)},
         .attributes = {.strides = {3, 2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 10, 8},
                    .values = {0.,  0., 1.,  1.,  3., 2.,  2.,  0., 0.,  0.,  1.,
                               1.,  3., 2.,  2.,  0., 0.,  0.,  1., 1.,  3.,  2.,
@@ -1546,17 +1546,17 @@
   {
     Conv2dTester<float>{
         .type = mojom::Conv2d::Kind::kTransposed,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 2, 2},
                   .values = {0, 1, 2, 3}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 2, 2},
                    .values = {0, 1, 2, 3}},
         .attributes = {.bias =
-                           OperandInfo<float>{.type = mojom::DataType::kFloat32,
+                           OperandInfo<float>{.type = OperandDataType::kFloat32,
                                               .dimensions = {1},
                                               .values = {1}}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3},
                    .values = {1., 1., 2., 1., 5., 7., 5., 13., 10.}}}
         .Test();
@@ -1585,26 +1585,26 @@
         builder.BuildInput("rhs", rhs.dimensions, rhs.type);
     auto graph_output_type = output.type;
 #if BUILDFLAG(IS_MAC)
-    if (output.type == mojom::DataType::kUint8) {
+    if (output.type == OperandDataType::kUint8) {
       // macOS only supports FP16,FP32,DOUBLE,INT32 as outputs of graph.
       // For testing, we cast the output of the element-wise logical
       // operators to Int32 and set the graph output to Int32.
-      graph_output_type = mojom::DataType::kInt32;
+      graph_output_type = OperandDataType::kInt32;
     }
 #endif  // BUILD_FLAG(IS_MAC)
     uint64_t output_operand_id =
         builder.BuildOutput("output", output.dimensions, graph_output_type);
     uint64_t element_wise_binary_output_operand_id = output_operand_id;
 #if BUILDFLAG(IS_MAC)
-    if (output.type == mojom::DataType::kUint8) {
+    if (output.type == OperandDataType::kUint8) {
       element_wise_binary_output_operand_id = builder.BuildIntermediateOperand(
-          output.dimensions, mojom::DataType::kUint8);
+          output.dimensions, OperandDataType::kUint8);
     }
 #endif  // BUILD_FLAG(IS_MAC)
     builder.BuildElementWiseBinary(kind, lhs_operand_id, rhs_operand_id,
                                    element_wise_binary_output_operand_id);
 #if BUILDFLAG(IS_MAC)
-    if (output.type == mojom::DataType::kUint8) {
+    if (output.type == OperandDataType::kUint8) {
       builder.BuildElementWiseUnary(mojom::ElementWiseUnary::Kind::kCast,
                                     element_wise_binary_output_operand_id,
                                     output_operand_id);
@@ -1620,7 +1620,7 @@
                     named_outputs);
 
 #if BUILDFLAG(IS_MAC)
-    if (output.type == mojom::DataType::kUint8) {
+    if (output.type == OperandDataType::kUint8) {
       VerifyIsEqual(std::move(named_outputs["output"]), output.ToInt32());
       return;
     }
@@ -1668,14 +1668,14 @@
   // Test add with linear activation.
   {
     ElementWiseBinaryTester<float>{
-        .lhs = {.type = mojom::DataType::kFloat32,
+        .lhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {1, 2, 3, 4, 5, 6}},
-        .rhs = {.type = mojom::DataType::kFloat32,
+        .rhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {0, 5.1, 4, 3, 2, 0}},
         .kind = mojom::ElementWiseBinary::Kind::kAdd,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 1},
                    .values = {11, 72, 71, 71, 71, 61}}}
         .TestFusingStandaloneActivation(
@@ -1685,14 +1685,14 @@
   }
   // Test add with relu activation.
   {
-    ElementWiseBinaryTester<float>{.lhs = {.type = mojom::DataType::kFloat32,
+    ElementWiseBinaryTester<float>{.lhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {1, 2, 3, 4, 5, 6}},
-                                   .rhs = {.type = mojom::DataType::kFloat32,
+                                   .rhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {-6, 5, 4, 3, 2, -7}},
                                    .kind = mojom::ElementWiseBinary::Kind::kAdd,
-                                   .output = {.type = mojom::DataType::kFloat32,
+                                   .output = {.type = OperandDataType::kFloat32,
                                               .dimensions = {1, 2, 3, 1},
                                               .values = {0, 7, 7, 7, 7, 0}}}
         .TestFusingStandaloneActivation(
@@ -1707,28 +1707,28 @@
   // Test building and computing a graph with single operator add for 0-D
   // scalars.
   {
-    ElementWiseBinaryTester<float>{.lhs = {.type = mojom::DataType::kFloat32,
+    ElementWiseBinaryTester<float>{.lhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {},
                                            .values = {1}},
-                                   .rhs = {.type = mojom::DataType::kFloat32,
+                                   .rhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {},
                                            .values = {6}},
                                    .kind = mojom::ElementWiseBinary::Kind::kAdd,
-                                   .output = {.type = mojom::DataType::kFloat32,
+                                   .output = {.type = OperandDataType::kFloat32,
                                               .dimensions = {},
                                               .values = {7}}}
         .Test(*this);
   }
   // Test building and computing a graph with single operator add.
   {
-    ElementWiseBinaryTester<float>{.lhs = {.type = mojom::DataType::kFloat32,
+    ElementWiseBinaryTester<float>{.lhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {1, 2, 3, 4, 5, 6}},
-                                   .rhs = {.type = mojom::DataType::kFloat32,
+                                   .rhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {6, 5, 4, 3, 2, 1}},
                                    .kind = mojom::ElementWiseBinary::Kind::kAdd,
-                                   .output = {.type = mojom::DataType::kFloat32,
+                                   .output = {.type = OperandDataType::kFloat32,
                                               .dimensions = {1, 2, 3, 1},
                                               .values = {7, 7, 7, 7, 7, 7}}}
         .Test(*this);
@@ -1736,14 +1736,14 @@
   // Test building and computing a graph with single operator add using
   // broadcasting from 0-D scalar.
   {
-    ElementWiseBinaryTester<float>{.lhs = {.type = mojom::DataType::kFloat32,
+    ElementWiseBinaryTester<float>{.lhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {1, 2, 3, 4, 5, 6}},
-                                   .rhs = {.type = mojom::DataType::kFloat32,
+                                   .rhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {},
                                            .values = {1}},
                                    .kind = mojom::ElementWiseBinary::Kind::kAdd,
-                                   .output = {.type = mojom::DataType::kFloat32,
+                                   .output = {.type = OperandDataType::kFloat32,
                                               .dimensions = {1, 2, 3, 1},
                                               .values = {2, 3, 4, 5, 6, 7}}}
         .Test(*this);
@@ -1752,14 +1752,14 @@
   // broadcasting.
   {
     ElementWiseBinaryTester<float>{
-        .lhs = {.type = mojom::DataType::kFloat32,
+        .lhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {1, 2, 3, 4, 5, 6}},
-        .rhs = {.type = mojom::DataType::kFloat32,
+        .rhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 1, 1, 2},
                 .values = {1, 11}},
         .kind = mojom::ElementWiseBinary::Kind::kAdd,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 2},
                    .values = {2, 12, 3, 13, 4, 14, 5, 15, 6, 16, 7, 17}}}
         .Test(*this);
@@ -1767,14 +1767,14 @@
   // Test building and computing a graph with single operator div.
   {
     ElementWiseBinaryTester<float>{
-        .lhs = {.type = mojom::DataType::kFloat32,
+        .lhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {1, 2, 3, 4, 5, 6}},
-        .rhs = {.type = mojom::DataType::kFloat32,
+        .rhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {2, 2, 2, 2, 2, 2}},
         .kind = mojom::ElementWiseBinary::Kind::kDiv,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 1},
                    .values = {0.5, 1, 1.5, 2, 2.5, 3}}}
         .Test(*this);
@@ -1783,28 +1783,28 @@
   // broadcasting.
   {
     ElementWiseBinaryTester<float>{
-        .lhs = {.type = mojom::DataType::kFloat32,
+        .lhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 1, 1},
                 .values = {1, 2}},
-        .rhs = {.type = mojom::DataType::kFloat32,
+        .rhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 1, 3, 2},
                 .values = {2, 2, 2, 2, 2, 2}},
         .kind = mojom::ElementWiseBinary::Kind::kDiv,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 2},
                    .values = {0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 1, 1, 1, 1, 1, 1}}}
         .Test(*this);
   }
   // Test building and computing a graph with single operator max.
   {
-    ElementWiseBinaryTester<float>{.lhs = {.type = mojom::DataType::kFloat32,
+    ElementWiseBinaryTester<float>{.lhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {1, 2, 3, 4, 5, 6}},
-                                   .rhs = {.type = mojom::DataType::kFloat32,
+                                   .rhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {6, 5, 4, 3, 2, 1}},
                                    .kind = mojom::ElementWiseBinary::Kind::kMax,
-                                   .output = {.type = mojom::DataType::kFloat32,
+                                   .output = {.type = OperandDataType::kFloat32,
                                               .dimensions = {1, 2, 3, 1},
                                               .values = {6, 5, 4, 4, 5, 6}}}
         .Test(*this);
@@ -1812,28 +1812,28 @@
   // Test building and computing a graph with single operator max using
   // broadcasting.
   {
-    ElementWiseBinaryTester<float>{.lhs = {.type = mojom::DataType::kFloat32,
+    ElementWiseBinaryTester<float>{.lhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {1, 2, 3, 4, 5, 6}},
-                                   .rhs = {.type = mojom::DataType::kFloat32,
+                                   .rhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 1, 1},
                                            .values = {6, 3}},
                                    .kind = mojom::ElementWiseBinary::Kind::kMax,
-                                   .output = {.type = mojom::DataType::kFloat32,
+                                   .output = {.type = OperandDataType::kFloat32,
                                               .dimensions = {1, 2, 3, 1},
                                               .values = {6, 6, 6, 4, 5, 6}}}
         .Test(*this);
   }
   // Test building and computing a graph with single operator min.
   {
-    ElementWiseBinaryTester<float>{.lhs = {.type = mojom::DataType::kFloat32,
+    ElementWiseBinaryTester<float>{.lhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {1, 2, 3, 4, 5, 6}},
-                                   .rhs = {.type = mojom::DataType::kFloat32,
+                                   .rhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {6, 5, 4, 3, 2, 1}},
                                    .kind = mojom::ElementWiseBinary::Kind::kMin,
-                                   .output = {.type = mojom::DataType::kFloat32,
+                                   .output = {.type = OperandDataType::kFloat32,
                                               .dimensions = {1, 2, 3, 1},
                                               .values = {1, 2, 3, 3, 2, 1}}}
         .Test(*this);
@@ -1841,28 +1841,28 @@
   // Test building and computing a graph with single operator min using
   // broadcasting.
   {
-    ElementWiseBinaryTester<float>{.lhs = {.type = mojom::DataType::kFloat32,
+    ElementWiseBinaryTester<float>{.lhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 3, 1, 1},
                                            .values = {1, 2, 3}},
-                                   .rhs = {.type = mojom::DataType::kFloat32,
+                                   .rhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 1, 2, 1},
                                            .values = {2, 1}},
                                    .kind = mojom::ElementWiseBinary::Kind::kMin,
-                                   .output = {.type = mojom::DataType::kFloat32,
+                                   .output = {.type = OperandDataType::kFloat32,
                                               .dimensions = {1, 3, 2, 1},
                                               .values = {1, 1, 2, 1, 2, 1}}}
         .Test(*this);
   }
   // Test building and computing a graph with single operator mul.
   {
-    ElementWiseBinaryTester<float>{.lhs = {.type = mojom::DataType::kFloat32,
+    ElementWiseBinaryTester<float>{.lhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {1, 2, 3, 4, 5, 6}},
-                                   .rhs = {.type = mojom::DataType::kFloat32,
+                                   .rhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {6, 5, 4, 3, 2, 1}},
                                    .kind = mojom::ElementWiseBinary::Kind::kMul,
-                                   .output = {.type = mojom::DataType::kFloat32,
+                                   .output = {.type = OperandDataType::kFloat32,
                                               .dimensions = {1, 2, 3, 1},
                                               .values = {6, 10, 12, 12, 10, 6}}}
         .Test(*this);
@@ -1871,28 +1871,28 @@
   // broadcasting.
   {
     ElementWiseBinaryTester<float>{
-        .lhs = {.type = mojom::DataType::kFloat32,
+        .lhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 1, 1},
                 .values = {6, 5}},
-        .rhs = {.type = mojom::DataType::kFloat32,
+        .rhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {1, 2, 3, 4, 5, 6}},
         .kind = mojom::ElementWiseBinary::Kind::kMul,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 1},
                    .values = {6, 12, 18, 20, 25, 30}}}
         .Test(*this);
   }
   // Test building and computing a graph with single operator pow.
   {
-    ElementWiseBinaryTester<float>{.lhs = {.type = mojom::DataType::kFloat32,
+    ElementWiseBinaryTester<float>{.lhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {1, 2, 3, 4, 5, 6}},
-                                   .rhs = {.type = mojom::DataType::kFloat32,
+                                   .rhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {1, 2, 1, 1, 2, 1}},
                                    .kind = mojom::ElementWiseBinary::Kind::kPow,
-                                   .output = {.type = mojom::DataType::kFloat32,
+                                   .output = {.type = OperandDataType::kFloat32,
                                               .dimensions = {1, 2, 3, 1},
                                               .values = {1, 4, 3, 4, 25, 6}}}
         .Test(*this);
@@ -1900,28 +1900,28 @@
   // Test building and computing a graph with single operator pow using
   // broadcasting.
   {
-    ElementWiseBinaryTester<float>{.lhs = {.type = mojom::DataType::kFloat32,
+    ElementWiseBinaryTester<float>{.lhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {1, 2, 3, 4, 5, 6}},
-                                   .rhs = {.type = mojom::DataType::kFloat32,
+                                   .rhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 1, 3, 1},
                                            .values = {1, 2, 1}},
                                    .kind = mojom::ElementWiseBinary::Kind::kPow,
-                                   .output = {.type = mojom::DataType::kFloat32,
+                                   .output = {.type = OperandDataType::kFloat32,
                                               .dimensions = {1, 2, 3, 1},
                                               .values = {1, 4, 3, 4, 25, 6}}}
         .Test(*this);
   }
   // Test building and computing a graph with single operator sub.
   {
-    ElementWiseBinaryTester<float>{.lhs = {.type = mojom::DataType::kFloat32,
+    ElementWiseBinaryTester<float>{.lhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {1, 2, 3, 4, 5, 6}},
-                                   .rhs = {.type = mojom::DataType::kFloat32,
+                                   .rhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {1, 2, 1, 2, 1, 2}},
                                    .kind = mojom::ElementWiseBinary::Kind::kSub,
-                                   .output = {.type = mojom::DataType::kFloat32,
+                                   .output = {.type = OperandDataType::kFloat32,
                                               .dimensions = {1, 2, 3, 1},
                                               .values = {0, 0, 2, 2, 4, 4}}}
         .Test(*this);
@@ -1929,14 +1929,14 @@
   // Test building and computing a graph with single operator sub using
   // broadcasting.
   {
-    ElementWiseBinaryTester<float>{.lhs = {.type = mojom::DataType::kFloat32,
+    ElementWiseBinaryTester<float>{.lhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 1},
                                            .values = {1, 2, 3, 4, 5, 6}},
-                                   .rhs = {.type = mojom::DataType::kFloat32,
+                                   .rhs = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 1, 1, 1},
                                            .values = {2}},
                                    .kind = mojom::ElementWiseBinary::Kind::kSub,
-                                   .output = {.type = mojom::DataType::kFloat32,
+                                   .output = {.type = OperandDataType::kFloat32,
                                               .dimensions = {1, 2, 3, 1},
                                               .values = {-1, 0, 1, 2, 3, 4}}}
         .Test(*this);
@@ -1947,15 +1947,15 @@
   // Test building and computing a graph with single operator equal.
   {
     ElementWiseBinaryTester<float, uint8_t>{
-        .lhs = {.type = mojom::DataType::kFloat32,
+        .lhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {-1, 2, -3, 4, 5,
                            std::numeric_limits<float>::infinity()}},
-        .rhs = {.type = mojom::DataType::kFloat32,
+        .rhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {6, 5, 3, 4, 2, 1}},
         .kind = mojom::ElementWiseBinary::Kind::kEqual,
-        .output = {.type = mojom::DataType::kUint8,
+        .output = {.type = OperandDataType::kUint8,
                    .dimensions = {1, 2, 3, 1},
                    .values = {0, 0, 0, 1, 0, 0}}}
         .Test(*this);
@@ -1964,15 +1964,15 @@
   // broadcasting.
   {
     ElementWiseBinaryTester<float, uint8_t>{
-        .lhs = {.type = mojom::DataType::kFloat32,
+        .lhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {-1, 2, 3, 4, 5,
                            std::numeric_limits<float>::infinity()}},
-        .rhs = {.type = mojom::DataType::kFloat32,
+        .rhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 1, 1, 1},
                 .values = {2}},
         .kind = mojom::ElementWiseBinary::Kind::kEqual,
-        .output = {.type = mojom::DataType::kUint8,
+        .output = {.type = OperandDataType::kUint8,
                    .dimensions = {1, 2, 3, 1},
                    .values = {0, 1, 0, 0, 0, 0}}}
         .Test(*this);
@@ -1980,15 +1980,15 @@
   // Test building and computing a graph with single operator greater.
   {
     ElementWiseBinaryTester<float, uint8_t>{
-        .lhs = {.type = mojom::DataType::kFloat32,
+        .lhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {-1, -2, 3, 4, 5,
                            std::numeric_limits<float>::infinity()}},
-        .rhs = {.type = mojom::DataType::kFloat32,
+        .rhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {6, -5, 3, 4, 2, 1}},
         .kind = mojom::ElementWiseBinary::Kind::kGreater,
-        .output = {.type = mojom::DataType::kUint8,
+        .output = {.type = OperandDataType::kUint8,
                    .dimensions = {1, 2, 3, 1},
                    .values = {0, 1, 0, 0, 1, 1}}}
         .Test(*this);
@@ -1997,15 +1997,15 @@
   // broadcasting.
   {
     ElementWiseBinaryTester<float, uint8_t>{
-        .lhs = {.type = mojom::DataType::kFloat32,
+        .lhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {-1, 2, 3, 4, 5,
                            std::numeric_limits<float>::infinity()}},
-        .rhs = {.type = mojom::DataType::kFloat32,
+        .rhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 1, 1, 1},
                 .values = {2}},
         .kind = mojom::ElementWiseBinary::Kind::kGreater,
-        .output = {.type = mojom::DataType::kUint8,
+        .output = {.type = OperandDataType::kUint8,
                    .dimensions = {1, 2, 3, 1},
                    .values = {0, 0, 1, 1, 1, 1}}}
         .Test(*this);
@@ -2013,15 +2013,15 @@
   // Test building and computing graph with single operator greaterOrEqual.
   {
     ElementWiseBinaryTester<float, uint8_t>{
-        .lhs = {.type = mojom::DataType::kFloat32,
+        .lhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {-1, 2, -3, 4, 5,
                            std::numeric_limits<float>::infinity()}},
-        .rhs = {.type = mojom::DataType::kFloat32,
+        .rhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {6, 5, 3, 4, 2, 1}},
         .kind = mojom::ElementWiseBinary::Kind::kGreaterOrEqual,
-        .output = {.type = mojom::DataType::kUint8,
+        .output = {.type = OperandDataType::kUint8,
                    .dimensions = {1, 2, 3, 1},
                    .values = {0, 0, 0, 1, 1, 1}}}
         .Test(*this);
@@ -2030,15 +2030,15 @@
   // greaterOrEqual using broadcasting.
   {
     ElementWiseBinaryTester<float, uint8_t>{
-        .lhs = {.type = mojom::DataType::kFloat32,
+        .lhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {-1, 2, -3, 4, 5,
                            std::numeric_limits<float>::infinity()}},
-        .rhs = {.type = mojom::DataType::kFloat32,
+        .rhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 1, 1, 1},
                 .values = {2}},
         .kind = mojom::ElementWiseBinary::Kind::kGreaterOrEqual,
-        .output = {.type = mojom::DataType::kUint8,
+        .output = {.type = OperandDataType::kUint8,
                    .dimensions = {1, 2, 3, 1},
                    .values = {0, 1, 0, 1, 1, 1}}}
         .Test(*this);
@@ -2046,15 +2046,15 @@
   // Test building and computing a graph with single operator lesser.
   {
     ElementWiseBinaryTester<float, uint8_t>{
-        .lhs = {.type = mojom::DataType::kFloat32,
+        .lhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {-1, 2, 3, -4, 5,
                            std::numeric_limits<float>::infinity()}},
-        .rhs = {.type = mojom::DataType::kFloat32,
+        .rhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {6, 5, 3, 3, 2, 1}},
         .kind = mojom::ElementWiseBinary::Kind::kLesser,
-        .output = {.type = mojom::DataType::kUint8,
+        .output = {.type = OperandDataType::kUint8,
                    .dimensions = {1, 2, 3, 1},
                    .values = {1, 1, 0, 1, 0, 0}}}
         .Test(*this);
@@ -2063,15 +2063,15 @@
   // broadcasting.
   {
     ElementWiseBinaryTester<float, uint8_t>{
-        .lhs = {.type = mojom::DataType::kFloat32,
+        .lhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {-1, 2, -3, 4, 5,
                            std::numeric_limits<float>::infinity()}},
-        .rhs = {.type = mojom::DataType::kFloat32,
+        .rhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 1, 1, 1},
                 .values = {2}},
         .kind = mojom::ElementWiseBinary::Kind::kLesser,
-        .output = {.type = mojom::DataType::kUint8,
+        .output = {.type = OperandDataType::kUint8,
                    .dimensions = {1, 2, 3, 1},
                    .values = {1, 0, 1, 0, 0, 0}}}
         .Test(*this);
@@ -2079,15 +2079,15 @@
   // Test building and computing a graph with single operator lesserOrEqual.
   {
     ElementWiseBinaryTester<float, uint8_t>{
-        .lhs = {.type = mojom::DataType::kFloat32,
+        .lhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {-1, 2, 3, 4, 5,
                            std::numeric_limits<float>::infinity()}},
-        .rhs = {.type = mojom::DataType::kFloat32,
+        .rhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {6, 5, -3, 4, 2, 1}},
         .kind = mojom::ElementWiseBinary::Kind::kLesserOrEqual,
-        .output = {.type = mojom::DataType::kUint8,
+        .output = {.type = OperandDataType::kUint8,
                    .dimensions = {1, 2, 3, 1},
                    .values = {1, 1, 0, 1, 0, 0}}}
         .Test(*this);
@@ -2096,15 +2096,15 @@
   // using broadcasting.
   {
     ElementWiseBinaryTester<float, uint8_t>{
-        .lhs = {.type = mojom::DataType::kFloat32,
+        .lhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 1},
                 .values = {-1, 2, -2, -4, 5,
                            std::numeric_limits<float>::infinity()}},
-        .rhs = {.type = mojom::DataType::kFloat32,
+        .rhs = {.type = OperandDataType::kFloat32,
                 .dimensions = {1, 1, 1, 1},
                 .values = {2}},
         .kind = mojom::ElementWiseBinary::Kind::kLesserOrEqual,
-        .output = {.type = mojom::DataType::kUint8,
+        .output = {.type = OperandDataType::kUint8,
                    .dimensions = {1, 2, 3, 1},
                    .values = {1, 1, 1, 1, 0, 0}}}
         .Test(*this);
@@ -2143,22 +2143,22 @@
 TEST_F(WebNNGraphImplBackendTest,
        BuildAndComputeSingleOperatorElementWiseUnary) {
   OperandInfo<float_t> test_operand_info_float32_scalar{
-      .type = mojom::DataType::kFloat32, .dimensions = {}, .values = {2}};
+      .type = OperandDataType::kFloat32, .dimensions = {}, .values = {2}};
   OperandInfo<float_t> test_operand_info_float32{
-      .type = mojom::DataType::kFloat32,
+      .type = OperandDataType::kFloat32,
       .dimensions = {1, 2, 3, 1},
       .values = {0, 2, 0, 4, 5, 120}};
   OperandInfo<float16> test_operand_info_float16{
-      .type = mojom::DataType::kFloat16,
+      .type = OperandDataType::kFloat16,
       .dimensions = {1, 2, 3, 1},
       .values = {0, 2, 0, 4, 5, 120}};
-  OperandInfo<int32_t> test_operand_info_int32{.type = mojom::DataType::kInt32,
+  OperandInfo<int32_t> test_operand_info_int32{.type = OperandDataType::kInt32,
                                                .dimensions = {1, 2, 3, 1},
                                                .values = {0, 2, 0, 4, 5, 120}};
-  OperandInfo<int8_t> test_operand_info_int8{.type = mojom::DataType::kInt8,
+  OperandInfo<int8_t> test_operand_info_int8{.type = OperandDataType::kInt8,
                                              .dimensions = {1, 2, 3, 1},
                                              .values = {0, 2, 0, 4, 5, 120}};
-  OperandInfo<uint8_t> test_operand_info_uint8{.type = mojom::DataType::kUint8,
+  OperandInfo<uint8_t> test_operand_info_uint8{.type = OperandDataType::kUint8,
                                                .dimensions = {1, 2, 3, 1},
                                                .values = {0, 2, 0, 4, 5, 120}};
 
@@ -2167,11 +2167,11 @@
 #if !BUILDFLAG(WEBNN_USE_TFLITE) && !BUILDFLAG(IS_MAC)
   {
     ElementWiseUnaryTester<uint8_t>{
-        .input = {.type = mojom::DataType::kUint8,
+        .input = {.type = OperandDataType::kUint8,
                   .dimensions = {1, 2, 3, 1},
                   .values = {0, 2, 0, 4, 5, 255}},
         .kind = mojom::ElementWiseUnary::Kind::kLogicalNot,
-        .output = {.type = mojom::DataType::kUint8,
+        .output = {.type = OperandDataType::kUint8,
                    .dimensions = {1, 2, 3, 1},
                    .values = {1, 0, 1, 0, 0, 0}}}
         .Test(*this);
@@ -2224,21 +2224,21 @@
 
   {
     // Test Sqrt with 0-D scalar input.
-    ElementWiseUnaryTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ElementWiseUnaryTester<float>{.input = {.type = OperandDataType::kFloat32,
                                             .dimensions = {},
                                             .values = {4}},
                                   .kind = mojom::ElementWiseUnary::Kind::kSqrt,
-                                  .output = {.type = mojom::DataType::kFloat32,
+                                  .output = {.type = OperandDataType::kFloat32,
                                              .dimensions = {},
                                              .values = {2}}}
         .Test(*this);
   }
   {
-    ElementWiseUnaryTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ElementWiseUnaryTester<float>{.input = {.type = OperandDataType::kFloat32,
                                             .dimensions = {1, 2, 3, 1},
                                             .values = {0, 4, 25, 16, 64, 49}},
                                   .kind = mojom::ElementWiseUnary::Kind::kSqrt,
-                                  .output = {.type = mojom::DataType::kFloat32,
+                                  .output = {.type = OperandDataType::kFloat32,
                                              .dimensions = {1, 2, 3, 1},
                                              .values = {0, 2, 5, 4, 8, 7}}}
         .Test(*this);
@@ -2249,11 +2249,11 @@
 #if !BUILDFLAG(WEBNN_USE_TFLITE)
   {
     ElementWiseUnaryTester<float16>{
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 2, 3, 1},
                   .values = Float16FromFloat32({0, 4, 25, 16, 64, 49})},
         .kind = mojom::ElementWiseUnary::Kind::kSqrt,
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 2, 3, 1},
                    .values = Float16FromFloat32({0, 2, 5, 4, 8, 7})}}
         .Test(*this);
@@ -2261,11 +2261,11 @@
 #endif  // !BUILDFLAG(WEBNN_USE_TFLITE)
 #if !BUILDFLAG(WEBNN_USE_TFLITE)
   {
-    ElementWiseUnaryTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ElementWiseUnaryTester<float>{.input = {.type = OperandDataType::kFloat32,
                                             .dimensions = {1, 2, 3, 1},
                                             .values = {0, 4, 0, 16, 64, -5}},
                                   .kind = mojom::ElementWiseUnary::Kind::kErf,
-                                  .output = {.type = mojom::DataType::kFloat32,
+                                  .output = {.type = OperandDataType::kFloat32,
                                              .dimensions = {1, 2, 3, 1},
                                              .values = {0, 1, 0, 1, 1, -1}}}
         .Test(*this);
@@ -2274,11 +2274,11 @@
 #if !BUILDFLAG(WEBNN_USE_TFLITE)
   {
     ElementWiseUnaryTester<float16>{
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 2, 3, 1},
                   .values = Float16FromFloat32({0, 4, 0, 16, 64, -5})},
         .kind = mojom::ElementWiseUnary::Kind::kErf,
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 2, 3, 1},
                    .values = Float16FromFloat32({0, 1, 0, 1, 1, -1})}}
         .Test(*this);
@@ -2287,11 +2287,11 @@
 #if !BUILDFLAG(WEBNN_USE_TFLITE)
   {
     ElementWiseUnaryTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 1},
                   .values = {1, 4, 2, 16, 64, 0}},
         .kind = mojom::ElementWiseUnary::Kind::kReciprocal,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 1},
                    .values = {1, 0.25, 0.5, 0.0625, 0.015625,
                               std::numeric_limits<float>::infinity()}}}
@@ -2301,11 +2301,11 @@
 #if !BUILDFLAG(WEBNN_USE_TFLITE)
   {
     ElementWiseUnaryTester<float16>{
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 2, 3, 1},
                   .values = Float16FromFloat32({1, 4, 2, 16, 64, 0})},
         .kind = mojom::ElementWiseUnary::Kind::kReciprocal,
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 2, 3, 1},
                    .values = Float16FromFloat32(
                        {1, 0.25, 0.5, 0.0625, 0.015625,
@@ -2314,44 +2314,44 @@
   }
 #endif  // !BUILDFLAG(WEBNN_USE_TFLITE)
   {
-    ElementWiseUnaryTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ElementWiseUnaryTester<float>{.input = {.type = OperandDataType::kFloat32,
                                             .dimensions = {1, 2, 3, 1},
                                             .values = {-1, 4, -2, 16, -64, 0}},
                                   .kind = mojom::ElementWiseUnary::Kind::kAbs,
-                                  .output = {.type = mojom::DataType::kFloat32,
+                                  .output = {.type = OperandDataType::kFloat32,
                                              .dimensions = {1, 2, 3, 1},
                                              .values = {1, 4, 2, 16, 64, 0}}}
         .Test(*this);
   }
   {
     ElementWiseUnaryTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 3},
                   .values = {-1.1, 0, 1.1, -2.2, 0, 2.2}},
         .kind = mojom::ElementWiseUnary::Kind::kCeil,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 3},
                    .values = {-1, 0, 2, -2, 0, 3}}}
         .Test(*this);
   }
   {
     ElementWiseUnaryTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 2},
                   .values = {1, -2, 3, -4}},
         .kind = mojom::ElementWiseUnary::Kind::kCos,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2},
                    .values = {cos(1.f), cos(-2.f), cos(3.f), cos(-4.f)}}}
         .Test(*this);
   }
   {
     ElementWiseUnaryTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 2},
                   .values = {1, -2, 3, -4}},
         .kind = mojom::ElementWiseUnary::Kind::kExp,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2},
                    .values = {exp(1.f), exp(-2.f), exp(3.f), exp(-4.f)}}}
         .Test(*this);
@@ -2362,11 +2362,11 @@
 #if !BUILDFLAG(WEBNN_USE_TFLITE)
   {
     ElementWiseUnaryTester<float16>{
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 2, 3, 1},
                   .values = Float16FromFloat32({-1.1, 0, 1.1, -2.2, 0, 2.2})},
         .kind = mojom::ElementWiseUnary::Kind::kFloor,
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 2, 3, 1},
                    .values = Float16FromFloat32({-2, 0, 1, -3, 0, 2})}}
         .Test(*this);
@@ -2374,33 +2374,33 @@
 #endif  // !BUILDFLAG(WEBNN_USE_TFLITE)
   {
     ElementWiseUnaryTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {3},
                   .values = {0, 3, 10}},
         .kind = mojom::ElementWiseUnary::Kind::kLog,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {3},
                    .values = {log(0.f), log(3.f), log(10.f)}}}
         .Test(*this);
   }
   {
     ElementWiseUnaryTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 1},
                   .values = {-1, 0, 1.1, -2.2, 0, 2}},
         .kind = mojom::ElementWiseUnary::Kind::kNeg,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 1},
                    .values = {1, 0, -1.1, 2.2, 0, -2}}}
         .Test(*this);
   }
   {
     ElementWiseUnaryTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 2},
                   .values = {1, -2, 3, -4}},
         .kind = mojom::ElementWiseUnary::Kind::kSin,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2},
                    .values = {sin(1.f), sin(-2.f), sin(3.f), sin(-4.f)}}}
         .Test(*this);
@@ -2411,11 +2411,11 @@
 #if !BUILDFLAG(WEBNN_USE_TFLITE)
   {
     ElementWiseUnaryTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 2},
                   .values = {1, -2, 3, -4}},
         .kind = mojom::ElementWiseUnary::Kind::kTan,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2},
                    .values = {tan(1.f), tan(-2.f), tan(3.f), tan(-4.f)}}}
         .Test(*this);
@@ -2450,12 +2450,12 @@
   {
     // Test building expand 0-D scalar to 3-D tensor.
     ExpandTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {},
                   .values = {6}},
         .output =
             {
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {2, 2, 4},
                 // [[[ 6,  6,  6,  6],
                 //   [ 6,  6,  6,  6]],
@@ -2470,7 +2470,7 @@
     ExpandTester<float>{
         .input =
             {
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {3, 4},
                 // [[ 1,  2,  3,  4],
                 //  [ 5,  6,  7,  8],
@@ -2479,7 +2479,7 @@
             },
         .output =
             {
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {3, 4},
                 // [[ 1,  2,  3,  4],
                 //  [ 5,  6,  7,  8],
@@ -2493,7 +2493,7 @@
     ExpandTester<float>{
         .input =
             {
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {2, 1, 5},
                 // [[[1, 2, 3, 4, 5]],
                 //  [[6, 7, 8, 9, 10]]] with shape (2, 1, 5)
@@ -2501,7 +2501,7 @@
             },
         .output =
             {
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {2, 3, 5},
                 // [[[ 1, 2, 3, 4, 5],
                 //   [ 1, 2, 3, 4, 5],
@@ -2520,7 +2520,7 @@
     ExpandTester<float>{
         .input =
             {
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {2, 6},
                 // [[[1, 2, 3, 4,  5,  6]],
                 //  [[7, 8, 9, 10, 11, 12]]] with shape (2, 6)
@@ -2528,7 +2528,7 @@
             },
         .output =
             {
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {3, 2, 6},
                 // [[[ 1, 2, 3, 4,  5,  6],
                 //   [ 7, 8, 9, 10, 11, 12]],
@@ -2546,24 +2546,24 @@
 
 TEST_F(WebNNGraphImplBackendTest, BuildAndComputeSingleOperatorCast) {
   OperandInfo<float_t> test_operand_info_float32{
-      .type = mojom::DataType::kFloat32,
+      .type = OperandDataType::kFloat32,
       .dimensions = {1, 2, 3, 1},
       .values = {1, 0, 0, 0, 0, 0}};
   OperandInfo<float16> test_operand_info_float16{
-      .type = mojom::DataType::kFloat16,
+      .type = OperandDataType::kFloat16,
       .dimensions = {1, 2, 3, 1},
       .values = Float16FromFloat32({1.0f, 0, 0, 0, 0, 0})};
-  OperandInfo<int32_t> test_operand_info_int32{.type = mojom::DataType::kInt32,
+  OperandInfo<int32_t> test_operand_info_int32{.type = OperandDataType::kInt32,
                                                .dimensions = {1, 2, 3, 1},
                                                .values = {1, 0, 0, 0, 0, 0}};
   OperandInfo<uint32_t> test_operand_info_uint32{
-      .type = mojom::DataType::kUint32,
+      .type = OperandDataType::kUint32,
       .dimensions = {1, 2, 3, 1},
       .values = {1, 0, 0, 0, 0, 0}};
-  OperandInfo<int8_t> test_operand_info_int8{.type = mojom::DataType::kInt8,
+  OperandInfo<int8_t> test_operand_info_int8{.type = OperandDataType::kInt8,
                                              .dimensions = {1, 2, 3, 1},
                                              .values = {1, 0, 0, 0, 0, 0}};
-  OperandInfo<uint8_t> test_operand_info_uint8{.type = mojom::DataType::kUint8,
+  OperandInfo<uint8_t> test_operand_info_uint8{.type = OperandDataType::kUint8,
                                                .dimensions = {1, 2, 3, 1},
                                                .values = {1, 0, 0, 0, 0, 0}};
 
@@ -2877,7 +2877,7 @@
   {
     // Test average pool2d with nchw layout, float 32 data type.
     Pool2dTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3},
                   .values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
                              16, 17, 18}},
@@ -2887,7 +2887,7 @@
                        .dilations = {1, 1},
                        .layout = mojom::InputOperandLayout::kChannelsFirst},
         .kind = mojom::Pool2d::Kind::kAveragePool2d,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 2, 2},
                    .values = {3, 4, 6, 7, 12, 13, 15, 16}}}
         .Test();
@@ -2895,7 +2895,7 @@
   {
     // Test average pool2d with nchw layout, float 16 data type.
     Pool2dTester<float16>{
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 2, 3, 3},
                   .values =
                       Float16FromFloat32({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
@@ -2906,7 +2906,7 @@
                        .dilations = {1, 1},
                        .layout = mojom::InputOperandLayout::kChannelsFirst},
         .kind = mojom::Pool2d::Kind::kAveragePool2d,
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 2, 2, 2},
                    .values = {3, 4, 6, 7, 12, 13, 15, 16}}}
         .Test();
@@ -2914,7 +2914,7 @@
   {
     // Test average pool2d with nhwc layout, float 32 data type.
     Pool2dTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 3, 3, 2},
                   .values = {1, 10, 2, 11, 3, 12, 4, 13, 5, 14, 6, 15, 7, 16, 8,
                              17, 9, 18}},
@@ -2924,7 +2924,7 @@
                        .dilations = {1, 1},
                        .layout = mojom::InputOperandLayout::kChannelsLast},
         .kind = mojom::Pool2d::Kind::kAveragePool2d,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 2, 2},
                    .values = {3, 12, 4, 13, 6, 15, 7, 16}}}
         .Test();
@@ -2932,7 +2932,7 @@
   {
     // Test average pool2d with nhwc layout, float 16 data type.
     Pool2dTester<float16>{
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 3, 3, 2},
                   .values =
                       Float16FromFloat32({1, 10, 2, 11, 3, 12, 4, 13, 5, 14, 6,
@@ -2943,7 +2943,7 @@
                        .dilations = {1, 1},
                        .layout = mojom::InputOperandLayout::kChannelsLast},
         .kind = mojom::Pool2d::Kind::kAveragePool2d,
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 2, 2, 2},
                    .values = {3, 12, 4, 13, 6, 15, 7, 16}}}
         .Test();
@@ -2955,7 +2955,7 @@
   {
     // Test l2Pool2d with nchw layout, float 32 data type.
     Pool2dTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 4, 2, 2},
                   .values = {1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}},
         .attributes = {.window_dimensions = {2, 2},
@@ -2964,7 +2964,7 @@
                        .dilations = {1, 1},
                        .layout = mojom::InputOperandLayout::kChannelsFirst},
         .kind = mojom::Pool2d::Kind::kL2Pool2d,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 4, 1, 1},
                    .values = {2, 4, 6, 8}}}
         .Test();
@@ -2972,7 +2972,7 @@
   {
     // Test l2Pool2d with nchw layout, float 16 data type.
     Pool2dTester<float16>{
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 4, 2, 2},
                   .values = Float16FromFloat32(
                       {1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4})},
@@ -2982,7 +2982,7 @@
                        .dilations = {1, 1},
                        .layout = mojom::InputOperandLayout::kChannelsFirst},
         .kind = mojom::Pool2d::Kind::kL2Pool2d,
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 4, 1, 1},
                    .values = {2, 4, 6, 8}}}
         .Test();
@@ -2990,7 +2990,7 @@
   {
     // Test l2Pool2d with nhwc layout, float 32 data type.
     Pool2dTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 2, 4},
                   .values = {1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4}},
         .attributes = {.window_dimensions = {2, 2},
@@ -2999,7 +2999,7 @@
                        .dilations = {1, 1},
                        .layout = mojom::InputOperandLayout::kChannelsLast},
         .kind = mojom::Pool2d::Kind::kL2Pool2d,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 1, 4},
                    .values = {2, 4, 6, 8}}}
         .Test();
@@ -3007,7 +3007,7 @@
   {
     // Test l2Pool2d with nhwc layout, float 16 data type.
     Pool2dTester<float16>{
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 2, 2, 4},
                   .values = Float16FromFloat32(
                       {1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4})},
@@ -3017,7 +3017,7 @@
                        .dilations = {1, 1},
                        .layout = mojom::InputOperandLayout::kChannelsLast},
         .kind = mojom::Pool2d::Kind::kL2Pool2d,
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 1, 1, 4},
                    .values = {2, 4, 6, 8}}}
         .Test();
@@ -3031,7 +3031,7 @@
     // Test max pool2d with nchw layout, strides=1, padding=0, dilations={1,1}
     // and floor rounding.
     Pool2dTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3},
                   .values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
                              16, 17, 18}},
@@ -3041,7 +3041,7 @@
                        .dilations = {1, 1},
                        .layout = mojom::InputOperandLayout::kChannelsFirst},
         .kind = mojom::Pool2d::Kind::kMaxPool2d,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 2, 2},
                    .values = {5, 6, 8, 9, 14, 15, 17, 18}}}
         .Test();
@@ -3050,7 +3050,7 @@
     // Test max pool2d with nchw layout, strides=1, padding=0, dilations={2,2}
     // and floor rounding.
     Pool2dTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 4, 4},
                   .values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
                              16}},
@@ -3060,7 +3060,7 @@
                        .dilations = {2, 2},
                        .layout = mojom::InputOperandLayout::kChannelsFirst},
         .kind = mojom::Pool2d::Kind::kMaxPool2d,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 2, 2},
                    .values = {11, 12, 15, 16}}}
         .Test();
@@ -3101,16 +3101,16 @@
   {
     // Test prelu when the input and slope have the same dimensions.
     PreluTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3},
                   .values = {-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, 11, 12,
                              13, 14, 15, 16, 17, 18}},
-        .slope = {.type = mojom::DataType::kFloat32,
+        .slope = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3},
                   .values = {0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08,
                              0.09, 0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16,
                              0.17, 0.18}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3},
                    .values = {-0.01, -0.04, -0.09, -0.16, -0.25, -0.36, -0.49,
                               -0.64, -0.81, -1, 11, 12, 13, 14, 15, 16, 17,
@@ -3120,14 +3120,14 @@
   {
     // Test prelu with broadcastable slope.
     PreluTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3},
                   .values = {-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, 11, 12,
                              13, 14, 15, 16, 17, 18}},
-        .slope = {.type = mojom::DataType::kFloat32,
+        .slope = {.type = OperandDataType::kFloat32,
                   .dimensions = {1},
                   .values = {0.01}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3},
                    .values = {-0.01, -0.02, -0.03, -0.04, -0.05, -0.06, -0.07,
                               -0.08, -0.09, -0.1, 11, 12, 13, 14, 15, 16, 17,
@@ -3203,13 +3203,13 @@
 TEST_F(WebNNGraphImplBackendTest, BuildAndComputeSliceOperator) {
   {
     // Test a simple 2-dimension slice
-    SliceTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    SliceTester<float>{.input = {.type = OperandDataType::kFloat32,
                                  .dimensions = {2, 2},
                                  // [[1, 2],
                                  //  [3, 4]] with shape [2, 2]
                                  .values = {1, 2, 3, 4}},
                        .attributes = {.starts = {0, 0}, .sizes = {2, 2}},
-                       .output = {.type = mojom::DataType::kFloat32,
+                       .output = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 2},
                                   // [[1, 2],
                                   //  [3, 4]] with shape [2, 2]
@@ -3219,7 +3219,7 @@
   {
     // Test a complex 3-dimension slice
     SliceTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {3, 4, 5},
                   // [[[1 , 4 , 4 , -6, -3],
                   //   [-1, 7 , 3 , 1 , -8],
@@ -3239,7 +3239,7 @@
                              4,  1,  -5, 1,  -8, 4,  1,  -1, 9,  -4, 1,  -5,
                              -4, -1, 4,  -1, -3, 7,  1,  9,  -4, -9, -8, -9}},
         .attributes = {.starts = {0, 0, 1}, .sizes = {2, 3, 4}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 3, 4},
                    // [[[4 , 4 , -6, -3],
                    //   [7 , 3 , 1 , -8],
@@ -3258,7 +3258,7 @@
     SplitTester<float>{
         .input =
             {
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {2, 1, 3, 4},
                 // [[[[ 1,  2,  3,  4],
                 //    [ 5,  6,  7,  8],
@@ -3272,7 +3272,7 @@
             },
         .axis = 0,
         .outputs = {{
-                        .type = mojom::DataType::kFloat32,
+                        .type = OperandDataType::kFloat32,
                         .dimensions = {1, 1, 3, 4},
                         // [[[[ 1,  2,  3,  4],
                         //    [ 5,  6,  7,  8],
@@ -3280,7 +3280,7 @@
                         .values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
                     },
                     {
-                        .type = mojom::DataType::kFloat32,
+                        .type = OperandDataType::kFloat32,
                         .dimensions = {1, 1, 3, 4},
                         // [[[[13, 14, 15, 16],
                         //    [17, 18, 19, 20],
@@ -3294,7 +3294,7 @@
     SplitTester<float>{
         .input =
             {
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {1, 2, 3, 4},
                 // [[[[ 1,  2,  3,  4],
                 //    [ 5,  6,  7,  8],
@@ -3308,7 +3308,7 @@
             },
         .axis = 1,
         .outputs = {{
-                        .type = mojom::DataType::kFloat32,
+                        .type = OperandDataType::kFloat32,
                         .dimensions = {1, 1, 3, 4},
                         // [[[[ 1,  2,  3,  4],
                         //    [ 5,  6,  7,  8],
@@ -3316,7 +3316,7 @@
                         .values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
                     },
                     {
-                        .type = mojom::DataType::kFloat32,
+                        .type = OperandDataType::kFloat32,
                         .dimensions = {1, 1, 3, 4},
                         // [[[[13, 14, 15, 16],
                         //    [17, 18, 19, 20],
@@ -3330,7 +3330,7 @@
     SplitTester<float>{
         .input =
             {
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {2, 1, 3, 4},
                 // [[[[ 1,  2,  3,  4],
                 //    [ 5,  6,  7,  8],
@@ -3344,14 +3344,14 @@
             },
         .axis = 2,
         .outputs = {{
-                        .type = mojom::DataType::kFloat32,
+                        .type = OperandDataType::kFloat32,
                         .dimensions = {2, 1, 1, 4},
                         // [[[[ 1,  2,  3,  4]]],
                         //  [[[13, 14, 15, 16]]]] with shape (2, 1, 1, 4)
                         .values = {1, 2, 3, 4, 13, 14, 15, 16},
                     },
                     {
-                        .type = mojom::DataType::kFloat32,
+                        .type = OperandDataType::kFloat32,
                         .dimensions = {2, 1, 2, 4},
                         // [[[[ 5,  6,  7,  8],
                         //    [ 9, 10, 11, 12]]],
@@ -3366,7 +3366,7 @@
     SplitTester<float>{
         .input =
             {
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {2, 1, 3, 4},
                 // [[[[ 1,  2,  3,  4],
                 //    [ 5,  6,  7,  8],
@@ -3380,7 +3380,7 @@
             },
         .axis = 3,
         .outputs = {{
-                        .type = mojom::DataType::kFloat32,
+                        .type = OperandDataType::kFloat32,
                         .dimensions = {2, 1, 3, 2},
                         // [[[[ 1,  2],
                         //    [ 5,  6],
@@ -3391,7 +3391,7 @@
                         .values = {1, 2, 5, 6, 9, 10, 13, 14, 17, 18, 21, 22},
                     },
                     {
-                        .type = mojom::DataType::kFloat32,
+                        .type = OperandDataType::kFloat32,
                         .dimensions = {2, 1, 3, 2},
                         // [[[[ 3,  4],
                         //    [ 7,  8],
@@ -3417,16 +3417,16 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_operand_id =
-      builder.BuildInput("input", {2, 5}, mojom::DataType::kFloat32);
+      builder.BuildInput("input", {2, 5}, OperandDataType::kFloat32);
   uint64_t output1_operand_id =
-      builder.BuildOutput("output1", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output1", {2, 2}, OperandDataType::kFloat32);
   uint64_t split_operand_id =
-      builder.BuildIntermediateOperand({2, 3}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({2, 3}, OperandDataType::kFloat32);
   builder.BuildSplit(input_operand_id, {output1_operand_id, split_operand_id},
                      1);
 
   uint64_t output_operand_id =
-      builder.BuildOutput("output2", {3, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output2", {3, 2}, OperandDataType::kFloat32);
   builder.BuildReshape(split_operand_id, output_operand_id);
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -3487,14 +3487,14 @@
   // Test pad with mode = "constant" and value = 0 by default.
   {
     PadTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 3},
                   // [[1 2 3]
                   //  [4 5 6]]]] with shape (2, 3)
                   .values = {1, 2, 3, 4, 5, 6}},
         .beginning_padding = {1, 2},
         .ending_padding = {1, 2},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {4, 7},
                    // [[0 0 0 0 0 0 0]
                    //  [0 0 1 2 3 0 0]
@@ -3507,7 +3507,7 @@
   // Test pad with mode = "constant" and value = 1.
   {
     PadTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 3},
                   // [[1 2 3]
                   //  [4 5 6]]]] with shape (2, 3)
@@ -3515,7 +3515,7 @@
         .beginning_padding = {1, 2},
         .ending_padding = {1, 2},
         .value = 1,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {4, 7},
                    // [[1 1 1 1 1 1 1]
                    //  [1 1 1 2 3 1 1]
@@ -3528,7 +3528,7 @@
   // Test pad with mode = "edge".
   {
     PadTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 3},
                   // [[1 2 3]
                   //  [4 5 6]]]] with shape (2, 3)
@@ -3536,7 +3536,7 @@
         .beginning_padding = {1, 2},
         .ending_padding = {1, 2},
         .mode = mojom::PaddingMode::Tag::kEdge,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {4, 7},
                    // [[1 1 1 2 3 3 3]
                    //  [1 1 1 2 3 3 3]
@@ -3549,7 +3549,7 @@
   // Test pad with mode = "reflection".
   {
     PadTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 3},
                   // [[1 2 3]
                   //  [4 5 6]]]] with shape (2, 3)
@@ -3557,7 +3557,7 @@
         .beginning_padding = {1, 2},
         .ending_padding = {1, 2},
         .mode = mojom::PaddingMode::Tag::kReflection,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {4, 7},
                    // [[6 5 4 5 6 5 4]
                    //  [3 2 1 2 3 2 1]
@@ -3570,7 +3570,7 @@
   // Test pad with mode = "symmetric".
   {
     PadTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 3},
                   // [[1 2 3]
                   //  [4 5 6]]]] with shape (2, 3)
@@ -3578,7 +3578,7 @@
         .beginning_padding = {1, 2},
         .ending_padding = {1, 2},
         .mode = mojom::PaddingMode::Tag::kSymmetric,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {4, 7},
                    // [[2 1 1 2 3 3 2]
                    //  [2 1 1 2 3 3 2]
@@ -3682,13 +3682,13 @@
     // Test clamp for 4-D tensor input.
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kClamp,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 4},
                   .values = {-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12,
                              13, 14, 15, 16, 17, 18, 19, 20, 21, 22,  23,  24}},
         .clamp_min_value = 0,
         .clamp_max_value = 3,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 4},
                    .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                               3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}}}
@@ -3697,12 +3697,12 @@
   {
     // Test clamp for 0-D scalar input.
     UnaryOperatorTester<float>{.tag = mojom::Operation::Tag::kClamp,
-                               .input = {.type = mojom::DataType::kFloat32,
+                               .input = {.type = OperandDataType::kFloat32,
                                          .dimensions = {},
                                          .values = {24}},
                                .clamp_min_value = 0,
                                .clamp_max_value = 3,
-                               .output = {.type = mojom::DataType::kFloat32,
+                               .output = {.type = OperandDataType::kFloat32,
                                           .dimensions = {},
                                           .values = {3}}}
         .Test();
@@ -3714,10 +3714,10 @@
   {
     // Test hardSigmoid with default alpha = 0.2 and beta = 0.5.
     UnaryOperatorTester<float>{.tag = mojom::Operation::Tag::kHardSigmoid,
-                               .input = {.type = mojom::DataType::kFloat32,
+                               .input = {.type = OperandDataType::kFloat32,
                                          .dimensions = {1, 2, 2, 1},
                                          .values = {-1, -2, 0, 2}},
-                               .output = {.type = mojom::DataType::kFloat32,
+                               .output = {.type = OperandDataType::kFloat32,
                                           .dimensions = {1, 2, 2, 1},
                                           .values = {0.3, 0.1, 0.5, 0.9}}}
         .Test();
@@ -3725,12 +3725,12 @@
   {
     // Test hardSigmoid for 4-D tensor input.
     UnaryOperatorTester<float>{.tag = mojom::Operation::Tag::kHardSigmoid,
-                               .input = {.type = mojom::DataType::kFloat32,
+                               .input = {.type = OperandDataType::kFloat32,
                                          .dimensions = {1, 2, 2, 1},
                                          .values = {-1, -2, 0, 2}},
                                .hard_sigmoid_alpha = 0.1,
                                .hard_sigmoid_beta = 0.2,
-                               .output = {.type = mojom::DataType::kFloat32,
+                               .output = {.type = OperandDataType::kFloat32,
                                           .dimensions = {1, 2, 2, 1},
                                           .values = {0.1, 0, 0.2, 0.4}}}
         .Test();
@@ -3738,12 +3738,12 @@
   {
     // Test sigmoid for 0-D scalar input.
     UnaryOperatorTester<float>{.tag = mojom::Operation::Tag::kHardSigmoid,
-                               .input = {.type = mojom::DataType::kFloat32,
+                               .input = {.type = OperandDataType::kFloat32,
                                          .dimensions = {},
                                          .values = {24}},
                                .hard_sigmoid_alpha = 0.1,
                                .hard_sigmoid_beta = 3,
-                               .output = {.type = mojom::DataType::kFloat32,
+                               .output = {.type = OperandDataType::kFloat32,
                                           .dimensions = {},
                                           .values = {1}}}
         .Test();
@@ -3755,10 +3755,10 @@
   // Test hardSwish with a 0-D scalar input.
   {
     UnaryOperatorTester<float>{.tag = mojom::Operation::Tag::kHardSwish,
-                               .input = {.type = mojom::DataType::kFloat32,
+                               .input = {.type = OperandDataType::kFloat32,
                                          .dimensions = {},
                                          .values = {7.0}},
-                               .output = {.type = mojom::DataType::kFloat32,
+                               .output = {.type = OperandDataType::kFloat32,
                                           .dimensions = {},
                                           .values = {7.0}}}
         .Test();
@@ -3767,10 +3767,10 @@
   {
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kHardSwish,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 2, 2},
                   .values = {-6, -5, -4, -3, 0, 4, 5, 6}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 2, 2},
                    .values = {0, 0, 0, 0, 0, 4, 5, 6}}}
         .Test();
@@ -3782,10 +3782,10 @@
   // Test sigmoid with a 0-D scalar input.
   {
     UnaryOperatorTester<float>{.tag = mojom::Operation::Tag::kSigmoid,
-                               .input = {.type = mojom::DataType::kFloat32,
+                               .input = {.type = OperandDataType::kFloat32,
                                          .dimensions = {},
                                          .values = {0}},
-                               .output = {.type = mojom::DataType::kFloat32,
+                               .output = {.type = OperandDataType::kFloat32,
                                           .dimensions = {},
                                           .values = {0.5}}}
         .Test();
@@ -3794,10 +3794,10 @@
   {
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kSigmoid,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {3},
                   .values = {-1, 0, 1}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {3},
                    .values = {0.26894143, 0.5, 0.7310586}}}
         .Test();
@@ -3807,7 +3807,7 @@
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kSigmoid,
         .input =
-            {.type = mojom::DataType::kFloat32,
+            {.type = OperandDataType::kFloat32,
              .dimensions = {3, 4, 5},
              .values = {-0.18371736, 0.4805392,   2.7183356,   0.03039639,
                         0.04197176,  -1.1536852,  -2.0124357,  -0.885673,
@@ -3824,7 +3824,7 @@
                         -1.2325221,  -0.11140272, -0.43866253, 0.5770897,
                         0.42372307,  -0.33066413, -0.46210232, -0.6456375,
                         2.0984166,   -1.2020895,  1.5637838,   -0.7114222}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {3, 4, 5},
                    .values = {0.4541994,  0.61787516, 0.9381,     0.50759846,
                               0.5104914,  0.23981662, 0.11790343, 0.29200357,
@@ -3851,10 +3851,10 @@
     // Test softplus operator.
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kSoftplus,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 2, 3},
                   .values = {-100, -50, 40, 50, 100, 150}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 2, 3},
                    .values = {0, 0, 40, 50, 100, 150}}}
         .Test();
@@ -3867,10 +3867,10 @@
     // Test softsign with a float32 input.
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kSoftsign,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 1, 3},
                   .values = {-9, -7, -4, -3, -1, 0}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 1, 3},
                    .values = {-0.9, -0.875, -0.8, -0.75, -0.5, 0}}}
         .Test();
@@ -3879,10 +3879,10 @@
     // Test softsign with a float16 input.
     UnaryOperatorTester<float16>{
         .tag = mojom::Operation::Tag::kSoftsign,
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 2, 3, 1},
                   .values = Float16FromFloat32({0, 1, 3, 4, 7, 9})},
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 2, 3, 1},
                    .values =
                        Float16FromFloat32({0, 0.5, 0.75, 0.8, 0.875, 0.9})}}
@@ -3895,10 +3895,10 @@
   // Test tanh with a 0-D scalar input.
   {
     UnaryOperatorTester<float>{.tag = mojom::Operation::Tag::kTanh,
-                               .input = {.type = mojom::DataType::kFloat32,
+                               .input = {.type = OperandDataType::kFloat32,
                                          .dimensions = {},
                                          .values = {-1}},
-                               .output = {.type = mojom::DataType::kFloat32,
+                               .output = {.type = OperandDataType::kFloat32,
                                           .dimensions = {},
                                           .values = {-0.76159418}}}
         .Test();
@@ -3907,10 +3907,10 @@
   {
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kTanh,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {3},
                   .values = {-1, 0, 1}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {3},
                    .values = {-0.76159418, 0., 0.76159418}}}
         .Test();
@@ -3919,10 +3919,10 @@
   {
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kTanh,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3},
                   .values = {-2, -1, 0, 1, 2, 3}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3},
                    .values = {-0.9640275800758168, -0.7615941559557649, 0,
                               0.7615941559557649, 0.9640275800758169,
@@ -3936,11 +3936,11 @@
   {
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kRelu,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 4},
                   .values = {-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12,
                              13, 14, 15, 16, 17, 18, 19, 20, 21, 22,  23,  24}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 4},
                    .values = {0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
                               13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}}}
@@ -3950,10 +3950,10 @@
   // Test with 8-byte-length input/output.
   {
     UnaryOperatorTester<float>{.tag = mojom::Operation::Tag::kRelu,
-                               .input = {.type = mojom::DataType::kFloat32,
+                               .input = {.type = OperandDataType::kFloat32,
                                          .dimensions = {1, 2, 1, 1},
                                          .values = {-1, 2}},
-                               .output = {.type = mojom::DataType::kFloat32,
+                               .output = {.type = OperandDataType::kFloat32,
                                           .dimensions = {1, 2, 1, 1},
                                           .values = {0, 2}}}
         .Test();
@@ -3966,14 +3966,14 @@
     // Test elu with a 3d input and alpha = 1.0.
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kElu,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 2, 3},
                   .values = {0.4301911, 0.54719144, -1.1637765, 0.18390046,
                              0.58390397, 0.1735679, 0.539724, -0.953514,
                              -0.59202826, -0.17344485, 0.14395015,
                              -0.37920907}},
         .elu_alpha = 1.0,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2, 3},
                    .values = {0.4301911, 0.54719144, -0.6876954670284463,
                               0.18390046, 0.58390397, 0.1735679, 0.539724,
@@ -3986,14 +3986,14 @@
     // Test elu with a 3d input and alpha = 0.8.
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kElu,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 2, 3},
                   .values = {0.4301911, 0.54719144, -1.1637765, 0.18390046,
                              0.58390397, 0.1735679, 0.539724, -0.953514,
                              -0.59202826, -0.17344485, 0.14395015,
                              -0.37920907}},
         .elu_alpha = 0.8,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2, 3},
                    .values = {0.4301911, 0.54719144, -0.550156373622757,
                               0.18390046, 0.58390397, 0.1735679, 0.539724,
@@ -4010,14 +4010,14 @@
     // Test leakyRelu with a 3d input and alpha = 0.01.
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kLeakyRelu,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 2, 3},
                   .values = {0.4301911, 0.54719144, -1.1637765, 0.18390046,
                              0.58390397, 0.1735679, 0.539724, -0.953514,
                              -0.59202826, -0.17344485, 0.14395015,
                              -0.37920907}},
         .leaky_relu_alpha = 0.01,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2, 3},
                    .values = {0.4301911, 0.54719144, -0.011637765, 0.18390046,
                               0.58390397, 0.1735679, 0.539724, -0.00953514,
@@ -4029,14 +4029,14 @@
     // Test leakyRelu with a 3d input and alpha = 0.05.
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kLeakyRelu,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 2, 3},
                   .values = {0.4301911, 0.54719144, -1.1637765, 0.18390046,
                              0.58390397, 0.1735679, 0.539724, -0.953514,
                              -0.59202826, -0.17344485, 0.14395015,
                              -0.37920907}},
         .leaky_relu_alpha = 0.05,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2, 3},
                    .values = {0.4301911, 0.54719144, -0.058188825, 0.18390046,
                               0.58390397, 0.1735679, 0.539724, -0.0476757,
@@ -4052,12 +4052,12 @@
     // Test linear with a 3d input and alpha = 0.01, beta = 1.0.
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kLinear,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 2, 3},
                   .values = {-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}},
         .linear_alpha = 0.01,
         .linear_beta = 1.0,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2, 3},
                    .values = {0.99, 1, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07,
                               1.08, 1.09, 1.1}}}
@@ -4067,12 +4067,12 @@
     // Test linear with a 2d input and alpha = 0.02, beta = 2.0.
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kLinear,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 3},
                   .values = {-1, 0, 1, 2, 3, 4}},
         .linear_alpha = 0.02,
         .linear_beta = 2.0,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 3},
                    .values = {1.98, 2, 2.02, 2.04, 2.06, 2.08}}}
         .Test();
@@ -4089,12 +4089,12 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_operand_id =
-      builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
   uint64_t relu1_output_id =
-      builder.BuildIntermediateOperand({1, 2, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({1, 2, 3, 4}, OperandDataType::kFloat32);
   builder.BuildRelu(input_operand_id, relu1_output_id);
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {1, 2, 3, 4}, OperandDataType::kFloat32);
   builder.BuildRelu(relu1_output_id, output_operand_id);
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -4118,9 +4118,9 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_operand_id =
-      builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {1, 1, 6, 4}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {1, 1, 6, 4}, OperandDataType::kFloat32);
   builder.BuildReshape(input_operand_id, output_operand_id);
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -4148,12 +4148,12 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_operand_id =
-      builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
   uint64_t relu_output_id =
-      builder.BuildIntermediateOperand({1, 2, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({1, 2, 3, 4}, OperandDataType::kFloat32);
   builder.BuildRelu(input_operand_id, relu_output_id);
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {1, 1, 6, 4}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {1, 1, 6, 4}, OperandDataType::kFloat32);
   builder.BuildReshape(relu_output_id, output_operand_id);
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -4182,12 +4182,12 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_operand_id =
-      builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
   uint64_t reshape_output_id =
-      builder.BuildIntermediateOperand({1, 1, 6, 4}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({1, 1, 6, 4}, OperandDataType::kFloat32);
   builder.BuildReshape(input_operand_id, reshape_output_id);
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {1, 1, 6, 4}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {1, 1, 6, 4}, OperandDataType::kFloat32);
   builder.BuildRelu(reshape_output_id, output_operand_id);
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -4214,12 +4214,12 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_operand_id =
-      builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
   uint64_t reshape_output_id =
-      builder.BuildIntermediateOperand({1, 1, 6, 4}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({1, 1, 6, 4}, OperandDataType::kFloat32);
   builder.BuildReshape(input_operand_id, reshape_output_id);
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {1, 2, 3, 4}, OperandDataType::kFloat32);
   builder.BuildReshape(reshape_output_id, output_operand_id);
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -4246,12 +4246,12 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_operand_id =
-      builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
   uint64_t output1_operand_id =
-      builder.BuildOutput("output1", {1, 1, 6, 4}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output1", {1, 1, 6, 4}, OperandDataType::kFloat32);
   builder.BuildReshape(input_operand_id, output1_operand_id);
   uint64_t output2_operand_id =
-      builder.BuildOutput("output2", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output2", {1, 2, 3, 4}, OperandDataType::kFloat32);
   builder.BuildRelu(input_operand_id, output2_operand_id);
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -4309,156 +4309,156 @@
 TEST_F(WebNNGraphImplBackendTest, BuildAndComputeSingleOperatorReduce) {
   // Test reduceL1 with axes = {1} and keep_dimensions = true.
   {
-    ReduceTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ReduceTester<float>{.input = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {1, 2, 3, 4, 5, 6}},
                         .axes = {1},
                         .keep_dimensions = true,
                         .kind = mojom::Reduce::Kind::kL1,
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {2, 1},
                                    .values = {6, 15}}}
         .Test();
   }
   // Test reduceL2 with axes = {1} and keep_dimensions = true.
   {
-    ReduceTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ReduceTester<float>{.input = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {1, 2, 3, 4, 5, 6}},
                         .axes = {1},
                         .keep_dimensions = true,
                         .kind = mojom::Reduce::Kind::kL2,
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {2, 1},
                                    .values = {3.74165738, 8.77496438}}}
         .Test();
   }
   // Test reduceLogSum with axes = {1} and keep_dimensions = true.
   {
-    ReduceTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ReduceTester<float>{.input = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {1, 2, 3, 4, 5, 6}},
                         .axes = {1},
                         .keep_dimensions = true,
                         .kind = mojom::Reduce::Kind::kLogSum,
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {2, 1},
                                    .values = {1.79175946, 2.70805020}}}
         .Test();
   }
   // Test reduceLosSumExp with axes = {1} and keep_dimensions = true.
   {
-    ReduceTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ReduceTester<float>{.input = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {1, 2, 3, 4, 5, 6}},
                         .axes = {1},
                         .keep_dimensions = true,
                         .kind = mojom::Reduce::Kind::kLogSumExp,
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {2, 1},
                                    .values = {3.40760596, 6.40760596}}}
         .Test();
   }
   // Test reduceMax with axes = {1} and keep_dimensions = true.
   {
-    ReduceTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ReduceTester<float>{.input = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {1, 2, 3, 4, 5, 6}},
                         .axes = {1},
                         .keep_dimensions = true,
                         .kind = mojom::Reduce::Kind::kMax,
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {2, 1},
                                    .values = {3, 6}}}
         .Test();
   }
   // Test reduceMean with axes = {1} and keep_dimensions = true.
   {
-    ReduceTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ReduceTester<float>{.input = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {1, 2, 3, 4, 5, 6}},
                         .axes = {1},
                         .keep_dimensions = true,
                         .kind = mojom::Reduce::Kind::kMean,
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {2, 1},
                                    .values = {2, 5}}}
         .Test();
   }
   // Test reduceMin with axes = {1} and keep_dimensions = false.
   {
-    ReduceTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ReduceTester<float>{.input = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {1, 2, 3, 4, 5, 6}},
                         .axes = {1},
                         .keep_dimensions = false,
                         .kind = mojom::Reduce::Kind::kMin,
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {2},
                                    .values = {1, 4}}}
         .Test();
   }
   // Test reduceProduct with axes = {1} and keep_dimensions = false.
   {
-    ReduceTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ReduceTester<float>{.input = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {1, 2, 3, 4, 5, 6}},
                         .axes = {1},
                         .keep_dimensions = false,
                         .kind = mojom::Reduce::Kind::kProduct,
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {2},
                                    .values = {6, 120}}}
         .Test();
   }
   // Test reduceSum with axes = {1} and keep_dimensions = false.
   {
-    ReduceTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ReduceTester<float>{.input = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {1, 2, 3, 4, 5, 6}},
                         .axes = {1},
                         .keep_dimensions = false,
                         .kind = mojom::Reduce::Kind::kSum,
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {2},
                                    .values = {6, 15}}}
         .Test();
   }
   // Test reduceSumSquare with axes = {1} and keep_dimensions = false.
   {
-    ReduceTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ReduceTester<float>{.input = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {1, 2, 3, 4, 5, 6}},
                         .axes = {1},
                         .keep_dimensions = false,
                         .kind = mojom::Reduce::Kind::kSumSquare,
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {2},
                                    .values = {14, 77}}}
         .Test();
   }
   // Test reduceSum with all axes and keep_dimensions = true.
   {
-    ReduceTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ReduceTester<float>{.input = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {1, 2, 3, 4, 5, 6}},
                         .axes = {0, 1},
                         .keep_dimensions = true,
                         .kind = mojom::Reduce::Kind::kSum,
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {1, 1},
                                    .values = {21}}}
         .Test();
   }
   // Test reduceSum with all axes and keep_dimensions = false.
   {
-    ReduceTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    ReduceTester<float>{.input = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {1, 2, 3, 4, 5, 6}},
                         .axes = {0, 1},
                         .keep_dimensions = false,
                         .kind = mojom::Reduce::Kind::kSum,
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {},
                                    .values = {21}}}
         .Test();
@@ -4501,14 +4501,14 @@
   {
     // Test gather with 1-D input, 1-D indices and axis = 0 with data type
     // uint32.
-    GatherTester<float, uint32_t>{.input = {.type = mojom::DataType::kFloat32,
+    GatherTester<float, uint32_t>{.input = {.type = OperandDataType::kFloat32,
                                             .dimensions = {4},
                                             .values = {1, 2, 3, 4}},
-                                  .indices = {.type = mojom::DataType::kUint32,
+                                  .indices = {.type = OperandDataType::kUint32,
                                               .dimensions = {5},
                                               .values = {2, 1, 3, 0, 1}},
                                   .axis = 0,
-                                  .output = {.type = mojom::DataType::kFloat32,
+                                  .output = {.type = OperandDataType::kFloat32,
                                              .dimensions = {5},
                                              .values = {3, 2, 4, 1, 2}}}
         .Test();
@@ -4517,7 +4517,7 @@
     // Test gather with 4-D input, 1-D indices with negative index and axis = 1
     // with data type int64.
     GatherTester<uint32_t, int64_t>{
-        .input = {.type = mojom::DataType::kUint32,
+        .input = {.type = OperandDataType::kUint32,
                   .dimensions = {2, 2, 2, 2},
                   // [[[[ 1  2]
                   //    [ 3  4]]
@@ -4529,11 +4529,11 @@
                   //    [15 16]]]] with shape (2, 2, 2, 2)
                   .values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
                              16}},
-        .indices = {.type = mojom::DataType::kInt64,
+        .indices = {.type = OperandDataType::kInt64,
                     .dimensions = {1},
                     .values = {-1}},
         .axis = 1,
-        .output = {.type = mojom::DataType::kUint32,
+        .output = {.type = OperandDataType::kUint32,
                    .dimensions = {2, 1, 2, 2},
                    // [[[[ 5  6]
                    //    [ 7  8]]]
@@ -4546,14 +4546,14 @@
     // Test gather with 1-D input, 0-D indices and axis = 0 with data type
     // uint32.
     GatherTester<int32_t, uint32_t>{
-        .input = {.type = mojom::DataType::kInt32,
+        .input = {.type = OperandDataType::kInt32,
                   .dimensions = {3},
                   .values = {1, 2, 3}},
-        .indices = {.type = mojom::DataType::kUint32,
+        .indices = {.type = OperandDataType::kUint32,
                     .dimensions = {},
                     .values = {2}},
         .axis = 0,
-        .output = {.type = mojom::DataType::kInt32,
+        .output = {.type = OperandDataType::kInt32,
                    .dimensions = {},
                    .values = {3}}}
         .Test();
@@ -4562,16 +4562,16 @@
     // Test gather with 6-D input, 0-D indices and axis = 0 with data type
     // int32.
     GatherTester<float, int32_t>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 1, 1, 1, 1, 5},
                   // [[[[[[1 2 3 4  5]]]]]
                   //  [[[[[6 7 8 9 10]]]]]] with shape (2, 1, 1, 1, 1, 5)
                   .values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}},
-        .indices = {.type = mojom::DataType::kInt32,
+        .indices = {.type = OperandDataType::kInt32,
                     .dimensions = {},
                     .values = {1}},
         .axis = 0,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 1, 1, 5},
                    // [[[[[6 7 8 9 10]]]]] with shape (1, 1, 1, 1, 5)
                    .values = {6, 7, 8, 9, 10}}}
@@ -4581,7 +4581,7 @@
     // Test gather with 3-D input, 0-D indices and axis = 1 with data type
     // int64.
     GatherTester<float, int64_t>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {3, 4, 2},
                   // [[[ 1  2]
                   //   [ 3  4]
@@ -4597,11 +4597,11 @@
                   //   [23 24]]] with shape (3, 4, 2)
                   .values = {1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12,
                              13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}},
-        .indices = {.type = mojom::DataType::kInt64,
+        .indices = {.type = OperandDataType::kInt64,
                     .dimensions = {},
                     .values = {2}},
         .axis = 1,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {3, 2},
                    // [[ 5  6]
                    //  [13 14]
@@ -4613,7 +4613,7 @@
     // Test gather with 5-D input, 0-D indices and axis = 4 with data type
     // int32.
     GatherTester<int32_t, int32_t>{
-        .input = {.type = mojom::DataType::kInt32,
+        .input = {.type = OperandDataType::kInt32,
                   .dimensions = {2, 1, 1, 3, 2},
                   // [[[[[ 1  2]
                   //     [ 3  4]
@@ -4622,11 +4622,11 @@
                   //     [ 9 10]
                   //     [11 12]]]]] with shape (2, 1, 1, 3, 2)
                   .values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}},
-        .indices = {.type = mojom::DataType::kInt32,
+        .indices = {.type = OperandDataType::kInt32,
                     .dimensions = {},
                     .values = {1}},
         .axis = 4,
-        .output = {.type = mojom::DataType::kInt32,
+        .output = {.type = OperandDataType::kInt32,
                    .dimensions = {2, 1, 1, 3},
                    // [[[[ 2  4  6]]]
                    //  [[[ 8 10 12]]]] with shape (2, 1, 1, 3)
@@ -4637,17 +4637,17 @@
     // Test gather with 2-D input, 2-D out-of-bound indices and axis = 1 with
     // data type uint32.
     GatherTester<float, uint32_t>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {3, 3},
                   // [[10 20 30]
                   //  [40 50 60]
                   //  [70 80 90]] with shape (3, 3)
                   .values = {10, 20, 30, 40, 50, 60, 70, 80, 90}},
-        .indices = {.type = mojom::DataType::kUint32,
+        .indices = {.type = OperandDataType::kUint32,
                     .dimensions = {1, 2},
                     .values = {0, 4}},
         .axis = 1,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {3, 1, 2},
                    // [[[10 50]]
                    //  [[40 80]]
@@ -4659,14 +4659,14 @@
     // Test gather with 1-D input, 2-D out-of-bound indices and axis = 0 with
     // data type int32.
     GatherTester<float, int32_t>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {4},
                   .values = {0, 1, 2, 3}},
-        .indices = {.type = mojom::DataType::kInt32,
+        .indices = {.type = OperandDataType::kInt32,
                     .dimensions = {2, 5},
                     .values = {0, 1, 2, 3, 4, -1, -2, -3, -4, -5}},
         .axis = 0,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 5},
                    // [[0 1 2 3 3]
                    //  [3 2 1 0 3]] with shape (2, 5)
@@ -4681,10 +4681,10 @@
   {
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kGelu,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {3},
                   .values = {-1, 0, 1}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {3},
                    .values = {-0.15865526383236372, 0, 0.8413447361676363}}}
         .Test();
@@ -4694,10 +4694,10 @@
   {
     UnaryOperatorTester<float>{
         .tag = mojom::Operation::Tag::kGelu,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 1, 3},
                   .values = {-1, 0, 1}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 1, 3},
                    .values = {-0.15865526383236372, 0, 0.8413447361676363}}}
         .Test();
@@ -4798,13 +4798,13 @@
 TEST_F(WebNNGraphImplBackendTest, FuseStandaloneActivationIntoGemm) {
   // Test gemm without a third input, activation = linear.
   {
-    GemmTester<float>{.input_a = {.type = mojom::DataType::kFloat32,
+    GemmTester<float>{.input_a = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 2},
                                   .values = {1, 2, 3, 4}},
-                      .input_b = {.type = mojom::DataType::kFloat32,
+                      .input_b = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 2},
                                   .values = {1, 2, 3, 4}},
-                      .output = {.type = mojom::DataType::kFloat32,
+                      .output = {.type = OperandDataType::kFloat32,
                                  .dimensions = {2, 2},
                                  .values = {71, 101, 151, 221}}}
         .TestFusingStandaloneActivation(
@@ -4816,16 +4816,16 @@
   // Test gemm with a third input, activation = relu.
   {
     GemmTester<float>{
-        .input_a = {.type = mojom::DataType::kFloat32,
+        .input_a = {.type = OperandDataType::kFloat32,
                     .dimensions = {2, 2},
                     .values = {1, 2, 3, -4}},
-        .input_b = {.type = mojom::DataType::kFloat32,
+        .input_b = {.type = OperandDataType::kFloat32,
                     .dimensions = {2, 2},
                     .values = {1, 2, 3, 4}},
-        .input_c = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .input_c = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                       .dimensions = {2, 2},
                                       .values = {1, 1, 1, 1}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2},
                    .values = {8, 11, 0, 0}}}
         .TestFusingStandaloneActivation(
@@ -4840,13 +4840,13 @@
   SKIP_TEST_IF(!dml::Adapter::GetNpuInstanceForTesting(DML_FEATURE_LEVEL_4_0)
                     .has_value());
   // Test gemm without a third input.
-  GemmTester<float>{.input_a = {.type = mojom::DataType::kFloat32,
+  GemmTester<float>{.input_a = {.type = OperandDataType::kFloat32,
                                 .dimensions = {2, 2},
                                 .values = {1, 2, 3, 4}},
-                    .input_b = {.type = mojom::DataType::kFloat32,
+                    .input_b = {.type = OperandDataType::kFloat32,
                                 .dimensions = {2, 2},
                                 .values = {1, 2, 3, 4}},
-                    .output = {.type = mojom::DataType::kFloat32,
+                    .output = {.type = OperandDataType::kFloat32,
                                .dimensions = {2, 2},
                                .values = {7, 10, 15, 22}}}
       .Test(mojom::CreateContextOptions::Device::kNpu);
@@ -4857,13 +4857,13 @@
 TEST_F(WebNNGraphImplBackendTest, BuildSingleOperatorGemmOnGpu) {
   // Test gemm without a third input.
   {
-    GemmTester<float>{.input_a = {.type = mojom::DataType::kFloat32,
+    GemmTester<float>{.input_a = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 2},
                                   .values = {1, 2, 3, 4}},
-                      .input_b = {.type = mojom::DataType::kFloat32,
+                      .input_b = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 2},
                                   .values = {1, 2, 3, 4}},
-                      .output = {.type = mojom::DataType::kFloat32,
+                      .output = {.type = OperandDataType::kFloat32,
                                  .dimensions = {2, 2},
                                  .values = {7, 10, 15, 22}}}
         .Test();
@@ -4872,16 +4872,16 @@
   // Test gemm with a third input.
   {
     GemmTester<float>{
-        .input_a = {.type = mojom::DataType::kFloat32,
+        .input_a = {.type = OperandDataType::kFloat32,
                     .dimensions = {2, 2},
                     .values = {1, 2, 3, 4}},
-        .input_b = {.type = mojom::DataType::kFloat32,
+        .input_b = {.type = OperandDataType::kFloat32,
                     .dimensions = {2, 2},
                     .values = {1, 2, 3, 4}},
-        .input_c = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .input_c = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                       .dimensions = {2, 2},
                                       .values = {1, 1, 1, 1}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2},
                    .values = {8, 11, 16, 23}}}
         .Test();
@@ -4890,16 +4890,16 @@
   // Test broadcasting the third input's dimensions from  {1,2} to {2,2}.
   {
     GemmTester<float>{
-        .input_a = {.type = mojom::DataType::kFloat32,
+        .input_a = {.type = OperandDataType::kFloat32,
                     .dimensions = {2, 2},
                     .values = {1, 2, 3, 4}},
-        .input_b = {.type = mojom::DataType::kFloat32,
+        .input_b = {.type = OperandDataType::kFloat32,
                     .dimensions = {2, 2},
                     .values = {1, 2, 3, 4}},
-        .input_c = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .input_c = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                       .dimensions = {1, 2},
                                       .values = {1, 2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2},
                    .values = {8, 12, 16, 24}}}
         .Test();
@@ -4908,16 +4908,16 @@
   // Test broadcasting the third input's dimensions from  {2,1} to {2,2}.
   {
     GemmTester<float>{
-        .input_a = {.type = mojom::DataType::kFloat32,
+        .input_a = {.type = OperandDataType::kFloat32,
                     .dimensions = {2, 2},
                     .values = {1, 2, 3, 4}},
-        .input_b = {.type = mojom::DataType::kFloat32,
+        .input_b = {.type = OperandDataType::kFloat32,
                     .dimensions = {2, 2},
                     .values = {1, 2, 3, 4}},
-        .input_c = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .input_c = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                       .dimensions = {2, 1},
                                       .values = {1, 2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2},
                    .values = {8, 11, 17, 24}}}
         .Test();
@@ -4926,16 +4926,16 @@
   // Test gemm with a third input which is a scalar.
   {
     GemmTester<float>{
-        .input_a = {.type = mojom::DataType::kFloat32,
+        .input_a = {.type = OperandDataType::kFloat32,
                     .dimensions = {2, 2},
                     .values = {1, 2, 3, 4}},
-        .input_b = {.type = mojom::DataType::kFloat32,
+        .input_b = {.type = OperandDataType::kFloat32,
                     .dimensions = {2, 2},
                     .values = {1, 2, 3, 4}},
-        .input_c = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .input_c = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                       .dimensions = {},
                                       .values = {1}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2},
                    .values = {8, 11, 16, 23}}}
         .Test();
@@ -5043,14 +5043,14 @@
     const uint32_t hidden_size = 5;
     const uint32_t num_directions = 1;
     GruTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size},
                   .values = {1, 2, 3, 4, 5, 6, 7, 8, 9}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {num_directions, 3 * hidden_size, input_size},
                    .values = std::vector<float>(
                        num_directions * 3 * hidden_size * input_size, 1)},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {num_directions, 3 * hidden_size,
                                             hidden_size},
                              .values = std::vector<float>(
@@ -5061,7 +5061,7 @@
         .attributes = {.activations =
                            {Activation{.kind = mojom::Activation::Tag::kRelu},
                             Activation{.kind = mojom::Activation::Tag::kRelu}}},
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {num_directions, batch_size, hidden_size},
                      .values = {-30., -30., -30., -30., -30., -210., -210.,
                                 -210., -210., -210., -552., -552., -552., -552.,
@@ -5076,14 +5076,14 @@
     const uint32_t hidden_size = 5;
     const uint32_t num_directions = 2;
     GruTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size},
                   .values = {1, 2, 3, 4, 5, 6, 7, 8, 9}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {num_directions, 3 * hidden_size, input_size},
                    .values = std::vector<float>(
                        num_directions * 3 * hidden_size * input_size, 1)},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {num_directions, 3 * hidden_size,
                                             hidden_size},
                              .values = std::vector<float>(
@@ -5095,7 +5095,7 @@
                        .activations =
                            {Activation{.kind = mojom::Activation::Tag::kRelu},
                             Activation{.kind = mojom::Activation::Tag::kRelu}}},
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {num_directions, batch_size, hidden_size},
                      .values = {-30.,  -30.,  -30.,  -30.,  -30.,  -210.,
                                 -210., -210., -210., -210., -552., -552.,
@@ -5112,15 +5112,15 @@
     const uint32_t hidden_size = 5;
     const uint32_t num_directions = 2;
     GruTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size},
                   .values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8,
                              9}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {num_directions, 3 * hidden_size, input_size},
                    .values = std::vector<float>(
                        num_directions * 3 * hidden_size * input_size, 1)},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {num_directions, 3 * hidden_size,
                                             hidden_size},
                              .values = std::vector<float>(
@@ -5132,7 +5132,7 @@
                        .activations =
                            {Activation{.kind = mojom::Activation::Tag::kRelu},
                             Activation{.kind = mojom::Activation::Tag::kRelu}}},
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {num_directions, batch_size, hidden_size},
                      .values = {6.,  6.,  6.,  6.,  6.,  15., 15., 15.,
                                 15., 15., 24., 24., 24., 24., 24., 6.,
@@ -5148,14 +5148,14 @@
     const uint32_t hidden_size = 5;
     const uint32_t num_directions = 1;
     GruTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size},
                   .values = {1, 2, 3, 4, 5, 6, 7, 8, 9}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {num_directions, 3 * hidden_size, input_size},
                    .values = std::vector<float>(
                        num_directions * 3 * hidden_size * input_size, 1)},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {num_directions, 3 * hidden_size,
                                             hidden_size},
                              .values = std::vector<float>(
@@ -5164,19 +5164,19 @@
         .steps = steps,
         .hidden_size = hidden_size,
         .bias =
-            OperandInfo<float>{.type = mojom::DataType::kFloat32,
+            OperandInfo<float>{.type = OperandDataType::kFloat32,
                                .dimensions = {num_directions, 3 * hidden_size},
                                .values = std::vector<float>(
                                    num_directions * 3 * hidden_size, 1)},
         .recurrent_bias =
-            OperandInfo<float>{.type = mojom::DataType::kFloat32,
+            OperandInfo<float>{.type = OperandDataType::kFloat32,
                                .dimensions = {num_directions, 3 * hidden_size},
                                .values = std::vector<float>(
                                    num_directions * 3 * hidden_size, 0)},
         .attributes = {.activations =
                            {Activation{.kind = mojom::Activation::Tag::kRelu},
                             Activation{.kind = mojom::Activation::Tag::kRelu}}},
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {num_directions, batch_size, hidden_size},
                      .values = {-42., -42., -42., -42., -42., -240., -240.,
                                 -240., -240., -240., -600., -600., -600., -600.,
@@ -5191,14 +5191,14 @@
     const uint32_t hidden_size = 5;
     const uint32_t num_directions = 1;
     GruTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size},
                   .values = {1, 2, 3, 4, 5, 6, 7, 8, 9}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {num_directions, 3 * hidden_size, input_size},
                    .values = std::vector<float>(
                        num_directions * 3 * hidden_size * input_size, 1)},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {num_directions, 3 * hidden_size,
                                             hidden_size},
                              .values = std::vector<float>(
@@ -5207,20 +5207,20 @@
         .steps = steps,
         .hidden_size = hidden_size,
         .bias =
-            OperandInfo<float>{.type = mojom::DataType::kFloat32,
+            OperandInfo<float>{.type = OperandDataType::kFloat32,
                                .dimensions = {num_directions, 3 * hidden_size},
                                .values = std::vector<float>(
                                    num_directions * 3 * hidden_size, 1)},
         .initial_hidden_state =
             OperandInfo<float>{
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {num_directions, batch_size, hidden_size},
                 .values = std::vector<float>(
                     num_directions * batch_size * hidden_size, 1)},
         .attributes = {.activations =
                            {Activation{.kind = mojom::Activation::Tag::kRelu},
                             Activation{.kind = mojom::Activation::Tag::kRelu}}},
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {num_directions, batch_size, hidden_size},
                      .values = {-725., -725., -725., -725., -725., -2399.,
                                 -2399., -2399., -2399., -2399., -5045., -5045.,
@@ -5235,14 +5235,14 @@
     const uint32_t hidden_size = 5;
     const uint32_t num_directions = 1;
     GruTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size},
                   .values = {1, 2, 3, 4, 5, 6, 7, 8, 9}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {num_directions, 3 * hidden_size, input_size},
                    .values = std::vector<float>(
                        num_directions * 3 * hidden_size * input_size, 1)},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {num_directions, 3 * hidden_size,
                                             hidden_size},
                              .values = std::vector<float>(
@@ -5251,18 +5251,18 @@
         .steps = steps,
         .hidden_size = hidden_size,
         .bias =
-            OperandInfo<float>{.type = mojom::DataType::kFloat32,
+            OperandInfo<float>{.type = OperandDataType::kFloat32,
                                .dimensions = {num_directions, 3 * hidden_size},
                                .values = std::vector<float>(
                                    num_directions * 3 * hidden_size, 1)},
         .recurrent_bias =
-            OperandInfo<float>{.type = mojom::DataType::kFloat32,
+            OperandInfo<float>{.type = OperandDataType::kFloat32,
                                .dimensions = {num_directions, 3 * hidden_size},
                                .values = std::vector<float>(
                                    num_directions * 3 * hidden_size, 0)},
         .initial_hidden_state =
             OperandInfo<float>{
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {num_directions, batch_size, hidden_size},
                 .values = std::vector<float>(
                     num_directions * batch_size * hidden_size, 1)},
@@ -5271,12 +5271,12 @@
                            {Activation{.kind = mojom::Activation::Tag::kRelu},
                             Activation{.kind = mojom::Activation::Tag::kRelu}}},
         .outputs =
-            {{.type = mojom::DataType::kFloat32,
+            {{.type = OperandDataType::kFloat32,
               .dimensions = {num_directions, batch_size, hidden_size},
               .values = {-725., -725., -725., -725., -725., -2399., -2399.,
                          -2399., -2399., -2399., -5045., -5045., -5045., -5045.,
                          -5045.}},
-             {.type = mojom::DataType::kFloat32,
+             {.type = OperandDataType::kFloat32,
               .dimensions = {steps, num_directions, batch_size, hidden_size},
               .values = {-725., -725., -725., -725., -725., -2399., -2399.,
                          -2399., -2399., -2399., -5045., -5045., -5045., -5045.,
@@ -5371,18 +5371,18 @@
     const uint32_t input_size = 3;
     const uint32_t hidden_size = 5;
     GruCellTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {batch_size, input_size},
                   .values = {1, 2, 3, 4, 5, 6, 7, 8, 9}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {3 * hidden_size, input_size},
                    .values =
                        std::vector<float>(3 * hidden_size * input_size, 1)},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {3 * hidden_size, hidden_size},
                              .values = std::vector<float>(
                                  3 * hidden_size * hidden_size, 1)},
-        .hidden_state = {.type = mojom::DataType::kFloat32,
+        .hidden_state = {.type = OperandDataType::kFloat32,
                          .dimensions = {batch_size, hidden_size},
                          .values =
                              std::vector<float>(batch_size * hidden_size, 0)},
@@ -5390,7 +5390,7 @@
         .attributes = {.activations =
                            {Activation{.kind = mojom::Activation::Tag::kRelu},
                             Activation{.kind = mojom::Activation::Tag::kRelu}}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {batch_size, hidden_size},
                    .values = {-30., -30., -30., -30., -30., -210., -210., -210.,
                               -210., -210., -552., -552., -552., -552., -552.}}}
@@ -5402,34 +5402,34 @@
     const uint32_t input_size = 3;
     const uint32_t hidden_size = 5;
     GruCellTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {batch_size, input_size},
                   .values = {1, 2, 3, 4, 5, 6, 7, 8, 9}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {3 * hidden_size, input_size},
                    .values =
                        std::vector<float>(3 * hidden_size * input_size, 1)},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {3 * hidden_size, hidden_size},
                              .values = std::vector<float>(
                                  3 * hidden_size * hidden_size, 1)},
-        .hidden_state = {.type = mojom::DataType::kFloat32,
+        .hidden_state = {.type = OperandDataType::kFloat32,
                          .dimensions = {batch_size, hidden_size},
                          .values =
                              std::vector<float>(batch_size * hidden_size, 0)},
         .hidden_size = hidden_size,
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {3 * hidden_size},
                                    .values =
                                        std::vector<float>(3 * hidden_size, 1)},
-        .recurrent_bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .recurrent_bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                              .dimensions = {3 * hidden_size},
                                              .values = std::vector<float>(
                                                  3 * hidden_size, 0)},
         .attributes = {.activations =
                            {Activation{.kind = mojom::Activation::Tag::kRelu},
                             Activation{.kind = mojom::Activation::Tag::kRelu}}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {batch_size, hidden_size},
                    .values = {-42., -42., -42., -42., -42., -240., -240., -240.,
                               -240., -240., -600., -600., -600., -600., -600.}}}
@@ -5447,19 +5447,19 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_a_operand_id =
-      builder.BuildInput("input_a", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_a", {2, 2}, OperandDataType::kFloat32);
   uint64_t input_b_operand_id =
-      builder.BuildInput("input_b", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_b", {2, 2}, OperandDataType::kFloat32);
   uint64_t intermediate_1_operand_id =
-      builder.BuildIntermediateOperand({2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({2, 2}, OperandDataType::kFloat32);
   builder.BuildGemm(input_a_operand_id, input_b_operand_id,
                     intermediate_1_operand_id, GemmAttributes());
   uint64_t intermediate_2_operand_id =
-      builder.BuildIntermediateOperand({2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({2, 2}, OperandDataType::kFloat32);
   builder.BuildGemm(input_a_operand_id, input_b_operand_id,
                     intermediate_2_operand_id, GemmAttributes());
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {2, 2}, OperandDataType::kFloat32);
   builder.BuildGemm(intermediate_1_operand_id, intermediate_2_operand_id,
                     output_operand_id, GemmAttributes());
 
@@ -5483,12 +5483,12 @@
   std::vector<float> constant_data = {5, 6, 7, 8};
   GraphInfoBuilder builder;
   uint64_t input_a_operand_id =
-      builder.BuildInput("input_a", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_a", {2, 2}, OperandDataType::kFloat32);
   uint64_t input_b_operand_id =
-      builder.BuildConstant({2, 2}, mojom::DataType::kFloat32,
+      builder.BuildConstant({2, 2}, OperandDataType::kFloat32,
                             base::as_bytes(base::make_span(constant_data)));
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {2, 2}, OperandDataType::kFloat32);
   builder.BuildGemm(input_a_operand_id, input_b_operand_id, output_operand_id,
                     GemmAttributes());
 
@@ -5511,12 +5511,12 @@
   std::vector<float> constant_data = {5, 6, 7, 8};
   GraphInfoBuilder builder;
   uint64_t input_a_operand_id =
-      builder.BuildInput("input_a", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_a", {2, 2}, OperandDataType::kFloat32);
   uint64_t input_b_operand_id =
-      builder.BuildConstant({2, 2}, mojom::DataType::kFloat32,
+      builder.BuildConstant({2, 2}, OperandDataType::kFloat32,
                             base::as_bytes(base::make_span(constant_data)));
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {2, 2}, OperandDataType::kFloat32);
   builder.BuildGemm(input_a_operand_id, input_b_operand_id, output_operand_id,
                     GemmAttributes());
 
@@ -5710,10 +5710,10 @@
     // Test instanceNormalization with 4-D input with default scale and bias and
     // activation = relu.
     InstanceNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 1, 3},
                   .values = {1, 2, 3, 4, 5, 6}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 1, 3},
                    .values = {0, 0, 1.2247356859083902, 0, 0,
                               1.2247356859083902}}}
@@ -5728,10 +5728,10 @@
   {
     // Test instanceNormalization with 4-D input with default scale and bias.
     InstanceNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 1, 3},
                   .values = {1, 2, 3, 4, 5, 6}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 1, 3},
                    .values = {-1.2247356859083902, 0, 1.2247356859083902,
                               -1.2247356859083902, 0, 1.2247356859083902}}}
@@ -5741,16 +5741,16 @@
     // Test instanceNormalization with 4-D input with layout = nchw and
     // non-default scale and bias.
     InstanceNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 1, 3},
                   .values = {1, 2, 3, 4, 5, 6}},
-        .scale = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .scale = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                     .dimensions = {2},
                                     .values = {0.5, -0.5}},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {2},
                                    .values = {0.1, 0.2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 1, 3},
                    .values = {-0.5123678429541951, 0.1, 0.7123678429541951,
                               0.8123678429541952, 0.2, -0.4123678429541951}}}
@@ -5760,17 +5760,17 @@
     // Test instanceNormalization with 4-D input with layout = nhwc and
     // non-default scale and bias.
     InstanceNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 1, 3},
                   .values = {1, 2, 3, 4, 5, 6}},
-        .scale = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .scale = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                     .dimensions = {3},
                                     .values = {0.5, 1, -0.5}},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {3},
                                    .values = {0.1, 0.2, 0.3}},
         .attributes = {.layout = mojom::InputOperandLayout::kChannelsLast},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 1, 3},
                    .values = {-0.3999988888925926, -0.7999977777851852,
                               0.7999988888925926, 0.5999988888925926,
@@ -5781,14 +5781,14 @@
     // Test instanceNormalization with 4-D input with float16 data type, given
     // scale only.
     InstanceNormalizationTester<float16>{
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 2, 1, 3},
                   .values = Float16FromFloat32({1, 2, 3, 4, 5, 6})},
         .scale =
-            OperandInfo<float16>{.type = mojom::DataType::kFloat16,
+            OperandInfo<float16>{.type = OperandDataType::kFloat16,
                                  .dimensions = {2},
                                  .values = Float16FromFloat32({0.5, -0.5})},
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 2, 1, 3},
                    .values = Float16FromFloat32(
                        {-0.6123678429541951, 0, 0.6123678429541951,
@@ -5799,13 +5799,13 @@
     // Test instanceNormalization with 4-D input with float32 data type, given
     // bias only.
     InstanceNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 1, 3},
                   .values = {1, 2, 3, 4, 5, 6}},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {2},
                                    .values = {0.5, -0.5}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 1, 3},
                    .values = {-0.7247356859083902, 0.5, 1.7247356859083902,
                               -1.7247356859083902, -0.5, 0.7247356859083902}}}
@@ -5914,11 +5914,11 @@
     // Test layerNormalization with 1-D input with axes = [0] and default scale
     // and bias and activation = relu.
     LayerNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {5},
                   .values = {0, 1, 2, 3, 4}},
         .attributes = {.axes = {0}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {5},
                    .values = {0, 0, 0, 0.7071050134262237, 1.4142100268524473}}}
         .TestFusingStandaloneActivation(
@@ -5932,11 +5932,11 @@
   {
     // Test layerNormalization with a scalar input with default scale and bias.
     LayerNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {},
                   .values = {5}},
         .attributes = {.axes = {}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {},
                    .values = {0}}}
         .Test();
@@ -5945,11 +5945,11 @@
     // Test layerNormalization with 1-D input with axes = [0] and default scale
     // and bias.
     LayerNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {5},
                   .values = {0, 1, 2, 3, 4}},
         .attributes = {.axes = {0}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {5},
                    .values = {-1.4142100268524473, -0.7071050134262237, 0,
                               0.7071050134262237, 1.4142100268524473}}}
@@ -5959,11 +5959,11 @@
     // Test layerNormalization with 4-D input with axes = [1, 2, 3] and default
     // scale and bias.
     LayerNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 1, 3},
                   .values = {-1, 0, 1, 2, 3, 4}},
         .attributes = {.axes = {1, 2, 3}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 1, 3},
                    .values = {-1.4638475999719223, -0.8783085599831534,
                               -0.29276951999438444, 0.29276951999438444,
@@ -5973,17 +5973,17 @@
   {
     // Test layerNormalization with 4-D input with axes = [2, 3].
     LayerNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 1, 3},
                   .values = {-1, 0, 1, 2, 3, 4}},
-        .scale = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .scale = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                     .dimensions = {1, 3},
                                     .values = {0.5, 1, -0.5}},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {1, 3},
                                    .values = {0.1, 0.2, 0.3}},
         .attributes = {.axes = {2, 3}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 1, 3},
                    .values = {-0.5123678429541951, 0.2, -0.3123678429541951,
                               -0.5123678429541951, 0.2, -0.3123678429541951}}}
@@ -5993,11 +5993,11 @@
     // Test layerNormalization with 3-D input with axes = [0, 1, 2] and default
     // scale and bias.
     LayerNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 2, 2},
                   .values = {-4, -3, -2, -1, 1, 2, 3, 4}},
         .attributes = {.axes = {0, 1, 2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2, 2},
                    .values = {-1.4605925129524255, -1.0954443847143192,
                               -0.7302962564762128, -0.3651481282381064,
@@ -6008,17 +6008,17 @@
   {
     // Test layerNormalization with 6-D input with permuted axes = [4, 1, 2].
     LayerNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 1, 3, 2, 1},
                   .values = {-4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}},
-        .scale = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .scale = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                     .dimensions = {2, 2, 1},
                                     .values = {0.5, 0, 1, -0.5}},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {2, 2, 1},
                                    .values = {0.1, 0.2, 0.3, 0.4}},
         .attributes = {.axes = {4, 1, 2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 1, 3, 2, 1},
                    .values = {-0.47539614454389156, -0.5219944922055593,
                               -0.47539614454389156, -0.5219944922055593,
@@ -6031,15 +6031,15 @@
     // Test layerNormalization with 4-D input with axes = [1, 2, 3], float16
     // data type, given scale only.
     LayerNormalizationTester<float16>{
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 2, 1, 2},
                   .values = Float16FromFloat32({-2, -2, 2, 2})},
         .scale =
-            OperandInfo<float16>{.type = mojom::DataType::kFloat16,
+            OperandInfo<float16>{.type = OperandDataType::kFloat16,
                                  .dimensions = {2, 1, 2},
                                  .values = Float16FromFloat32({1, 1, 1, 1})},
         .attributes = {.axes = {1, 2, 3}, .epsilon = 0},
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 2, 1, 2},
                    .values = Float16FromFloat32({-1, -1, 1, 1})}}
         .Test();
@@ -6048,14 +6048,14 @@
     // Test layerNormalization with 4-D input with axes = [1, 2, 3], float32
     // data type, given bias only.
     LayerNormalizationTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 1, 3},
                   .values = {-1, 0, 1, 2, 3, 4}},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {2, 1, 3},
                                    .values = {0, 0.1, 0.2, 0.3, 0.4, 0.5}},
         .attributes = {.axes = {1, 2, 3}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 1, 3},
                    .values = {-1.4638475999719223, -0.7783085599831534,
                               -0.09276951999438444, 0.59276951999438444,
@@ -6190,13 +6190,13 @@
     uint32_t direction_count = 2;
     uint32_t hidden_size = 1;
     LstmTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size},
                   .values = {1, 2, 3, 4}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {direction_count, 4 * hidden_size, input_size},
                    .values = std::vector<float>(16, 1)},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {direction_count, 4 * hidden_size,
                                             hidden_size},
                              .values = std::vector<float>(8, 1)},
@@ -6209,10 +6209,10 @@
                              Activation{.kind = mojom::Activation::Tag::kLinear,
                                         .linear_alpha = 2,
                                         .linear_beta = 0}}},
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {direction_count, batch_size, hidden_size},
                      .values = {54, 686, 54, 686}},
-                    {.type = mojom::DataType::kFloat32,
+                    {.type = OperandDataType::kFloat32,
                      .dimensions = {direction_count, batch_size, hidden_size},
                      .values = {9, 49, 9, 49}}}}
         .Test();
@@ -6226,34 +6226,34 @@
     uint32_t direction_count = 1;
     uint32_t hidden_size = 1;
     LstmTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size},
                   .values = {-4, -3, -2, -1, 0, 1, 2, 3}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {direction_count, 4 * hidden_size, input_size},
                    .values = std::vector<float>(8, 1)},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {direction_count, 4 * hidden_size,
                                             hidden_size},
                              .values = std::vector<float>(4, 1)},
         .steps = steps,
         .hidden_size = hidden_size,
         .bias =
-            OperandInfo<float>{.type = mojom::DataType::kFloat32,
+            OperandInfo<float>{.type = OperandDataType::kFloat32,
                                .dimensions = {direction_count, 4 * hidden_size},
                                .values = std::vector<float>(4, 0.5)},
         .recurrent_bias =
-            OperandInfo<float>{.type = mojom::DataType::kFloat32,
+            OperandInfo<float>{.type = OperandDataType::kFloat32,
                                .dimensions = {direction_count, 4 * hidden_size},
                                .values = std::vector<float>(4, 0.5)},
         .attributes = {.activations =
                            {Activation{.kind = mojom::Activation::Tag::kRelu},
                             Activation{.kind = mojom::Activation::Tag::kRelu},
                             Activation{.kind = mojom::Activation::Tag::kRelu}}},
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {direction_count, batch_size, hidden_size},
                      .values = {8, 216}},
-                    {.type = mojom::DataType::kFloat32,
+                    {.type = OperandDataType::kFloat32,
                      .dimensions = {direction_count, batch_size, hidden_size},
                      .values = {4, 36}}}}
         .Test();
@@ -6267,34 +6267,34 @@
     uint32_t direction_count = 1;
     uint32_t hidden_size = 2;
     LstmTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size},
                   .values = {1, 2, 3, 4}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {direction_count, 4 * hidden_size, input_size},
                    .values = std::vector<float>(16, 1)},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {direction_count, 4 * hidden_size,
                                             hidden_size},
                              .values = std::vector<float>(16, 1)},
         .steps = steps,
         .hidden_size = hidden_size,
         .bias =
-            OperandInfo<float>{.type = mojom::DataType::kFloat32,
+            OperandInfo<float>{.type = OperandDataType::kFloat32,
                                .dimensions = {direction_count, 4 * hidden_size},
                                .values = std::vector<float>(8, 1)},
         .peephole_weight =
-            OperandInfo<float>{.type = mojom::DataType::kFloat32,
+            OperandInfo<float>{.type = OperandDataType::kFloat32,
                                .dimensions = {direction_count, 3 * hidden_size},
                                .values = std::vector<float>(6, 0)},
         .attributes = {.activations =
                            {Activation{.kind = mojom::Activation::Tag::kRelu},
                             Activation{.kind = mojom::Activation::Tag::kRelu},
                             Activation{.kind = mojom::Activation::Tag::kRelu}}},
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {direction_count, batch_size, hidden_size},
                      .values = {2811392, 2811392}},
-                    {.type = mojom::DataType::kFloat32,
+                    {.type = OperandDataType::kFloat32,
                      .dimensions = {direction_count, batch_size, hidden_size},
                      .values = {20672, 20672}}}}
         .Test();
@@ -6309,30 +6309,30 @@
     uint32_t direction_count = 1;
     uint32_t hidden_size = 2;
     LstmTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size},
                   .values = {0, 1}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {direction_count, 4 * hidden_size, input_size},
                    .values = std::vector<float>(8, 1)},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {direction_count, 4 * hidden_size,
                                             hidden_size},
                              .values = std::vector<float>(16, 1)},
         .steps = steps,
         .hidden_size = hidden_size,
         .recurrent_bias =
-            OperandInfo<float>{.type = mojom::DataType::kFloat32,
+            OperandInfo<float>{.type = OperandDataType::kFloat32,
                                .dimensions = {direction_count, 4 * hidden_size},
                                .values = std::vector<float>(8, 2)},
         .initial_hidden_state =
             OperandInfo<float>{
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {direction_count, batch_size, hidden_size},
                 .values = std::vector<float>(4, 1)},
         .initial_cell_state =
             OperandInfo<float>{
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {direction_count, batch_size, hidden_size},
                 .values = std::vector<float>(4, 0)},
         .attributes =
@@ -6346,13 +6346,13 @@
                              Activation{.kind = mojom::Activation::Tag::kLinear,
                                         .linear_alpha = 1,
                                         .linear_beta = 2}}},
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {direction_count, batch_size, hidden_size},
                      .values = {88, 88, 160, 160}},
-                    {.type = mojom::DataType::kFloat32,
+                    {.type = OperandDataType::kFloat32,
                      .dimensions = {direction_count, batch_size, hidden_size},
                      .values = {20, 20, 30, 30}},
-                    {.type = mojom::DataType::kFloat32,
+                    {.type = OperandDataType::kFloat32,
                      .dimensions = {steps, direction_count, batch_size,
                                     hidden_size},
                      .values = {88, 88, 160, 160}}}}
@@ -6375,26 +6375,26 @@
 
     GraphInfoBuilder builder;
     uint64_t input_operand_id = builder.BuildConstant(
-        {steps, batch_size, input_size}, mojom::DataType::kFloat32,
+        {steps, batch_size, input_size}, OperandDataType::kFloat32,
         base::as_bytes(base::make_span(input_data)));
     uint64_t weight_operand_id =
         builder.BuildConstant({direction_count, 4 * hidden_size, input_size},
-                              mojom::DataType::kFloat32,
+                              OperandDataType::kFloat32,
                               base::as_bytes(base::make_span(weight_data)));
     uint64_t recurrent_weight_operand_id = builder.BuildConstant(
         {direction_count, 4 * hidden_size, hidden_size},
-        mojom::DataType::kFloat32,
+        OperandDataType::kFloat32,
         base::as_bytes(base::make_span(recurrent_weight_data)));
 
     LstmTester<float>::LstmAttributes attributes;
     attributes.peephole_weight_operand_id = builder.BuildConstant(
-        {direction_count, 3 * hidden_size}, mojom::DataType::kFloat32,
+        {direction_count, 3 * hidden_size}, OperandDataType::kFloat32,
         base::as_bytes(base::make_span(peephole_weight_data)));
     attributes.initial_hidden_state_operand_id = builder.BuildConstant(
-        {direction_count, batch_size, hidden_size}, mojom::DataType::kFloat32,
+        {direction_count, batch_size, hidden_size}, OperandDataType::kFloat32,
         base::as_bytes(base::make_span(initial_hidden_state_data)));
     attributes.initial_cell_state_operand_id = builder.BuildConstant(
-        {direction_count, batch_size, hidden_size}, mojom::DataType::kFloat32,
+        {direction_count, batch_size, hidden_size}, OperandDataType::kFloat32,
         base::as_bytes(base::make_span(initial_cell_state_data)));
     attributes.activations = {
         Activation{.kind = mojom::Activation::Tag::kRelu},
@@ -6403,10 +6403,10 @@
 
     uint64_t output_a_operand_id = builder.BuildOutput(
         "output0", {direction_count, batch_size, hidden_size},
-        mojom::DataType::kFloat32);
+        OperandDataType::kFloat32);
     uint64_t output_b_operand_id = builder.BuildOutput(
         "output1", {direction_count, batch_size, hidden_size},
-        mojom::DataType::kFloat32);
+        OperandDataType::kFloat32);
     std::vector<uint64_t> output_operand_ids{output_a_operand_id,
                                              output_b_operand_id};
     builder.BuildLstm(input_operand_id, weight_operand_id,
@@ -6449,16 +6449,16 @@
 
   GraphInfoBuilder builder;
   uint64_t input_operand_id = builder.BuildInput(
-      "input", {batch_size, input_size}, mojom::DataType::kFloat32);
+      "input", {batch_size, input_size}, OperandDataType::kFloat32);
   uint64_t weight_operand_id = builder.BuildInput(
-      "weight", {4 * hidden_size, input_size}, mojom::DataType::kFloat32);
+      "weight", {4 * hidden_size, input_size}, OperandDataType::kFloat32);
   uint64_t recurrent_weight_operand_id =
       builder.BuildInput("recurrentWeight", {4 * hidden_size, hidden_size},
-                         mojom::DataType::kFloat32);
+                         OperandDataType::kFloat32);
   uint64_t hidden_state_operand_id = builder.BuildInput(
-      "hiddenState", {batch_size, hidden_size}, mojom::DataType::kFloat32);
+      "hiddenState", {batch_size, hidden_size}, OperandDataType::kFloat32);
   uint64_t cell_state_operand_id = builder.BuildInput(
-      "cellState", {batch_size, hidden_size}, mojom::DataType::kFloat32);
+      "cellState", {batch_size, hidden_size}, OperandDataType::kFloat32);
 
   LstmCellAttributes attributes;
   attributes.activations = {Activation{.kind = mojom::Activation::Tag::kRelu},
@@ -6466,9 +6466,9 @@
                             Activation{.kind = mojom::Activation::Tag::kRelu}};
 
   uint64_t output_a_operand_id = builder.BuildOutput(
-      "output0", {batch_size, hidden_size}, mojom::DataType::kFloat32);
+      "output0", {batch_size, hidden_size}, OperandDataType::kFloat32);
   uint64_t output_b_operand_id = builder.BuildOutput(
-      "output1", {batch_size, hidden_size}, mojom::DataType::kFloat32);
+      "output1", {batch_size, hidden_size}, OperandDataType::kFloat32);
   std::vector<uint64_t> output_operand_ids{output_a_operand_id,
                                            output_b_operand_id};
   builder.BuildLstmCell(input_operand_id, weight_operand_id,
@@ -6595,13 +6595,13 @@
   // Test matmul with fusible transpose for input a.
   {
     MatmulTester<float>{
-        .input_a = {.type = mojom::DataType::kFloat32,
+        .input_a = {.type = OperandDataType::kFloat32,
                     .dimensions = {1, 2, 3},
                     .values = {1, 2, 3, 4, 5, 6}},
-        .input_b = {.type = mojom::DataType::kFloat32,
+        .input_b = {.type = OperandDataType::kFloat32,
                     .dimensions = {1, 2, 3},
                     .values = {1, 2, 3, 4, 5, 6}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 3, 3},
                    .values = {17, 22, 27, 22, 29, 36, 27, 36, 45}}}
         .TestFusion(
@@ -6612,13 +6612,13 @@
 
   // Test matmul with fusible transpose for input b.
   {
-    MatmulTester<float>{.input_a = {.type = mojom::DataType::kFloat32,
+    MatmulTester<float>{.input_a = {.type = OperandDataType::kFloat32,
                                     .dimensions = {1, 2, 3},
                                     .values = {1, 2, 3, 4, 5, 6}},
-                        .input_b = {.type = mojom::DataType::kFloat32,
+                        .input_b = {.type = OperandDataType::kFloat32,
                                     .dimensions = {1, 2, 3},
                                     .values = {1, 2, 3, 4, 5, 6}},
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {1, 2, 2},
                                    .values = {14, 32, 32, 77}}}
         .TestFusion(
@@ -6629,13 +6629,13 @@
 
   // Test matmul with fusible transpose for both input a and b.
   {
-    MatmulTester<float>{.input_a = {.type = mojom::DataType::kFloat32,
+    MatmulTester<float>{.input_a = {.type = OperandDataType::kFloat32,
                                     .dimensions = {1, 3, 2},
                                     .values = {1, 2, 3, 4, 5, 6}},
-                        .input_b = {.type = mojom::DataType::kFloat32,
+                        .input_b = {.type = OperandDataType::kFloat32,
                                     .dimensions = {1, 2, 3},
                                     .values = {1, 2, 3, 4, 5, 6}},
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {1, 2, 2},
                                    .values = {22, 49, 28, 64}}}
         .TestFusion(
@@ -6647,13 +6647,13 @@
   // Test matmul with unfusible transpose for input a.
   {
     MatmulTester<float>{
-        .input_a = {.type = mojom::DataType::kFloat32,
+        .input_a = {.type = OperandDataType::kFloat32,
                     .dimensions = {2, 3, 1},
                     .values = {1, 2, 3, 4, 5, 6}},
-        .input_b = {.type = mojom::DataType::kFloat32,
+        .input_b = {.type = OperandDataType::kFloat32,
                     .dimensions = {1, 2, 3},
                     .values = {1, 2, 3, 4, 5, 6}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 3, 3},
                    .values = {17, 22, 27, 22, 29, 36, 27, 36, 45}}}
         .TestFusion(
@@ -6663,13 +6663,13 @@
 
   // Test matmul with 2-D * 2-D inputs, activation = linear.
   {
-    MatmulTester<float>{.input_a = {.type = mojom::DataType::kFloat32,
+    MatmulTester<float>{.input_a = {.type = OperandDataType::kFloat32,
                                     .dimensions = {2, 2},
                                     .values = {1, 2, 3, 4}},
-                        .input_b = {.type = mojom::DataType::kFloat32,
+                        .input_b = {.type = OperandDataType::kFloat32,
                                     .dimensions = {2, 2},
                                     .values = {1, 2, 3, 4}},
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {2, 2},
                                    .values = {71, 101, 151, 221}}}
         .TestFusion(
@@ -6682,13 +6682,13 @@
 
   // Test matmul that can fuse transpose a, b and linear.
   {
-    MatmulTester<float>{.input_a = {.type = mojom::DataType::kFloat32,
+    MatmulTester<float>{.input_a = {.type = OperandDataType::kFloat32,
                                     .dimensions = {1, 3, 2},
                                     .values = {1, 2, 3, 4, 5, 6}},
-                        .input_b = {.type = mojom::DataType::kFloat32,
+                        .input_b = {.type = OperandDataType::kFloat32,
                                     .dimensions = {1, 2, 3},
                                     .values = {1, 2, 3, 4, 5, 6}},
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {1, 2, 2},
                                    .values = {221, 491, 281, 641}}}
         .TestFusion(
@@ -6705,39 +6705,39 @@
 TEST_F(WebNNGraphImplBackendTest, BuildAndComputeSingleOperatorMatmul) {
   // Test matmul with 2-D * 2-D inputs.
   {
-    MatmulTester<float>{.input_a = {.type = mojom::DataType::kFloat32,
+    MatmulTester<float>{.input_a = {.type = OperandDataType::kFloat32,
                                     .dimensions = {2, 2},
                                     .values = {1, 2, 3, 4}},
-                        .input_b = {.type = mojom::DataType::kFloat32,
+                        .input_b = {.type = OperandDataType::kFloat32,
                                     .dimensions = {2, 2},
                                     .values = {1, 2, 3, 4}},
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {2, 2},
                                    .values = {7, 10, 15, 22}}}
         .Test();
   }
   // Test matmul with 3-D * 3-D inputs using broadcasting.
   {
-    MatmulTester<float>{.input_a = {.type = mojom::DataType::kFloat32,
+    MatmulTester<float>{.input_a = {.type = OperandDataType::kFloat32,
                                     .dimensions = {1, 2, 3},
                                     .values = {1, 2, 3, 4, 5, 6}},
-                        .input_b = {.type = mojom::DataType::kFloat32,
+                        .input_b = {.type = OperandDataType::kFloat32,
                                     .dimensions = {2, 3, 1},
                                     .values = {1, 2, 3, 4, 5, 6}},
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {2, 2, 1},
                                    .values = {14, 32, 32, 77}}}
         .Test();
   }
   // Test matmul with 2-D * 3-D inputs using broadcasting.
   {
-    MatmulTester<float>{.input_a = {.type = mojom::DataType::kFloat32,
+    MatmulTester<float>{.input_a = {.type = OperandDataType::kFloat32,
                                     .dimensions = {2, 3},
                                     .values = {1, 2, 3, 4, 5, 6}},
-                        .input_b = {.type = mojom::DataType::kFloat32,
+                        .input_b = {.type = OperandDataType::kFloat32,
                                     .dimensions = {2, 3, 1},
                                     .values = {1, 2, 3, 4, 5, 6}},
-                        .output = {.type = mojom::DataType::kFloat32,
+                        .output = {.type = OperandDataType::kFloat32,
                                    .dimensions = {2, 2, 1},
                                    .values = {14, 32, 32, 77}}}
         .Test();
@@ -6745,13 +6745,13 @@
   // Test matmul with 3-D * 4-D inputs using broadcasting.
   {
     MatmulTester<float>{
-        .input_a = {.type = mojom::DataType::kFloat32,
+        .input_a = {.type = OperandDataType::kFloat32,
                     .dimensions = {2, 2, 3},
                     .values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}},
-        .input_b = {.type = mojom::DataType::kFloat32,
+        .input_b = {.type = OperandDataType::kFloat32,
                     .dimensions = {2, 1, 3, 1},
                     .values = {1, 2, 3, 4, 5, 6}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2, 2, 1},
                    .values = {14, 32, 50, 68, 32, 77, 122, 167}}}
         .Test();
@@ -6759,13 +6759,13 @@
   // Test matmul with 4-D * 4-D inputs.
   {
     MatmulTester<float>{
-        .input_a = {.type = mojom::DataType::kFloat32,
+        .input_a = {.type = OperandDataType::kFloat32,
                     .dimensions = {2, 1, 2, 3},
                     .values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}},
-        .input_b = {.type = mojom::DataType::kFloat32,
+        .input_b = {.type = OperandDataType::kFloat32,
                     .dimensions = {2, 1, 3, 1},
                     .values = {1, 2, 3, 4, 5, 6}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 1, 2, 1},
                    .values = {14, 32, 122, 167}}}
         .Test();
@@ -6783,28 +6783,28 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_a_operand_id =
-      builder.BuildInput("input_a", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_a", {2, 2}, OperandDataType::kFloat32);
   uint64_t input_b_operand_id =
-      builder.BuildInput("input_b", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_b", {2, 2}, OperandDataType::kFloat32);
   std::vector<float> constant_data = {1, 1, 1, 1};
   uint64_t constant_a_operand_id =
-      builder.BuildConstant({2, 2}, mojom::DataType::kFloat32,
+      builder.BuildConstant({2, 2}, OperandDataType::kFloat32,
                             base::as_bytes(base::make_span(constant_data)));
   uint64_t constant_b_operand_id =
-      builder.BuildConstant({2, 2}, mojom::DataType::kFloat32,
+      builder.BuildConstant({2, 2}, OperandDataType::kFloat32,
                             base::as_bytes(base::make_span(constant_data)));
 
   // The order of inputs are [input_a, constant_a, input_b, constant_b].
   uint64_t intermediate_1_operand_id =
-      builder.BuildIntermediateOperand({2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({2, 2}, OperandDataType::kFloat32);
   builder.BuildGemm(input_a_operand_id, constant_a_operand_id,
                     intermediate_1_operand_id, GemmAttributes());
   uint64_t intermediate_2_operand_id =
-      builder.BuildIntermediateOperand({2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({2, 2}, OperandDataType::kFloat32);
   builder.BuildGemm(input_b_operand_id, constant_b_operand_id,
                     intermediate_2_operand_id, GemmAttributes());
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {2, 2}, OperandDataType::kFloat32);
   builder.BuildGemm(intermediate_1_operand_id, intermediate_2_operand_id,
                     output_operand_id, GemmAttributes());
 
@@ -6832,28 +6832,28 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_a_operand_id =
-      builder.BuildInput("input_a", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_a", {2, 2}, OperandDataType::kFloat32);
   uint64_t input_b_operand_id =
-      builder.BuildInput("input_b", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_b", {2, 2}, OperandDataType::kFloat32);
   std::vector<float> constant_data = {1, 2, 3, 4};
   uint64_t constant_a_operand_id =
-      builder.BuildConstant({2, 2}, mojom::DataType::kFloat32,
+      builder.BuildConstant({2, 2}, OperandDataType::kFloat32,
                             base::as_bytes(base::make_span(constant_data)));
   uint64_t constant_b_operand_id =
-      builder.BuildConstant({2, 2}, mojom::DataType::kFloat32,
+      builder.BuildConstant({2, 2}, OperandDataType::kFloat32,
                             base::as_bytes(base::make_span(constant_data)));
 
   // The order of inputs are [constant_a, input_a, constant_b, input_b].
   uint64_t intermediate_1_operand_id =
-      builder.BuildIntermediateOperand({2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({2, 2}, OperandDataType::kFloat32);
   builder.BuildGemm(constant_a_operand_id, input_a_operand_id,
                     intermediate_1_operand_id, GemmAttributes());
   uint64_t intermediate_2_operand_id =
-      builder.BuildIntermediateOperand({2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({2, 2}, OperandDataType::kFloat32);
   builder.BuildGemm(constant_b_operand_id, input_b_operand_id,
                     intermediate_2_operand_id, GemmAttributes());
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {2, 2}, OperandDataType::kFloat32);
   builder.BuildGemm(intermediate_1_operand_id, intermediate_2_operand_id,
                     output_operand_id, GemmAttributes());
 
@@ -6884,21 +6884,21 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_a_operand_id =
-      builder.BuildInput("input_a", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_a", {2, 2}, OperandDataType::kFloat32);
   uint64_t input_b_operand_id =
-      builder.BuildInput("input_b", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_b", {2, 2}, OperandDataType::kFloat32);
   std::vector<float> constant_data = {1, 1};
   uint64_t constant_c_operand_id =
-      builder.BuildConstant({2}, mojom::DataType::kFloat32,
+      builder.BuildConstant({2}, OperandDataType::kFloat32,
                             base::as_bytes(base::make_span(constant_data)));
   // Reshape constant_c from [2] to [1, 2] and use it as operand c for gemm.
   uint64_t reshape_operand_id =
-      builder.BuildIntermediateOperand({1, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({1, 2}, OperandDataType::kFloat32);
   builder.BuildReshape(constant_c_operand_id, reshape_operand_id);
   GemmAttributes gemm_attributes;
   gemm_attributes.c_operand_id = reshape_operand_id;
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {2, 2}, OperandDataType::kFloat32);
   builder.BuildGemm(input_a_operand_id, input_b_operand_id, output_operand_id,
                     gemm_attributes);
 
@@ -6926,17 +6926,17 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_a_operand_id =
-      builder.BuildInput("input_a", {1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_a", {1, 1, 2, 2}, OperandDataType::kFloat32);
   std::vector<float> constant_data = {1, 1};
   uint64_t constant_b_operand_id =
-      builder.BuildConstant({2}, mojom::DataType::kFloat32,
+      builder.BuildConstant({2}, OperandDataType::kFloat32,
                             base::as_bytes(base::make_span(constant_data)));
   // Reshape constant_b from [2] to [1, 2] and use it as operand b for add.
   uint64_t reshape_operand_id =
-      builder.BuildIntermediateOperand({1, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({1, 2}, OperandDataType::kFloat32);
   builder.BuildReshape(constant_b_operand_id, reshape_operand_id);
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {1, 1, 2, 2}, OperandDataType::kFloat32);
   builder.BuildElementWiseBinary(mojom::ElementWiseBinary::Kind::kAdd,
                                  input_a_operand_id, reshape_operand_id,
                                  output_operand_id);
@@ -6961,10 +6961,10 @@
   GraphInfoBuilder builder;
   std::vector<float> constant_data = {-1, 0, 1};
   uint64_t constant_operand_id =
-      builder.BuildConstant({3}, mojom::DataType::kFloat32,
+      builder.BuildConstant({3}, OperandDataType::kFloat32,
                             base::as_bytes(base::make_span(constant_data)));
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {3}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {3}, OperandDataType::kFloat32);
   builder.BuildRelu(constant_operand_id, output_operand_id);
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -6985,14 +6985,14 @@
   GraphInfoBuilder builder;
   std::vector<float> constant_a_data = {1, 1, 1, 1};
   uint64_t constant_a_operand_id =
-      builder.BuildConstant({2, 2}, mojom::DataType::kFloat32,
+      builder.BuildConstant({2, 2}, OperandDataType::kFloat32,
                             base::as_bytes(base::make_span(constant_a_data)));
   std::vector<float> constant_b_data = {2, 2, 2, 2};
   uint64_t constant_b_operand_id =
-      builder.BuildConstant({2, 2}, mojom::DataType::kFloat32,
+      builder.BuildConstant({2, 2}, OperandDataType::kFloat32,
                             base::as_bytes(base::make_span(constant_b_data)));
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {2, 2}, OperandDataType::kFloat32);
   builder.BuildElementWiseBinary(mojom::ElementWiseBinary::Kind::kAdd,
                                  constant_a_operand_id, constant_b_operand_id,
                                  output_operand_id);
@@ -7018,23 +7018,23 @@
   GraphInfoBuilder builder;
   std::vector<float> constant_a_data = {1, 1, 1, 1};
   uint64_t constant_a_operand_id =
-      builder.BuildConstant({2, 2}, mojom::DataType::kFloat32,
+      builder.BuildConstant({2, 2}, OperandDataType::kFloat32,
                             base::as_bytes(base::make_span(constant_a_data)));
   std::vector<float> constant_b_data = {2, 2, 2, 2};
   uint64_t constant_b_operand_id =
-      builder.BuildConstant({2, 2}, mojom::DataType::kFloat32,
+      builder.BuildConstant({2, 2}, OperandDataType::kFloat32,
                             base::as_bytes(base::make_span(constant_b_data)));
   uint64_t intermediate_operand_id =
-      builder.BuildIntermediateOperand({2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({2, 2}, OperandDataType::kFloat32);
   builder.BuildElementWiseBinary(mojom::ElementWiseBinary::Kind::kAdd,
                                  constant_a_operand_id, constant_b_operand_id,
                                  intermediate_operand_id);
   std::vector<float> constant_c_data = {3, 3, 3, 3};
   uint64_t constant_c_operand_id =
-      builder.BuildConstant({2, 2}, mojom::DataType::kFloat32,
+      builder.BuildConstant({2, 2}, OperandDataType::kFloat32,
                             base::as_bytes(base::make_span(constant_c_data)));
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {2, 2}, OperandDataType::kFloat32);
   builder.BuildElementWiseBinary(mojom::ElementWiseBinary::Kind::kMul,
                                  intermediate_operand_id, constant_c_operand_id,
                                  output_operand_id);
@@ -7059,23 +7059,23 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_a_operand_id =
-      builder.BuildInput("input_a", {1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_a", {1, 1, 2, 2}, OperandDataType::kFloat32);
   uint64_t input_b_operand_id =
-      builder.BuildInput("input_b", {1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_b", {1, 1, 2, 2}, OperandDataType::kFloat32);
   uint64_t intermediate_1_operand_id =
-      builder.BuildIntermediateOperand({1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({1, 1, 2, 2}, OperandDataType::kFloat32);
   builder.BuildElementWiseBinary(mojom::ElementWiseBinary::Kind::kAdd,
                                  input_a_operand_id, input_b_operand_id,
                                  intermediate_1_operand_id);
 
   // Relu.
   uint64_t intermediate_2_operand_id =
-      builder.BuildIntermediateOperand({1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({1, 1, 2, 2}, OperandDataType::kFloat32);
   builder.BuildRelu(intermediate_1_operand_id, intermediate_2_operand_id);
 
   // Max pooling.
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {1, 1, 2, 2}, OperandDataType::kFloat32);
   builder.BuildPool2d(
       mojom::Pool2d::Kind::kMaxPool2d, intermediate_2_operand_id,
       output_operand_id,
@@ -7108,18 +7108,18 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_a_operand_id =
-      builder.BuildInput("input_a", {1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_a", {1, 1, 2, 2}, OperandDataType::kFloat32);
   uint64_t input_b_operand_id =
-      builder.BuildInput("input_b", {1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_b", {1, 1, 2, 2}, OperandDataType::kFloat32);
   uint64_t intermediate_1_operand_id =
-      builder.BuildIntermediateOperand({1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({1, 1, 2, 2}, OperandDataType::kFloat32);
   builder.BuildElementWiseBinary(mojom::ElementWiseBinary::Kind::kAdd,
                                  input_a_operand_id, input_b_operand_id,
                                  intermediate_1_operand_id);
 
   // Max pooling.
   uint64_t intermediate_2_operand_id =
-      builder.BuildIntermediateOperand({1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({1, 1, 2, 2}, OperandDataType::kFloat32);
   builder.BuildPool2d(
       mojom::Pool2d::Kind::kMaxPool2d, intermediate_1_operand_id,
       intermediate_2_operand_id,
@@ -7131,7 +7131,7 @@
 
   // Relu.
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {1, 1, 2, 2}, OperandDataType::kFloat32);
   builder.BuildRelu(intermediate_2_operand_id, output_operand_id);
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -7158,9 +7158,9 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_a_operand_id =
-      builder.BuildInput("input_a", {1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_a", {1, 1, 2, 2}, OperandDataType::kFloat32);
   uint64_t intermediate_1_operand_id =
-      builder.BuildIntermediateOperand({1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({1, 1, 2, 2}, OperandDataType::kFloat32);
   builder.BuildPool2d(
       mojom::Pool2d::Kind::kMaxPool2d, input_a_operand_id,
       intermediate_1_operand_id,
@@ -7172,16 +7172,16 @@
 
   // Add operation.
   uint64_t input_b_operand_id =
-      builder.BuildInput("input_b", {1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_b", {1, 1, 2, 2}, OperandDataType::kFloat32);
   uint64_t intermediate_2_operand_id =
-      builder.BuildIntermediateOperand({1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({1, 1, 2, 2}, OperandDataType::kFloat32);
   builder.BuildElementWiseBinary(mojom::ElementWiseBinary::Kind::kAdd,
                                  intermediate_1_operand_id, input_b_operand_id,
                                  intermediate_2_operand_id);
 
   // Relu.
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {1, 1, 2, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {1, 1, 2, 2}, OperandDataType::kFloat32);
   builder.BuildRelu(intermediate_2_operand_id, output_operand_id);
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -7206,13 +7206,13 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_operand_id1 =
-      builder.BuildInput("input_a", {1, 1, 2, 3}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_a", {1, 1, 2, 3}, OperandDataType::kFloat32);
   uint64_t input_operand_id2 =
-      builder.BuildInput("input_b", {1, 1, 2, 3}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_b", {1, 1, 2, 3}, OperandDataType::kFloat32);
   uint64_t input_operand_id3 =
-      builder.BuildInput("input_c", {1, 2, 2, 3}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_c", {1, 2, 2, 3}, OperandDataType::kFloat32);
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {1, 4, 2, 3}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {1, 4, 2, 3}, OperandDataType::kFloat32);
   builder.BuildConcat({input_operand_id1, input_operand_id2, input_operand_id3},
                       output_operand_id, 1);
 
@@ -7261,21 +7261,21 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_operand_id1 =
-      builder.BuildInput("input_a", {4, 3}, mojom::DataType::kFloat16);
+      builder.BuildInput("input_a", {4, 3}, OperandDataType::kFloat16);
   uint64_t input_operand_id2 =
-      builder.BuildInput("input_b", {1, 1, 2, 3}, mojom::DataType::kFloat16);
+      builder.BuildInput("input_b", {1, 1, 2, 3}, OperandDataType::kFloat16);
 
   uint64_t reshape_operand_id =
-      builder.BuildIntermediateOperand({1, 2, 2, 3}, mojom::DataType::kFloat16);
+      builder.BuildIntermediateOperand({1, 2, 2, 3}, OperandDataType::kFloat16);
   builder.BuildReshape(input_operand_id1, reshape_operand_id);
 
   uint64_t concat_operand_id =
-      builder.BuildIntermediateOperand({1, 3, 2, 3}, mojom::DataType::kFloat16);
+      builder.BuildIntermediateOperand({1, 3, 2, 3}, OperandDataType::kFloat16);
   builder.BuildConcat({reshape_operand_id, input_operand_id2},
                       concat_operand_id, 1);
 
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {1, 3, 2, 3}, mojom::DataType::kFloat16);
+      builder.BuildOutput("output", {1, 3, 2, 3}, OperandDataType::kFloat16);
   builder.BuildClamp(concat_operand_id, output_operand_id, 1.25, 8.75);
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -7304,7 +7304,7 @@
   //   [[1.25 1.25 1.25]
   //    [1.25 1.25 1.25]]]] with shape (1, 3, 2, 3)
   EXPECT_EQ(GetFloatOutputData(std::move(named_outputs["output"]),
-                               mojom::DataType::kFloat16),
+                               OperandDataType::kFloat16),
             std::vector<float>({1.25, 2, 3, 4, 5, 6, 7, 8, 8.75, 8.75, 8.75,
                                 8.75, 1.25, 1.25, 1.25, 1.25, 1.25, 1.25}));
 }
@@ -7325,28 +7325,28 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_operand_id =
-      builder.BuildInput("input", {1, 1, 1, 3}, mojom::DataType::kFloat32);
+      builder.BuildInput("input", {1, 1, 1, 3}, OperandDataType::kFloat32);
 
   // [[[[1 2 3]]]] with shape (1, 1, 1, 3)
   std::vector<float> constant_data_a = {1, 2, 3};
   uint64_t constant_a_operand_id =
-      builder.BuildConstant({1, 1, 1, 3}, mojom::DataType::kFloat32,
+      builder.BuildConstant({1, 1, 1, 3}, OperandDataType::kFloat32,
                             base::as_bytes(base::make_span(constant_data_a)));
 
   // [[[[-1 -2 -3]
   //    [-4 -5 -6]]]] with shape (1, 1, 2, 3)
   std::vector<float> constant_data_b = {-1, -2, -3, -4, -5, -6};
   uint64_t constant_b_operand_id =
-      builder.BuildConstant({1, 1, 2, 3}, mojom::DataType::kFloat32,
+      builder.BuildConstant({1, 1, 2, 3}, OperandDataType::kFloat32,
                             base::as_bytes(base::make_span(constant_data_b)));
 
   uint64_t concat_operand_id =
-      builder.BuildIntermediateOperand({1, 1, 2, 3}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({1, 1, 2, 3}, OperandDataType::kFloat32);
   builder.BuildConcat({input_operand_id, constant_a_operand_id},
                       concat_operand_id, 2);
 
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {1, 2, 2, 3}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {1, 2, 2, 3}, OperandDataType::kFloat32);
   builder.BuildConcat({concat_operand_id, constant_b_operand_id},
                       output_operand_id, 1);
 
@@ -7407,12 +7407,12 @@
   // Test resample2d with "NearestNeighbor" mode and axes = [2, 3].
   {
     Resample2dTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 2, 2},
                   // [[[[1 2]
                   //    [3 4]]]] with shape (1, 1, 2, 2)
                   .values = {1, 2, 3, 4}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 4, 6},
                    // [[[[1 1 1 2 2 2]
                    //    [1 1 1 2 2 2]
@@ -7426,13 +7426,13 @@
   // axes = [2, 3].
   {
     Resample2dTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 2, 2},
                   // [[[[1 2]
                   //    [3 4]]]] with shape (1, 1, 2, 2)
                   .values = {1, 2, 3, 4}},
         .attributes = {.scales = std::vector<float>{2, 3}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 4, 6},
                    // [[[[1 1 1 2 2 2]
                    //    [1 1 1 2 2 2]
@@ -7445,13 +7445,13 @@
   // Test resample2d with "NearestNeighbor" mode and axes = [1, 2].
   {
     Resample2dTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 2, 1},
                   // [[[[1] [2]]
                   //   [[3] [4]]]] with shape (1, 2, 2, 1)
                   .values = {1, 2, 3, 4}},
         .attributes = {.axes = {1, 2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 4, 6, 1},
                    // [[[[1] [1] [1] [2] [2] [2]]
                    //   [[1] [1] [1] [2] [2] [2]]
@@ -7464,13 +7464,13 @@
   // Test resample2d with "Linear" mode and axes = [2, 3].
   {
     Resample2dTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 2, 2},
                   // [[[[1 2]
                   //    [3 4]]]] with shape (1, 1, 2, 2)
                   .values = {1, 2, 3, 4}},
         .attributes = {.mode = mojom::Resample2d::InterpolationMode::kLinear},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 4, 4},
                    // [[[[1   1.25 1.75 2  ]
                    //    [1.5 1.75 2.25 2.5]
@@ -7484,12 +7484,12 @@
   // larger but not divisible to input sizes.
   {
     Resample2dTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 2, 3},
                   // [[[[1 2 3]
                   //    [4 5 6]]]] with shape (1, 1, 2, 3)
                   .values = {1, 2, 3, 4, 5, 6}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 4, 5},
                    // [[[[1 1 2 3 3]
                    //    [1 1 2 3 3]
@@ -7502,13 +7502,13 @@
   // Test resample2d with "NearestNeighbor" mode , axes = [2, 3] and output
   // sizes smaller than input sizes.
   {
-    Resample2dTester<float>{.input = {.type = mojom::DataType::kFloat32,
+    Resample2dTester<float>{.input = {.type = OperandDataType::kFloat32,
                                       .dimensions = {1, 1, 3, 3},
                                       // [[[[1 2 3]
                                       //    [4 5 6]
                                       //    [7 8 9]]]] with shape (1, 1, 3, 3)
                                       .values = {1, 2, 3, 4, 5, 6, 7, 8, 9}},
-                            .output = {.type = mojom::DataType::kFloat32,
+                            .output = {.type = OperandDataType::kFloat32,
                                        .dimensions = {1, 1, 2, 2},
                                        // [[[[1 3]
                                        //    [7 9]]]] with shape (1, 1, 2, 2)
@@ -7519,14 +7519,14 @@
   // than input sizes.
   {
     Resample2dTester<float>{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 3, 3},
                   // [[[[1 2 3]
                   //    [4 5 6]
                   //    [7 8 9]]]] with shape (1, 1, 3, 3)
                   .values = {1, 2, 3, 4, 5, 6, 7, 8, 9}},
         .attributes = {.mode = mojom::Resample2d::InterpolationMode::kLinear},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 2, 2},
                    // [[[[2   3.5]
                    //    [6.5 8  ]]]] with shape (1, 1, 2, 2)
@@ -7540,9 +7540,9 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_operand_id =
-      builder.BuildInput("input", {2, 3}, mojom::DataType::kFloat32);
+      builder.BuildInput("input", {2, 3}, OperandDataType::kFloat32);
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {3, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {3, 2}, OperandDataType::kFloat32);
 
   builder.BuildTranspose(input_operand_id, output_operand_id, {1, 0});
 
@@ -7568,14 +7568,14 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_operand_id =
-      builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
 
   uint64_t transpose_operand_id =
-      builder.BuildIntermediateOperand({2, 1, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({2, 1, 3, 4}, OperandDataType::kFloat32);
   builder.BuildTranspose(input_operand_id, transpose_operand_id, {1, 0, 2, 3});
 
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {4, 3, 1, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {4, 3, 1, 2}, OperandDataType::kFloat32);
   builder.BuildTranspose(transpose_operand_id, output_operand_id, {3, 2, 1, 0});
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -7622,14 +7622,14 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_operand_id =
-      builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
 
   uint64_t transpose_operand_id =
-      builder.BuildIntermediateOperand({4, 3, 1, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({4, 3, 1, 2}, OperandDataType::kFloat32);
   builder.BuildTranspose(input_operand_id, transpose_operand_id, {3, 2, 0, 1});
 
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {4, 3, 1, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {4, 3, 1, 2}, OperandDataType::kFloat32);
   builder.BuildRelu(transpose_operand_id, output_operand_id);
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -7679,22 +7679,22 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_operand_id =
-      builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+      builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
 
   uint64_t transpose_operand_id =
-      builder.BuildIntermediateOperand({4, 3, 1, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({4, 3, 1, 2}, OperandDataType::kFloat32);
   builder.BuildTranspose(input_operand_id, transpose_operand_id, {3, 2, 0, 1});
 
   uint64_t reshape_operand_id1 =
-      builder.BuildIntermediateOperand({2, 2, 6}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({2, 2, 6}, OperandDataType::kFloat32);
   builder.BuildReshape(transpose_operand_id, reshape_operand_id1);
 
   uint64_t reshape_operand_id2 =
-      builder.BuildIntermediateOperand({12, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({12, 2}, OperandDataType::kFloat32);
   builder.BuildReshape(reshape_operand_id1, reshape_operand_id2);
 
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {2, 12}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {2, 12}, OperandDataType::kFloat32);
   builder.BuildTranspose(reshape_operand_id2, output_operand_id, {1, 0});
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -7734,15 +7734,15 @@
   // Build the mojom graph info.
   GraphInfoBuilder builder;
   uint64_t input_operand_id =
-      builder.BuildInput("input", {1, 2, 3, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input", {1, 2, 3, 2}, OperandDataType::kFloat32);
   uint64_t relu_operand_id =
-      builder.BuildIntermediateOperand({1, 2, 3, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({1, 2, 3, 2}, OperandDataType::kFloat32);
   builder.BuildRelu(input_operand_id, relu_operand_id);
 
   uint64_t output1_operand_id =
-      builder.BuildOutput("output1", {3, 4}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output1", {3, 4}, OperandDataType::kFloat32);
   uint64_t output2_operand_id =
-      builder.BuildOutput("output2", {1, 2, 2, 3}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output2", {1, 2, 2, 3}, OperandDataType::kFloat32);
   builder.BuildReshape(relu_operand_id, output1_operand_id);
   builder.BuildTranspose(relu_operand_id, output2_operand_id, {0, 3, 1, 2});
 
@@ -7810,16 +7810,16 @@
 TEST_F(WebNNGraphImplBackendTest, BuildAndComputeSingleOperatorWhere) {
   // Test where with 2-D condition, 2-D true_value and 2-D false_value.
   {
-    WhereTester<float>{.condition = {.type = mojom::DataType::kUint8,
+    WhereTester<float>{.condition = {.type = OperandDataType::kUint8,
                                      .dimensions = {2, 3},
                                      .values = {1, 1, 0, 0, 1, 0}},
-                       .true_value = {.type = mojom::DataType::kFloat32,
+                       .true_value = {.type = OperandDataType::kFloat32,
                                       .dimensions = {2, 3},
                                       .values = {1, 2, 3, 4, 5, 64}},
-                       .false_value = {.type = mojom::DataType::kFloat32,
+                       .false_value = {.type = OperandDataType::kFloat32,
                                        .dimensions = {2, 3},
                                        .values = {6, 3, 5, 7, 8, 0}},
-                       .output = {.type = mojom::DataType::kFloat32,
+                       .output = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {1, 2, 5, 7, 5, 0}}}
         .Test();
@@ -7827,16 +7827,16 @@
   // Test where with 1-D condition, 2-D true_value and 2-D false_value using
   // broadcast.
   {
-    WhereTester<float>{.condition = {.type = mojom::DataType::kUint8,
+    WhereTester<float>{.condition = {.type = OperandDataType::kUint8,
                                      .dimensions = {3},
                                      .values = {1, 1, 0}},
-                       .true_value = {.type = mojom::DataType::kFloat32,
+                       .true_value = {.type = OperandDataType::kFloat32,
                                       .dimensions = {2, 3},
                                       .values = {1, 2, 3, 4, 5, 64}},
-                       .false_value = {.type = mojom::DataType::kFloat32,
+                       .false_value = {.type = OperandDataType::kFloat32,
                                        .dimensions = {2, 3},
                                        .values = {7, 8, 9, 10, 11, 12}},
-                       .output = {.type = mojom::DataType::kFloat32,
+                       .output = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {1, 2, 9, 4, 5, 12}}}
         .Test();
@@ -7844,16 +7844,16 @@
   // Test where with 2-D condition, 2-D true_value and 1-D false_value using
   // broadcast.
   {
-    WhereTester<float>{.condition = {.type = mojom::DataType::kUint8,
+    WhereTester<float>{.condition = {.type = OperandDataType::kUint8,
                                      .dimensions = {2, 3},
                                      .values = {1, 1, 0, 0, 0, 1}},
-                       .true_value = {.type = mojom::DataType::kFloat32,
+                       .true_value = {.type = OperandDataType::kFloat32,
                                       .dimensions = {2, 3},
                                       .values = {1, 2, 3, 4, 5, 64}},
-                       .false_value = {.type = mojom::DataType::kFloat32,
+                       .false_value = {.type = OperandDataType::kFloat32,
                                        .dimensions = {3},
                                        .values = {7, 8, 9}},
-                       .output = {.type = mojom::DataType::kFloat32,
+                       .output = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {1, 2, 9, 7, 8, 64}}}
         .Test();
@@ -7862,17 +7862,17 @@
   // broadcast.
   {
     WhereTester<float>{
-        .condition = {.type = mojom::DataType::kUint8,
+        .condition = {.type = OperandDataType::kUint8,
                       .dimensions = {3},
                       .values = {1, 1, 0}},
-        .true_value = {.type = mojom::DataType::kFloat32,
+        .true_value = {.type = OperandDataType::kFloat32,
                        .dimensions = {2, 3},
                        .values = {1, 2, 3, 4, 5, 64}},
-        .false_value = {.type = mojom::DataType::kFloat32,
+        .false_value = {.type = OperandDataType::kFloat32,
                         .dimensions = {2, 2, 3},
                         .values = {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
                                    18}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2, 3},
                    .values = {1, 2, 9, 4, 5, 12, 1, 2, 15, 4, 5, 18}}}
         .Test();
@@ -7881,16 +7881,16 @@
   // broadcast.
   {
     WhereTester<float>{
-        .condition = {.type = mojom::DataType::kUint8,
+        .condition = {.type = OperandDataType::kUint8,
                       .dimensions = {2, 2, 3},
                       .values = {1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0}},
-        .true_value = {.type = mojom::DataType::kFloat32,
+        .true_value = {.type = OperandDataType::kFloat32,
                        .dimensions = {2, 3},
                        .values = {1, 2, 3, 4, 5, 64}},
-        .false_value = {.type = mojom::DataType::kFloat32,
+        .false_value = {.type = OperandDataType::kFloat32,
                         .dimensions = {3},
                         .values = {7, 8, 9}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 2, 3},
                    .values = {1, 2, 9, 4, 5, 9, 1, 2, 9, 4, 5, 9}}}
         .Test();
@@ -7898,16 +7898,16 @@
   // Test where with 2-D condition, 2-D true_value and 2-D false_value, and
   // condition value !=0 should be true.
   {
-    WhereTester<float>{.condition = {.type = mojom::DataType::kUint8,
+    WhereTester<float>{.condition = {.type = OperandDataType::kUint8,
                                      .dimensions = {2, 3},
                                      .values = {2, 3, 0, 0, 5, 0}},
-                       .true_value = {.type = mojom::DataType::kFloat32,
+                       .true_value = {.type = OperandDataType::kFloat32,
                                       .dimensions = {2, 3},
                                       .values = {1, 2, 3, 4, 5, 64}},
-                       .false_value = {.type = mojom::DataType::kFloat32,
+                       .false_value = {.type = OperandDataType::kFloat32,
                                        .dimensions = {2, 3},
                                        .values = {6, 3, 5, 7, 8, 0}},
-                       .output = {.type = mojom::DataType::kFloat32,
+                       .output = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {1, 2, 5, 7, 5, 0}}}
         .Test();
@@ -7915,16 +7915,16 @@
   // Test where with 2-D condition, 0-D scalar true_value and 2-D false_value
   // using broadcast.
   {
-    WhereTester<float>{.condition = {.type = mojom::DataType::kUint8,
+    WhereTester<float>{.condition = {.type = OperandDataType::kUint8,
                                      .dimensions = {2, 3},
                                      .values = {1, 1, 0, 0, 1, 0}},
-                       .true_value = {.type = mojom::DataType::kFloat32,
+                       .true_value = {.type = OperandDataType::kFloat32,
                                       .dimensions = {},
                                       .values = {6}},
-                       .false_value = {.type = mojom::DataType::kFloat32,
+                       .false_value = {.type = OperandDataType::kFloat32,
                                        .dimensions = {2, 3},
                                        .values = {6, 3, 5, 7, 8, 0}},
-                       .output = {.type = mojom::DataType::kFloat32,
+                       .output = {.type = OperandDataType::kFloat32,
                                   .dimensions = {2, 3},
                                   .values = {6, 6, 5, 7, 6, 0}}}
         .Test();
@@ -7947,16 +7947,16 @@
     // Build the mojom graph info.
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 1, 5, 5}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 1, 5, 5}, OperandDataType::kFloat32);
     uint64_t filter_operand_id = builder.BuildConstant(
-        {1, 1, 3, 3}, mojom::DataType::kFloat32,
+        {1, 1, 3, 3}, OperandDataType::kFloat32,
         base::as_bytes(base::make_span(std::vector<float>(9, 1))));
     uint64_t conv2d_output_operand_id = builder.BuildIntermediateOperand(
-        {1, 1, 5, 5}, mojom::DataType::kFloat32);
+        {1, 1, 5, 5}, OperandDataType::kFloat32);
 
     Conv2dTester<float>::Conv2dAttributes attributes{
         .padding = {1, 1, 1, 1},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {1},
                                    .values = {-100}},
     };
@@ -7973,11 +7973,11 @@
                         std::move(attributes), bias_operand_id);
 
     uint64_t relu1_output_operand_id =
-        builder.BuildOutput("output1", {1, 1, 5, 5}, mojom::DataType::kFloat32);
+        builder.BuildOutput("output1", {1, 1, 5, 5}, OperandDataType::kFloat32);
     builder.BuildRelu(conv2d_output_operand_id, relu1_output_operand_id);
 
     uint64_t relu2_output_operand_id =
-        builder.BuildOutput("output2", {1, 1, 5, 5}, mojom::DataType::kFloat32);
+        builder.BuildOutput("output2", {1, 1, 5, 5}, OperandDataType::kFloat32);
     builder.BuildRelu(conv2d_output_operand_id, relu2_output_operand_id);
 
     base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -7996,11 +7996,11 @@
                                             62, 11, 0, 11, 17, 23, 0};
     VerifyFloatDataIsEqual(
         GetFloatOutputData(std::move(named_outputs["output1"]),
-                           mojom::DataType::kFloat32),
+                           OperandDataType::kFloat32),
         expected_output_data);
     VerifyFloatDataIsEqual(
         GetFloatOutputData(std::move(named_outputs["output2"]),
-                           mojom::DataType::kFloat32),
+                           OperandDataType::kFloat32),
         expected_output_data);
   }
   //     [input]
@@ -8015,16 +8015,16 @@
     // Build the mojom graph info.
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 1, 5, 5}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 1, 5, 5}, OperandDataType::kFloat32);
     uint64_t filter_operand_id = builder.BuildConstant(
-        {1, 1, 3, 3}, mojom::DataType::kFloat32,
+        {1, 1, 3, 3}, OperandDataType::kFloat32,
         base::as_bytes(base::make_span(std::vector<float>(9, 1))));
     uint64_t conv2d_output_operand_id = builder.BuildIntermediateOperand(
-        {1, 1, 5, 5}, mojom::DataType::kFloat32);
+        {1, 1, 5, 5}, OperandDataType::kFloat32);
 
     Conv2dTester<float>::Conv2dAttributes attributes{
         .padding = {1, 1, 1, 1},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {1},
                                    .values = {-100}},
     };
@@ -8041,11 +8041,11 @@
                         std::move(attributes), bias_operand_id);
 
     uint64_t reshape_output_operand_id =
-        builder.BuildOutput("output1", {1, 5, 1, 5}, mojom::DataType::kFloat32);
+        builder.BuildOutput("output1", {1, 5, 1, 5}, OperandDataType::kFloat32);
     builder.BuildReshape(conv2d_output_operand_id, reshape_output_operand_id);
 
     uint64_t relu_output_operand_id =
-        builder.BuildOutput("output2", {1, 1, 5, 5}, mojom::DataType::kFloat32);
+        builder.BuildOutput("output2", {1, 1, 5, 5}, OperandDataType::kFloat32);
     builder.BuildRelu(conv2d_output_operand_id, relu_output_operand_id);
 
     base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -8061,13 +8061,13 @@
 
     VerifyFloatDataIsEqual(
         GetFloatOutputData(std::move(named_outputs["output1"]),
-                           mojom::DataType::kFloat32),
+                           OperandDataType::kFloat32),
         std::vector<float>{-88, -79, -73, -67, -76, -67, -46, -37, -28,
                            -49, -37, -1,  8,   17,  -19, -7,  44,  53,
                            62,  11,  -28, 11,  17,  23,  -16});
     VerifyFloatDataIsEqual(
         GetFloatOutputData(std::move(named_outputs["output2"]),
-                           mojom::DataType::kFloat32),
+                           OperandDataType::kFloat32),
         std::vector<float>{0,  0, 0, 0,  0,  0,  0,  0, 0,  0,  0,  0, 8,
                            17, 0, 0, 44, 53, 62, 11, 0, 11, 17, 23, 0});
   }
@@ -8083,16 +8083,16 @@
     // Build the mojom graph info.
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 1, 5, 5}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 1, 5, 5}, OperandDataType::kFloat32);
     uint64_t filter_operand_id = builder.BuildConstant(
-        {1, 1, 3, 3}, mojom::DataType::kFloat32,
+        {1, 1, 3, 3}, OperandDataType::kFloat32,
         base::as_bytes(base::make_span(std::vector<float>(9, 1))));
     uint64_t conv2d_output_operand_id = builder.BuildIntermediateOperand(
-        {1, 1, 5, 5}, mojom::DataType::kFloat32);
+        {1, 1, 5, 5}, OperandDataType::kFloat32);
 
     Conv2dTester<float>::Conv2dAttributes attributes{
         .padding = {1, 1, 1, 1},
-        .bias = OperandInfo<float>{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo<float>{.type = OperandDataType::kFloat32,
                                    .dimensions = {1},
                                    .values = {-100}},
     };
@@ -8110,7 +8110,7 @@
     builder.AddOutput("output2", conv2d_output_operand_id);
 
     uint64_t relu_output_operand_id =
-        builder.BuildOutput("output1", {1, 1, 5, 5}, mojom::DataType::kFloat32);
+        builder.BuildOutput("output1", {1, 1, 5, 5}, OperandDataType::kFloat32);
     builder.BuildRelu(conv2d_output_operand_id, relu_output_operand_id);
 
     base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
@@ -8126,12 +8126,12 @@
 
     VerifyFloatDataIsEqual(
         GetFloatOutputData(std::move(named_outputs["output1"]),
-                           mojom::DataType::kFloat32),
+                           OperandDataType::kFloat32),
         std::vector<float>{0,  0, 0, 0,  0,  0,  0,  0, 0,  0,  0,  0, 8,
                            17, 0, 0, 44, 53, 62, 11, 0, 11, 17, 23, 0});
     VerifyFloatDataIsEqual(
         GetFloatOutputData(std::move(named_outputs["output2"]),
-                           mojom::DataType::kFloat32),
+                           OperandDataType::kFloat32),
         std::vector<float>{-88, -79, -73, -67, -76, -67, -46, -37, -28,
                            -49, -37, -1,  8,   17,  -19, -7,  44,  53,
                            62,  11,  -28, 11,  17,  23,  -16});
diff --git a/services/webnn/webnn_graph_impl_unittest.cc b/services/webnn/webnn_graph_impl_unittest.cc
index 730679e7..83d21f3a 100644
--- a/services/webnn/webnn_graph_impl_unittest.cc
+++ b/services/webnn/webnn_graph_impl_unittest.cc
@@ -301,10 +301,10 @@
   return valid;
 }
 
-mojom::DataType kAllOperandDataTypes[] = {
-    mojom::DataType::kFloat32, mojom::DataType::kFloat16,
-    mojom::DataType::kInt32,   mojom::DataType::kInt8,
-    mojom::DataType::kUint8,
+OperandDataType kAllOperandDataTypes[] = {
+    OperandDataType::kFloat32, OperandDataType::kFloat16,
+    OperandDataType::kInt32,   OperandDataType::kInt8,
+    OperandDataType::kUint8,
 };
 
 }  // namespace
@@ -335,7 +335,7 @@
 };
 
 struct OperandInfo {
-  mojom::DataType type;
+  OperandDataType type;
   std::vector<uint32_t> dimensions;
 };
 
@@ -373,11 +373,11 @@
     {
       // Test argMinMax operator with axis = {0} and keep_dimensions = true.
       ArgMinMaxTester{.kind = kind,
-                      .input = {.type = mojom::DataType::kFloat32,
+                      .input = {.type = OperandDataType::kFloat32,
                                 .dimensions = {2, 3, 4, 5}},
                       .axes = {0},
                       .keep_dimensions = true,
-                      .output = {.type = mojom::DataType::kInt64,
+                      .output = {.type = OperandDataType::kInt64,
                                  .dimensions = {1, 3, 4, 5}},
                       .expected = true}
           .Test();
@@ -386,11 +386,11 @@
       // Test argMinMax operator with axis = {0, 1} and keep_dimensions = false.
       ArgMinMaxTester{
           .kind = kind,
-          .input = {.type = mojom::DataType::kFloat16,
+          .input = {.type = OperandDataType::kFloat16,
                     .dimensions = {2, 3, 4, 5}},
           .axes = {0, 1},
           .keep_dimensions = false,
-          .output = {.type = mojom::DataType::kInt64, .dimensions = {4, 5}},
+          .output = {.type = OperandDataType::kInt64, .dimensions = {4, 5}},
           .expected = true}
           .Test();
     }
@@ -398,11 +398,11 @@
       // Test the invalid graph when value in the axes sequence is greater than
       // or equal to input rank.
       ArgMinMaxTester{.kind = kind,
-                      .input = {.type = mojom::DataType::kFloat32,
+                      .input = {.type = OperandDataType::kFloat32,
                                 .dimensions = {2, 3, 4, 5}},
                       .axes = {4},
                       .keep_dimensions = true,
-                      .output = {.type = mojom::DataType::kInt64,
+                      .output = {.type = OperandDataType::kInt64,
                                  .dimensions = {2, 3, 4, 1}},
                       .expected = false}
           .Test();
@@ -411,11 +411,11 @@
       // Test the invalid graph when two or more values are same in the axes
       // sequence.
       ArgMinMaxTester{.kind = mojom::ArgMinMax::Kind::kMax,
-                      .input = {.type = mojom::DataType::kFloat32,
+                      .input = {.type = OperandDataType::kFloat32,
                                 .dimensions = {2, 3, 4, 5}},
                       .axes = {1, 1},
                       .keep_dimensions = true,
-                      .output = {.type = mojom::DataType::kInt64,
+                      .output = {.type = OperandDataType::kInt64,
                                  .dimensions = {1, 3, 4, 5}},
                       .expected = false}
           .Test();
@@ -423,11 +423,11 @@
     {
       // Test the invalid graph when the output data type is not support.
       ArgMinMaxTester{.kind = kind,
-                      .input = {.type = mojom::DataType::kFloat32,
+                      .input = {.type = OperandDataType::kFloat32,
                                 .dimensions = {2, 3, 4, 5}},
                       .axes = {0},
                       .keep_dimensions = true,
-                      .output = {.type = mojom::DataType::kFloat32,
+                      .output = {.type = OperandDataType::kFloat32,
                                  .dimensions = {1, 3, 4, 5}},
                       .expected = false}
           .Test();
@@ -435,11 +435,11 @@
     {
       // Test the invalid graph when the output shape is incorrect.
       ArgMinMaxTester{.kind = kind,
-                      .input = {.type = mojom::DataType::kFloat32,
+                      .input = {.type = OperandDataType::kFloat32,
                                 .dimensions = {2, 3, 4, 5}},
                       .axes = {0},
                       .keep_dimensions = false,
-                      .output = {.type = mojom::DataType::kInt64,
+                      .output = {.type = OperandDataType::kInt64,
                                  .dimensions = {1, 3, 4, 5}},
                       .expected = false}
           .Test();
@@ -449,7 +449,7 @@
       auto context_properties = GetContextPropertiesForTesting();
       GraphInfoBuilder builder;
       uint64_t input_operand_id =
-          builder.BuildInput("input", {2, 3, 4, 5}, mojom::DataType::kInt64);
+          builder.BuildInput("input", {2, 3, 4, 5}, OperandDataType::kInt64);
       builder.BuildArgMinMax(kind, input_operand_id, input_operand_id, {0},
                              true, false);
       EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
@@ -489,37 +489,37 @@
   {
     // Test clamp operator with both the minimum and maximum values.
     ClampTester{
-        .input = {.type = mojom::DataType::kInt8, .dimensions = {3, 4}},
+        .input = {.type = OperandDataType::kInt8, .dimensions = {3, 4}},
         .attributes = {.min_value = 0.0, .max_value = 6.0},
-        .output = {.type = mojom::DataType::kInt8, .dimensions = {3, 4}},
+        .output = {.type = OperandDataType::kInt8, .dimensions = {3, 4}},
         .expected = true}
         .Test();
   }
   {
     // Test clamp operator with the min value is infinite.
     ClampTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {2, 3, 4}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {2, 3, 4}},
         .attributes = {.min_value = static_cast<float>(-1.0 / 0.0),
                        .max_value = 3.0},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {2, 3, 4}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {2, 3, 4}},
         .expected = true}
         .Test();
   }
   {
     // Test clamp operator with the max value is infinite.
     ClampTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {2, 3, 4}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {2, 3, 4}},
         .attributes = {.min_value = 0.0,
                        .max_value = static_cast<float>(1.0 / 0.0)},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {2, 3, 4}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {2, 3, 4}},
         .expected = true}
         .Test();
   }
   {
     // Test the invalid graph when max value = 0 and min value = 0.
-    ClampTester{.input = {.type = mojom::DataType::kFloat32,
+    ClampTester{.input = {.type = OperandDataType::kFloat32,
                           .dimensions = {1, 2, 2, 7}},
-                .output = {.type = mojom::DataType::kFloat32,
+                .output = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 2, 2, 7}},
                 .expected = false}
         .Test();
@@ -527,42 +527,42 @@
   {
     // Test the invalid graph when the max value is less than the min value.
     ClampTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
         .attributes = {.min_value = 7.0, .max_value = 3.0},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph when the min value is NAN.
     ClampTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {2, 3, 4}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {2, 3, 4}},
         .attributes = {.min_value = NAN, .max_value = 3.0},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {2, 3, 4}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {2, 3, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph when the max value is NAN.
     ClampTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {2, 3, 4}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {2, 3, 4}},
         .attributes = {.min_value = 0.0, .max_value = NAN},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {2, 3, 4}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {2, 3, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the output shapes are not expected.
     ClampTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output types don't match.
-    ClampTester{.input = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-                .output = {.type = mojom::DataType::kInt32, .dimensions = {2}},
+    ClampTester{.input = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+                .output = {.type = OperandDataType::kInt32, .dimensions = {2}},
                 .expected = false}
         .Test();
   }
@@ -595,44 +595,44 @@
   {
     // Test hardSigmoid operator with default alpha and beta values.
     HardSigmoidTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
         .expected = true}
         .Test();
   }
   {
     // Test the invalid graph when the alpha value is NAN.
     HardSigmoidTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3, 4}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 3, 4}},
         .alpha = NAN,
         .beta = 0.5,
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 3, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph when the beta value is NAN.
     HardSigmoidTester{
-        .input = {.type = mojom::DataType::kFloat16, .dimensions = {2, 3, 4}},
+        .input = {.type = OperandDataType::kFloat16, .dimensions = {2, 3, 4}},
         .alpha = 1.0,
         .beta = NAN,
-        .output = {.type = mojom::DataType::kFloat16, .dimensions = {2, 3, 4}},
+        .output = {.type = OperandDataType::kFloat16, .dimensions = {2, 3, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the output shapes are not expected.
     HardSigmoidTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output types don't match.
     HardSigmoidTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
@@ -699,11 +699,11 @@
   {
     // Test building batchNormalization with default option.
     BatchNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
-        .mean = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .variance = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .variance = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = true}
         .Test();
@@ -711,12 +711,12 @@
   {
     // Test building batchNormalization with axis = 3.
     BatchNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
-        .mean = {.type = mojom::DataType::kFloat32, .dimensions = {3}},
-        .variance = {.type = mojom::DataType::kFloat32, .dimensions = {3}},
+        .mean = {.type = OperandDataType::kFloat32, .dimensions = {3}},
+        .variance = {.type = OperandDataType::kFloat32, .dimensions = {3}},
         .attributes = {.axis = 3},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = true}
         .Test();
@@ -724,15 +724,15 @@
   {
     // Test building batchNormalization with setting optional bias and scale.
     BatchNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
-        .mean = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .variance = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .mean = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .variance = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .scale =
-            OperandInfo{.type = mojom::DataType::kFloat32, .dimensions = {2}},
+            OperandInfo{.type = OperandDataType::kFloat32, .dimensions = {2}},
         .bias =
-            OperandInfo{.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kFloat32,
+            OperandInfo{.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = true}
         .Test();
@@ -741,11 +741,11 @@
     // Test building batchNormalization when input data type and mean data
     // type mismatched.
     BatchNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
-        .mean = {.type = mojom::DataType::kInt32, .dimensions = {2}},
-        .variance = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kInt32, .dimensions = {2}},
+        .variance = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
@@ -754,11 +754,11 @@
     // Test building batchNormalization when the size of mean is not equal to
     // the size of the input dimension denoted by axis.
     BatchNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
-        .mean = {.type = mojom::DataType::kFloat32, .dimensions = {3}},
-        .variance = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kFloat32, .dimensions = {3}},
+        .variance = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
@@ -767,11 +767,11 @@
     // Test building batchNormalization when input data type and variance data
     // type mismatched.
     BatchNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
-        .mean = {.type = mojom::DataType::kInt32, .dimensions = {2}},
-        .variance = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kInt32, .dimensions = {2}},
+        .variance = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
@@ -780,11 +780,11 @@
     // Test building batchNormalization when the size of variance is not equal
     // to the size of the input dimension denoted by axis.
     BatchNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
-        .mean = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .variance = {.type = mojom::DataType::kFloat32, .dimensions = {1}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .variance = {.type = OperandDataType::kFloat32, .dimensions = {1}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
@@ -793,10 +793,10 @@
     // Test building batchNormalization when input data is not floating point
     // type.
     BatchNormalizationTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {1, 2, 3, 3}},
-        .mean = {.type = mojom::DataType::kInt32, .dimensions = {2}},
-        .variance = {.type = mojom::DataType::kInt32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kInt32, .dimensions = {1, 2, 3, 3}},
+        .mean = {.type = OperandDataType::kInt32, .dimensions = {2}},
+        .variance = {.type = OperandDataType::kInt32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
@@ -804,12 +804,12 @@
   {
     // Test building batchNormalization when axis is out of range [0, N-1].
     BatchNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
-        .mean = {.type = mojom::DataType::kFloat32, .dimensions = {3}},
-        .variance = {.type = mojom::DataType::kFloat32, .dimensions = {3}},
+        .mean = {.type = OperandDataType::kFloat32, .dimensions = {3}},
+        .variance = {.type = OperandDataType::kFloat32, .dimensions = {3}},
         .attributes = {.axis = 4},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
@@ -818,13 +818,13 @@
     // Test batchNormalization when input data type and scale data type
     // mismatched.
     BatchNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
-        .mean = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .variance = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .mean = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .variance = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .scale =
-            OperandInfo{.type = mojom::DataType::kInt32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kFloat32,
+            OperandInfo{.type = OperandDataType::kInt32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
@@ -833,13 +833,13 @@
     // Test building batchNormalization when the size of scale is not equal
     // to the size of the input dimension denoted by axis.
     BatchNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
-        .mean = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .variance = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .mean = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .variance = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .scale =
-            OperandInfo{.type = mojom::DataType::kFloat32, .dimensions = {3}},
-        .output = {.type = mojom::DataType::kFloat32,
+            OperandInfo{.type = OperandDataType::kFloat32, .dimensions = {3}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
@@ -848,12 +848,12 @@
     // Test batchNormalization when input data type and bias data type
     // mismatched.
     BatchNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
-        .mean = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .variance = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .bias = OperandInfo{.type = mojom::DataType::kInt32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .mean = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .variance = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .bias = OperandInfo{.type = OperandDataType::kInt32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
@@ -862,13 +862,13 @@
     // Test building batchNormalization when the size of bias is not equal
     // to the size of the input dimension denoted by axis.
     BatchNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
-        .mean = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .variance = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .mean = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .variance = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .bias =
-            OperandInfo{.type = mojom::DataType::kFloat32, .dimensions = {3}},
-        .output = {.type = mojom::DataType::kFloat32,
+            OperandInfo{.type = OperandDataType::kFloat32, .dimensions = {3}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
@@ -876,26 +876,26 @@
   {
     // Test the invalid graph for output type is not the same as input type.
     BatchNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
-        .mean = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .variance = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .mean = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .variance = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .bias =
-            OperandInfo{.type = mojom::DataType::kFloat32, .dimensions = {3}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {1, 2, 3, 3}},
+            OperandInfo{.type = OperandDataType::kFloat32, .dimensions = {3}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output shape is not the same as input shape.
     BatchNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
-        .mean = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .variance = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .mean = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .variance = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .bias =
-            OperandInfo{.type = mojom::DataType::kFloat32, .dimensions = {3}},
-        .output = {.type = mojom::DataType::kFloat32,
+            OperandInfo{.type = OperandDataType::kFloat32, .dimensions = {3}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3}},
         .expected = false}
         .Test();
@@ -905,11 +905,11 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
     uint64_t mean_operand_id =
-        builder.BuildInput("mean", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("mean", {2}, OperandDataType::kFloat32);
     uint64_t variance_operand_id =
-        builder.BuildInput("variance", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("variance", {2}, OperandDataType::kFloat32);
     builder.BuildBatchNormalization(
         input_operand_id, mean_operand_id, variance_operand_id,
         input_operand_id,
@@ -922,11 +922,11 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
     uint64_t mean_operand_id =
-        builder.BuildInput("mean", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("mean", {2}, OperandDataType::kFloat32);
     uint64_t variance_operand_id =
-        builder.BuildInput("variance", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("variance", {2}, OperandDataType::kFloat32);
     builder.BuildBatchNormalization(
         input_operand_id, mean_operand_id, variance_operand_id, mean_operand_id,
         BatchNormalizationTester::BatchNormalizationAttributes{});
@@ -938,11 +938,11 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
     uint64_t mean_operand_id =
-        builder.BuildInput("mean", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("mean", {2}, OperandDataType::kFloat32);
     uint64_t variance_operand_id =
-        builder.BuildInput("variance", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("variance", {2}, OperandDataType::kFloat32);
     builder.BuildBatchNormalization(
         input_operand_id, mean_operand_id, variance_operand_id,
         variance_operand_id,
@@ -984,21 +984,21 @@
     // Test concat operator with three inputs.
     ConcatTester{
         .inputs =
-            {{.type = mojom::DataType::kFloat32, .dimensions = {3, 1, 5, 6}},
-             {.type = mojom::DataType::kFloat32, .dimensions = {3, 2, 5, 6}},
-             {.type = mojom::DataType::kFloat32, .dimensions = {3, 3, 5, 6}}},
+            {{.type = OperandDataType::kFloat32, .dimensions = {3, 1, 5, 6}},
+             {.type = OperandDataType::kFloat32, .dimensions = {3, 2, 5, 6}},
+             {.type = OperandDataType::kFloat32, .dimensions = {3, 3, 5, 6}}},
         .axis = 1,
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {3, 6, 5, 6}},
         .expected = true}
         .Test();
   }
   {
     // Test concat operator when the input is the same as output.
-    ConcatTester{.inputs = {{.type = mojom::DataType::kFloat32,
+    ConcatTester{.inputs = {{.type = OperandDataType::kFloat32,
                              .dimensions = {3, 1, 5, 6}}},
                  .axis = 1,
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {3, 1, 5, 6}},
                  .expected = true}
         .Test();
@@ -1007,19 +1007,19 @@
     // Test concat operator with empty inputs.
     ConcatTester{.inputs = {},
                  .axis = 0,
-                 .output = {.type = mojom::DataType::kInt32, .dimensions = {1}},
+                 .output = {.type = OperandDataType::kInt32, .dimensions = {1}},
                  .expected = false}
         .Test();
   }
   {
     // Test concat operator when the inputs' datatypes don't match each
     // other.
-    ConcatTester{.inputs = {{.type = mojom::DataType::kFloat32,
+    ConcatTester{.inputs = {{.type = OperandDataType::kFloat32,
                              .dimensions = {3, 1, 5, 6}},
-                            {.type = mojom::DataType::kInt32,
+                            {.type = OperandDataType::kInt32,
                              .dimensions = {3, 2, 5, 6}}},
                  .axis = 1,
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {3, 3, 5, 6}},
                  .expected = false}
         .Test();
@@ -1027,23 +1027,23 @@
   {
     // Test concat operator when the inputs can not be concatenated.
     ConcatTester{
-        .inputs = {{.type = mojom::DataType::kFloat32, .dimensions = {3, 1, 5}},
-                   {.type = mojom::DataType::kFloat32,
+        .inputs = {{.type = OperandDataType::kFloat32, .dimensions = {3, 1, 5}},
+                   {.type = OperandDataType::kFloat32,
                     .dimensions = {3, 2, 5, 6}}},
         .axis = 1,
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {3, 3, 5}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {3, 3, 5}},
         .expected = false}
         .Test();
   }
   {
     // Test concat operator when the axis is equal to or greater than the
     // size of dimension.
-    ConcatTester{.inputs = {{.type = mojom::DataType::kFloat32,
+    ConcatTester{.inputs = {{.type = OperandDataType::kFloat32,
                              .dimensions = {3, 1, 5, 6}},
-                            {.type = mojom::DataType::kFloat32,
+                            {.type = OperandDataType::kFloat32,
                              .dimensions = {3, 1, 5, 6}}},
                  .axis = 4,
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {3, 1, 5, 12}},
                  .expected = false}
         .Test();
@@ -1051,48 +1051,37 @@
   {
     // Test concat operator when the inputs have other axes with different
     // sizes except on the axis.
-    ConcatTester{.inputs = {{.type = mojom::DataType::kFloat32,
+    ConcatTester{.inputs = {{.type = OperandDataType::kFloat32,
                              .dimensions = {3, 1, 5, 6}},
-                            {.type = mojom::DataType::kFloat32,
+                            {.type = OperandDataType::kFloat32,
                              .dimensions = {3, 1, 5, 1}}},
                  .axis = 1,
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {3, 2, 5, 7}},
                  .expected = false}
         .Test();
   }
   {
-    // Test concat operator when the concatenated dimension size overflows.
-    ConcatTester{
-        .inputs = {{.type = mojom::DataType::kFloat32,
-                    .dimensions = {std::numeric_limits<uint32_t>::max()}},
-                   {.type = mojom::DataType::kFloat32, .dimensions = {1}}},
-        .axis = 0,
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {0}},
-        .expected = false}
-        .Test();
-  }
-  {
     // Test concat operator when the output datatype doesn't match the
     // inputs' datatypes.
     ConcatTester{
-        .inputs = {{.type = mojom::DataType::kFloat32,
+        .inputs = {{.type = OperandDataType::kFloat32,
                     .dimensions = {3, 1, 5, 6}},
-                   {.type = mojom::DataType::kFloat32,
+                   {.type = OperandDataType::kFloat32,
                     .dimensions = {3, 2, 5, 6}}},
         .axis = 1,
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {3, 3, 5, 6}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {3, 3, 5, 6}},
         .expected = false}
         .Test();
   }
   {
     // Test concat operator when the output dimension is incorrect.
     ConcatTester{
-        .inputs = {{.type = mojom::DataType::kFloat32, .dimensions = {3, 1, 2}},
-                   {.type = mojom::DataType::kFloat32,
+        .inputs = {{.type = OperandDataType::kFloat32, .dimensions = {3, 1, 2}},
+                   {.type = OperandDataType::kFloat32,
                     .dimensions = {1, 1, 2}}},
         .axis = 0,
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {5, 1, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {5, 1, 2}},
         .expected = false}
         .Test();
   }
@@ -1148,11 +1137,11 @@
   {
     // Test conv2d with default attributes.
     Conv2dTester{.type = mojom::Conv2d::Kind::kDirect,
-                 .input = {.type = mojom::DataType::kFloat32,
+                 .input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 1, 5, 5}},
-                 .filter = {.type = mojom::DataType::kFloat32,
+                 .filter = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 1, 3, 3}},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 1, 3, 3}},
                  .expected = true}
         .Test();
@@ -1160,12 +1149,12 @@
   {
     // Test conv2d for same upper or lower padding.
     Conv2dTester{.type = mojom::Conv2d::Kind::kDirect,
-                 .input = {.type = mojom::DataType::kFloat16,
+                 .input = {.type = OperandDataType::kFloat16,
                            .dimensions = {1, 1, 5, 5}},
-                 .filter = {.type = mojom::DataType::kFloat16,
+                 .filter = {.type = OperandDataType::kFloat16,
                             .dimensions = {1, 1, 3, 3}},
                  .attributes = {.padding = {1, 1, 1, 1}},
-                 .output = {.type = mojom::DataType::kFloat16,
+                 .output = {.type = OperandDataType::kFloat16,
                             .dimensions = {1, 1, 5, 5}},
                  .expected = true}
         .Test();
@@ -1173,12 +1162,12 @@
   {
     // Test conv2d with strides=2 and padding=1.
     Conv2dTester{.type = mojom::Conv2d::Kind::kDirect,
-                 .input = {.type = mojom::DataType::kFloat16,
+                 .input = {.type = OperandDataType::kFloat16,
                            .dimensions = {1, 1, 5, 5}},
-                 .filter = {.type = mojom::DataType::kFloat16,
+                 .filter = {.type = OperandDataType::kFloat16,
                             .dimensions = {1, 1, 3, 3}},
                  .attributes = {.padding = {1, 1, 1, 1}, .strides = {2, 2}},
-                 .output = {.type = mojom::DataType::kFloat16,
+                 .output = {.type = OperandDataType::kFloat16,
                             .dimensions = {1, 1, 3, 3}},
                  .expected = true}
         .Test();
@@ -1186,12 +1175,12 @@
   {
     // Test depthwise conv2d by setting groups to input channels.
     Conv2dTester{.type = mojom::Conv2d::Kind::kDirect,
-                 .input = {.type = mojom::DataType::kFloat16,
+                 .input = {.type = OperandDataType::kFloat16,
                            .dimensions = {1, 4, 2, 2}},
-                 .filter = {.type = mojom::DataType::kFloat16,
+                 .filter = {.type = OperandDataType::kFloat16,
                             .dimensions = {4, 1, 2, 2}},
                  .attributes = {.groups = 4},
-                 .output = {.type = mojom::DataType::kFloat16,
+                 .output = {.type = OperandDataType::kFloat16,
                             .dimensions = {1, 4, 1, 1}},
                  .expected = true}
         .Test();
@@ -1199,13 +1188,13 @@
   {
     // Test conv2d with inputLayout="nchw" and filterLayout="oihw".
     Conv2dTester{.type = mojom::Conv2d::Kind::kDirect,
-                 .input = {.type = mojom::DataType::kFloat16,
+                 .input = {.type = OperandDataType::kFloat16,
                            .dimensions = {1, 2, 5, 5}},
-                 .filter = {.type = mojom::DataType::kFloat16,
+                 .filter = {.type = OperandDataType::kFloat16,
                             .dimensions = {1, 2, 3, 3}},
                  .attributes = {.input_layout =
                                     mojom::InputOperandLayout::kChannelsFirst},
-                 .output = {.type = mojom::DataType::kFloat16,
+                 .output = {.type = OperandDataType::kFloat16,
                             .dimensions = {1, 1, 3, 3}},
                  .expected = true}
         .Test();
@@ -1214,10 +1203,10 @@
     // Test the invalid graph when the input is not a 4-D tensor.
     Conv2dTester{
         .type = mojom::Conv2d::Kind::kDirect,
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {1, 5, 5}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {1, 5, 5}},
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3}},
         .expected = false}
         .Test();
@@ -1226,9 +1215,9 @@
     // Test the invalid graph when the input data type is not floating point.
     Conv2dTester{
         .type = mojom::Conv2d::Kind::kDirect,
-        .input = {.type = mojom::DataType::kInt8, .dimensions = {1, 1, 5, 5}},
-        .filter = {.type = mojom::DataType::kInt8, .dimensions = {1, 1, 3, 3}},
-        .output = {.type = mojom::DataType::kInt8, .dimensions = {1, 1, 3, 3}},
+        .input = {.type = OperandDataType::kInt8, .dimensions = {1, 1, 5, 5}},
+        .filter = {.type = OperandDataType::kInt8, .dimensions = {1, 1, 3, 3}},
+        .output = {.type = OperandDataType::kInt8, .dimensions = {1, 1, 3, 3}},
         .expected = false}
         .Test();
   }
@@ -1236,10 +1225,10 @@
     // Test the invalid graph when the filter is not a 4-D tensor.
     Conv2dTester{
         .type = mojom::Conv2d::Kind::kDirect,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 5, 5}},
-        .filter = {.type = mojom::DataType::kFloat32, .dimensions = {1, 3, 3}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32, .dimensions = {1, 3, 3}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3}},
         .expected = false}
         .Test();
@@ -1249,10 +1238,10 @@
     // type.
     Conv2dTester{
         .type = mojom::Conv2d::Kind::kDirect,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 5, 5}},
-        .filter = {.type = mojom::DataType::kInt32, .dimensions = {1, 1, 3, 3}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kInt32, .dimensions = {1, 1, 3, 3}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3}},
         .expected = false}
         .Test();
@@ -1261,13 +1250,13 @@
     // Test the invalid graph when the bias type doesn't match input type.
     Conv2dTester{
         .type = mojom::Conv2d::Kind::kDirect,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 5, 5}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3}},
-        .attributes = {.bias = OperandInfo{.type = mojom::DataType::kInt32,
+        .attributes = {.bias = OperandInfo{.type = OperandDataType::kInt32,
                                            .dimensions = {1}}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3}},
         .expected = false}
         .Test();
@@ -1277,13 +1266,13 @@
     // [output_channels].
     Conv2dTester{
         .type = mojom::Conv2d::Kind::kDirect,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 5, 5}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3}},
-        .attributes = {.bias = OperandInfo{.type = mojom::DataType::kFloat32,
+        .attributes = {.bias = OperandInfo{.type = OperandDataType::kFloat32,
                                            .dimensions = {2}}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3}},
         .expected = false}
         .Test();
@@ -1293,23 +1282,23 @@
     // doesn't match the result of input channels divided by groups
     Conv2dTester{
         .type = mojom::Conv2d::Kind::kDirect,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 5, 5}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3}},
         .attributes = {.groups = 3},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {1, 1, 3, 3}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {1, 1, 3, 3}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the output shapes are not expected.
     Conv2dTester{.type = mojom::Conv2d::Kind::kDirect,
-                 .input = {.type = mojom::DataType::kFloat32,
+                 .input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 1, 5, 5}},
-                 .filter = {.type = mojom::DataType::kFloat32,
+                 .filter = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 1, 3, 3}},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 2, 1, 1}},
                  .expected = false}
         .Test();
@@ -1317,11 +1306,11 @@
   {
     // Test the invalid graph for output types don't match.
     Conv2dTester{.type = mojom::Conv2d::Kind::kDirect,
-                 .input = {.type = mojom::DataType::kFloat32,
+                 .input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 1, 5, 5}},
-                 .filter = {.type = mojom::DataType::kFloat32,
+                 .filter = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 1, 3, 3}},
-                 .output = {.type = mojom::DataType::kFloat16,
+                 .output = {.type = OperandDataType::kFloat16,
                             .dimensions = {1, 1, 3, 3}},
                  .expected = false}
         .Test();
@@ -1331,9 +1320,9 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 1, 5, 5}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 1, 5, 5}, OperandDataType::kFloat32);
     uint64_t filter_operand_id =
-        builder.BuildInput("filter", {1, 1, 3, 3}, mojom::DataType::kFloat32);
+        builder.BuildInput("filter", {1, 1, 3, 3}, OperandDataType::kFloat32);
 
     builder.BuildConv2d(mojom::Conv2d::Kind::kDirect, input_operand_id,
                         filter_operand_id, input_operand_id,
@@ -1347,9 +1336,9 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 1, 5, 5}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 1, 5, 5}, OperandDataType::kFloat32);
     uint64_t filter_operand_id =
-        builder.BuildInput("filter", {1, 1, 3, 3}, mojom::DataType::kFloat32);
+        builder.BuildInput("filter", {1, 1, 3, 3}, OperandDataType::kFloat32);
 
     builder.BuildConv2d(mojom::Conv2d::Kind::kDirect, input_operand_id,
                         filter_operand_id, filter_operand_id,
@@ -1364,11 +1353,11 @@
   {
     // Test convTranspose2d with default attributes.
     Conv2dTester{.type = mojom::Conv2d::Kind::kTransposed,
-                 .input = {.type = mojom::DataType::kFloat32,
+                 .input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 1, 3, 3}},
-                 .filter = {.type = mojom::DataType::kFloat32,
+                 .filter = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 1, 3, 3}},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 1, 5, 5}},
                  .expected = true}
         .Test();
@@ -1376,13 +1365,13 @@
   {
     // Test convTranspose2d with input_layout = kChannelsLast.
     Conv2dTester{.type = mojom::Conv2d::Kind::kTransposed,
-                 .input = {.type = mojom::DataType::kFloat32,
+                 .input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 3, 3, 1}},
-                 .filter = {.type = mojom::DataType::kFloat32,
+                 .filter = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 1, 3, 3}},
                  .attributes = {.input_layout =
                                     mojom::InputOperandLayout::kChannelsLast},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 5, 5, 1}},
                  .expected = true}
         .Test();
@@ -1390,12 +1379,12 @@
   {
     // Test convTranspose2d with padding = [1, 1, 1, 1].
     Conv2dTester{.type = mojom::Conv2d::Kind::kTransposed,
-                 .input = {.type = mojom::DataType::kFloat32,
+                 .input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 1, 5, 5}},
-                 .filter = {.type = mojom::DataType::kFloat32,
+                 .filter = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 1, 3, 3}},
                  .attributes = {.padding = {1, 1, 1, 1}},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 1, 5, 5}},
                  .expected = true}
         .Test();
@@ -1403,12 +1392,12 @@
   {
     // Test convTranspose2d with strides = [2, 2].
     Conv2dTester{.type = mojom::Conv2d::Kind::kTransposed,
-                 .input = {.type = mojom::DataType::kFloat32,
+                 .input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 1, 3, 3}},
-                 .filter = {.type = mojom::DataType::kFloat32,
+                 .filter = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 2, 3, 3}},
                  .attributes = {.strides = {2, 2}},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 2, 7, 7}},
                  .expected = true}
         .Test();
@@ -1417,12 +1406,12 @@
     // Test convTranspose2d with strides = [2, 2] and padding = [1, 1, 1,
     // 1].
     Conv2dTester{.type = mojom::Conv2d::Kind::kTransposed,
-                 .input = {.type = mojom::DataType::kFloat32,
+                 .input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 1, 3, 3}},
-                 .filter = {.type = mojom::DataType::kFloat32,
+                 .filter = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 1, 3, 3}},
                  .attributes = {.padding = {1, 1, 1, 1}, .strides = {2, 2}},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 1, 5, 5}},
                  .expected = true}
         .Test();
@@ -1430,12 +1419,12 @@
   {
     // Test convTranspose2d with group = 3.
     Conv2dTester{.type = mojom::Conv2d::Kind::kTransposed,
-                 .input = {.type = mojom::DataType::kFloat32,
+                 .input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 1, 3, 3}},
-                 .filter = {.type = mojom::DataType::kFloat32,
+                 .filter = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 1, 3, 3}},
                  .attributes = {.groups = 3},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 3, 5, 5}},
                  .expected = true}
         .Test();
@@ -1444,11 +1433,11 @@
     // Test the invalid graph for output types don't match.
     Conv2dTester{
         .type = mojom::Conv2d::Kind::kTransposed,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 5, 5}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {1, 1, 3, 3}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {1, 1, 3, 3}},
         .expected = false}
         .Test();
   }
@@ -1456,10 +1445,10 @@
     // Test the invalid graph for the input is not a 4-D tensor.
     Conv2dTester{
         .type = mojom::Conv2d::Kind::kTransposed,
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {1, 3, 3}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {1, 3, 3}},
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {1, 1, 5, 5}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {1, 1, 5, 5}},
         .expected = false}
         .Test();
   }
@@ -1467,10 +1456,10 @@
     // Test the invalid graph for the filter is not a 4-D tensor.
     Conv2dTester{
         .type = mojom::Conv2d::Kind::kTransposed,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 3, 3}},
-        .filter = {.type = mojom::DataType::kFloat32, .dimensions = {1, 3, 3}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {1, 1, 5, 5}},
+        .filter = {.type = OperandDataType::kFloat32, .dimensions = {1, 3, 3}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {1, 1, 5, 5}},
         .expected = false}
         .Test();
   }
@@ -1478,12 +1467,12 @@
     // Test the invalid graph when the number of input channels is not equal
     // to the number of filter input channels.
     Conv2dTester{.type = mojom::Conv2d::Kind::kTransposed,
-                 .input = {.type = mojom::DataType::kFloat32,
+                 .input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 1, 3, 3}},
-                 .filter = {.type = mojom::DataType::kFloat32,
+                 .filter = {.type = OperandDataType::kFloat32,
                             .dimensions = {3, 1, 3, 3}},
                  .attributes = {.groups = 3},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 3, 5, 5}},
                  .expected = false}
         .Test();
@@ -1493,12 +1482,12 @@
     // match the result of filter output channels multiplied by groups
     Conv2dTester{
         .type = mojom::Conv2d::Kind::kTransposed,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 3, 3}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3}},
         .attributes = {.groups = 3},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {1, 1, 5, 5}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {1, 1, 5, 5}},
         .expected = false}
         .Test();
   }
@@ -1507,10 +1496,10 @@
     // type.
     Conv2dTester{
         .type = mojom::Conv2d::Kind::kTransposed,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 3, 3}},
-        .filter = {.type = mojom::DataType::kInt32, .dimensions = {1, 1, 3, 3}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kInt32, .dimensions = {1, 1, 3, 3}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 5, 5}},
         .expected = false}
         .Test();
@@ -1519,13 +1508,13 @@
     // Test the invalid graph when the bias type doesn't match input type.
     Conv2dTester{
         .type = mojom::Conv2d::Kind::kTransposed,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 3, 3}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3}},
-        .attributes = {.bias = OperandInfo{.type = mojom::DataType::kInt32,
+        .attributes = {.bias = OperandInfo{.type = OperandDataType::kInt32,
                                            .dimensions = {1}}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 5, 5}},
         .expected = false}
         .Test();
@@ -1535,13 +1524,13 @@
     // [output_channels].
     Conv2dTester{
         .type = mojom::Conv2d::Kind::kTransposed,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 3, 3}},
-        .filter = {.type = mojom::DataType::kFloat32,
+        .filter = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 3, 3}},
-        .attributes = {.bias = OperandInfo{.type = mojom::DataType::kFloat32,
+        .attributes = {.bias = OperandInfo{.type = OperandDataType::kFloat32,
                                            .dimensions = {2}}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 5, 5}},
         .expected = false}
         .Test();
@@ -1551,9 +1540,9 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 1, 3, 3}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 1, 3, 3}, OperandDataType::kFloat32);
     uint64_t filter_operand_id =
-        builder.BuildInput("filter", {1, 1, 3, 3}, mojom::DataType::kFloat32);
+        builder.BuildInput("filter", {1, 1, 3, 3}, OperandDataType::kFloat32);
 
     builder.BuildConv2d(mojom::Conv2d::Kind::kTransposed, input_operand_id,
                         filter_operand_id, input_operand_id,
@@ -1567,9 +1556,9 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 1, 3, 3}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 1, 3, 3}, OperandDataType::kFloat32);
     uint64_t filter_operand_id =
-        builder.BuildInput("filter", {1, 1, 3, 3}, mojom::DataType::kFloat32);
+        builder.BuildInput("filter", {1, 1, 3, 3}, OperandDataType::kFloat32);
 
     builder.BuildConv2d(mojom::Conv2d::Kind::kTransposed, input_operand_id,
                         filter_operand_id, filter_operand_id,
@@ -1631,9 +1620,9 @@
   {
     ElementWiseBinaryTester{
         .kind = mojom::ElementWiseBinary::Kind::kAdd,
-        .lhs = {.type = mojom::DataType::kFloat32, .dimensions = {8, 1, 6, 1}},
-        .rhs = {.type = mojom::DataType::kFloat32, .dimensions = {7, 1, 5}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .lhs = {.type = OperandDataType::kFloat32, .dimensions = {8, 1, 6, 1}},
+        .rhs = {.type = OperandDataType::kFloat32, .dimensions = {7, 1, 5}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {8, 7, 6, 5}},
         .expected = true}
         .Test();
@@ -1646,9 +1635,9 @@
   {
     ElementWiseBinaryTester{
         .kind = mojom::ElementWiseBinary::Kind::kSub,
-        .lhs = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2, 1}},
-        .rhs = {.type = mojom::DataType::kFloat32, .dimensions = {4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2, 4}},
+        .lhs = {.type = OperandDataType::kFloat32, .dimensions = {4, 2, 1}},
+        .rhs = {.type = OperandDataType::kFloat32, .dimensions = {4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {4, 2, 4}},
         .expected = true}
         .Test();
   }
@@ -1657,9 +1646,9 @@
   {
     ElementWiseBinaryTester{
         .kind = mojom::ElementWiseBinary::Kind::kMul,
-        .lhs = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .rhs = {.type = mojom::DataType::kFloat32, .dimensions = {4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
+        .lhs = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
+        .rhs = {.type = OperandDataType::kFloat32, .dimensions = {4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
         .expected = false}
         .Test();
   }
@@ -1668,9 +1657,9 @@
   {
     ElementWiseBinaryTester{
         .kind = mojom::ElementWiseBinary::Kind::kDiv,
-        .lhs = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .rhs = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .lhs = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
+        .rhs = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
@@ -1679,9 +1668,9 @@
   {
     ElementWiseBinaryTester{
         .kind = mojom::ElementWiseBinary::Kind::kMax,
-        .lhs = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .rhs = {.type = mojom::DataType::kInt32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .lhs = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .rhs = {.type = OperandDataType::kInt32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
@@ -1690,9 +1679,9 @@
   {
     ElementWiseBinaryTester{
         .kind = mojom::ElementWiseBinary::Kind::kMin,
-        .lhs = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .rhs = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {2}},
+        .lhs = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .rhs = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
@@ -1707,9 +1696,9 @@
   // output_dimenions (4d) 8 * 7 * 6 * 5
   {
     ElementWiseBinaryTester{
-        .lhs = {.type = mojom::DataType::kFloat32, .dimensions = {8, 1, 6, 1}},
-        .rhs = {.type = mojom::DataType::kFloat32, .dimensions = {7, 1, 5}},
-        .output = {.type = mojom::DataType::kUint8, .dimensions = {8, 7, 6, 5}},
+        .lhs = {.type = OperandDataType::kFloat32, .dimensions = {8, 1, 6, 1}},
+        .rhs = {.type = OperandDataType::kFloat32, .dimensions = {7, 1, 5}},
+        .output = {.type = OperandDataType::kUint8, .dimensions = {8, 7, 6, 5}},
         .expected = true}
         .TestLogicalOperators();
   }
@@ -1720,9 +1709,9 @@
   // output_dimenions (3d) 4 * 2 * 4
   {
     ElementWiseBinaryTester{
-        .lhs = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2, 1}},
-        .rhs = {.type = mojom::DataType::kFloat32, .dimensions = {4}},
-        .output = {.type = mojom::DataType::kUint8, .dimensions = {4, 2, 4}},
+        .lhs = {.type = OperandDataType::kFloat32, .dimensions = {4, 2, 1}},
+        .rhs = {.type = OperandDataType::kFloat32, .dimensions = {4}},
+        .output = {.type = OperandDataType::kUint8, .dimensions = {4, 2, 4}},
         .expected = true}
         .TestLogicalOperators();
   }
@@ -1730,9 +1719,9 @@
   // Test the invalid graph for the input shapes are not broadcastable.
   {
     ElementWiseBinaryTester{
-        .lhs = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .rhs = {.type = mojom::DataType::kFloat32, .dimensions = {4}},
-        .output = {.type = mojom::DataType::kUint8, .dimensions = {4, 2}},
+        .lhs = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
+        .rhs = {.type = OperandDataType::kFloat32, .dimensions = {4}},
+        .output = {.type = OperandDataType::kUint8, .dimensions = {4, 2}},
         .expected = false}
         .TestLogicalOperators();
   }
@@ -1740,9 +1729,9 @@
   // Test the invalid graph for the output shapes are not expected.
   {
     ElementWiseBinaryTester{
-        .lhs = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .rhs = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .output = {.type = mojom::DataType::kUint8, .dimensions = {2}},
+        .lhs = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
+        .rhs = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
+        .output = {.type = OperandDataType::kUint8, .dimensions = {2}},
         .expected = false}
         .TestLogicalOperators();
   }
@@ -1750,9 +1739,9 @@
   // Test the invalid graph for input types don't match.
   {
     ElementWiseBinaryTester{
-        .lhs = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .rhs = {.type = mojom::DataType::kInt32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kUint8, .dimensions = {2}},
+        .lhs = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .rhs = {.type = OperandDataType::kInt32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kUint8, .dimensions = {2}},
         .expected = false}
         .TestLogicalOperators();
   }
@@ -1761,9 +1750,9 @@
   // logical operators.
   {
     ElementWiseBinaryTester{
-        .lhs = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .rhs = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .lhs = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .rhs = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .expected = false}
         .TestLogicalOperators();
   }
@@ -1798,9 +1787,9 @@
 class ElementWiseUnaryDataTypeFixture
     : public testing::TestWithParam<
           std::tuple<std::pair<mojom::ElementWiseUnary::Kind,
-                               std::vector<mojom::DataType>>,
-                     mojom::DataType,
-                     mojom::DataType>> {
+                               std::vector<OperandDataType>>,
+                     OperandDataType,
+                     OperandDataType>> {
  public:
   // Populate meaningful test suffixes.
   struct PrintToStringParamName {
@@ -1854,27 +1843,27 @@
     ::testing::Combine(
         ::testing::ValuesIn({
             std::make_pair(mojom::ElementWiseUnary::Kind::kLogicalNot,
-                           std::vector<mojom::DataType>{
-                               mojom::DataType::kUint8}),
+                           std::vector<OperandDataType>{
+                               OperandDataType::kUint8}),
             std::make_pair(
                 mojom::ElementWiseUnary::Kind::kIdentity,
-                std::vector<mojom::DataType>(kAllOperandDataTypes,
+                std::vector<OperandDataType>(kAllOperandDataTypes,
                                              std::end(kAllOperandDataTypes))),
             std::make_pair(mojom::ElementWiseUnary::Kind::kSqrt,
-                           std::vector<mojom::DataType>{
-                               mojom::DataType::kFloat16,
-                               mojom::DataType::kFloat32}),
+                           std::vector<OperandDataType>{
+                               OperandDataType::kFloat16,
+                               OperandDataType::kFloat32}),
             std::make_pair(mojom::ElementWiseUnary::Kind::kErf,
-                           std::vector<mojom::DataType>{
-                               mojom::DataType::kFloat16,
-                               mojom::DataType::kFloat32}),
+                           std::vector<OperandDataType>{
+                               OperandDataType::kFloat16,
+                               OperandDataType::kFloat32}),
             std::make_pair(mojom::ElementWiseUnary::Kind::kReciprocal,
-                           std::vector<mojom::DataType>{
-                               mojom::DataType::kFloat16,
-                               mojom::DataType::kFloat32}),
+                           std::vector<OperandDataType>{
+                               OperandDataType::kFloat16,
+                               OperandDataType::kFloat32}),
             std::make_pair(
                 mojom::ElementWiseUnary::Kind::kCast,
-                std::vector<mojom::DataType>(kAllOperandDataTypes,
+                std::vector<OperandDataType>(kAllOperandDataTypes,
                                              std::end(kAllOperandDataTypes))),
         }),
         ::testing::ValuesIn(kAllOperandDataTypes),
@@ -1886,8 +1875,8 @@
     // Test building element-wise abs.
     ElementWiseUnaryTester{
         .kind = mojom::ElementWiseUnary::Kind::kAbs,
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {1}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {1}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {1}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {1}},
         .expected = true}
         .Test();
   }
@@ -1895,8 +1884,8 @@
     // Test building element-wise ceil.
     ElementWiseUnaryTester{
         .kind = mojom::ElementWiseUnary::Kind::kCeil,
-        .input = {.type = mojom::DataType::kFloat16, .dimensions = {1}},
-        .output = {.type = mojom::DataType::kFloat16, .dimensions = {1}},
+        .input = {.type = OperandDataType::kFloat16, .dimensions = {1}},
+        .output = {.type = OperandDataType::kFloat16, .dimensions = {1}},
         .expected = true}
         .Test();
   }
@@ -1904,8 +1893,8 @@
     // Test building element-wise cos.
     ElementWiseUnaryTester{
         .kind = mojom::ElementWiseUnary::Kind::kCos,
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {1, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {1, 2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {1, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {1, 2}},
         .expected = true}
         .Test();
   }
@@ -1913,8 +1902,8 @@
     // Test building element-wise exp.
     ElementWiseUnaryTester{
         .kind = mojom::ElementWiseUnary::Kind::kExp,
-        .input = {.type = mojom::DataType::kFloat16, .dimensions = {1, 2}},
-        .output = {.type = mojom::DataType::kFloat16, .dimensions = {1, 2}},
+        .input = {.type = OperandDataType::kFloat16, .dimensions = {1, 2}},
+        .output = {.type = OperandDataType::kFloat16, .dimensions = {1, 2}},
         .expected = true}
         .Test();
   }
@@ -1922,8 +1911,8 @@
     // Test building element-wise floor.
     ElementWiseUnaryTester{
         .kind = mojom::ElementWiseUnary::Kind::kFloor,
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {1, 2, 3}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {1, 2, 3}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {1, 2, 3}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {1, 2, 3}},
         .expected = true}
         .Test();
   }
@@ -1931,17 +1920,17 @@
     // Test building element-wise log.
     ElementWiseUnaryTester{
         .kind = mojom::ElementWiseUnary::Kind::kLog,
-        .input = {.type = mojom::DataType::kFloat16, .dimensions = {1, 2, 3}},
-        .output = {.type = mojom::DataType::kFloat16, .dimensions = {1, 2, 3}},
+        .input = {.type = OperandDataType::kFloat16, .dimensions = {1, 2, 3}},
+        .output = {.type = OperandDataType::kFloat16, .dimensions = {1, 2, 3}},
         .expected = true}
         .Test();
   }
   {
     // Test building element-wise neg.
     ElementWiseUnaryTester{.kind = mojom::ElementWiseUnary::Kind::kNeg,
-                           .input = {.type = mojom::DataType::kFloat32,
+                           .input = {.type = OperandDataType::kFloat32,
                                      .dimensions = {1, 2, 3, 4}},
-                           .output = {.type = mojom::DataType::kFloat32,
+                           .output = {.type = OperandDataType::kFloat32,
                                       .dimensions = {1, 2, 3, 4}},
                            .expected = true}
         .Test();
@@ -1949,9 +1938,9 @@
   {
     // Test building element-wise sin.
     ElementWiseUnaryTester{.kind = mojom::ElementWiseUnary::Kind::kSin,
-                           .input = {.type = mojom::DataType::kFloat16,
+                           .input = {.type = OperandDataType::kFloat16,
                                      .dimensions = {1, 2, 3, 4}},
-                           .output = {.type = mojom::DataType::kFloat16,
+                           .output = {.type = OperandDataType::kFloat16,
                                       .dimensions = {1, 2, 3, 4}},
                            .expected = true}
         .Test();
@@ -1959,9 +1948,9 @@
   {
     // Test building element-wise tan.
     ElementWiseUnaryTester{.kind = mojom::ElementWiseUnary::Kind::kTan,
-                           .input = {.type = mojom::DataType::kFloat32,
+                           .input = {.type = OperandDataType::kFloat32,
                                      .dimensions = {1, 2, 3, 4, 5}},
-                           .output = {.type = mojom::DataType::kFloat32,
+                           .output = {.type = OperandDataType::kFloat32,
                                       .dimensions = {1, 2, 3, 4, 5}},
                            .expected = true}
         .Test();
@@ -1971,8 +1960,8 @@
     // unsupported data type.
     ElementWiseUnaryTester{
         .kind = mojom::ElementWiseUnary::Kind::kAbs,
-        .input = {.type = mojom::DataType::kUint32, .dimensions = {1, 2, 3, 4}},
-        .output = {.type = mojom::DataType::kUint32,
+        .input = {.type = OperandDataType::kUint32, .dimensions = {1, 2, 3, 4}},
+        .output = {.type = OperandDataType::kUint32,
                    .dimensions = {1, 2, 3, 4}},
         .expected = false}
         .Test();
@@ -1982,8 +1971,8 @@
     // unsupported data type.
     ElementWiseUnaryTester{
         .kind = mojom::ElementWiseUnary::Kind::kNeg,
-        .input = {.type = mojom::DataType::kUint8, .dimensions = {1, 2, 3, 4}},
-        .output = {.type = mojom::DataType::kUint8, .dimensions = {1, 2, 3, 4}},
+        .input = {.type = OperandDataType::kUint8, .dimensions = {1, 2, 3, 4}},
+        .output = {.type = OperandDataType::kUint8, .dimensions = {1, 2, 3, 4}},
         .expected = false}
         .Test();
   }
@@ -1992,8 +1981,8 @@
     // unsupported data type.
     ElementWiseUnaryTester{
         .kind = mojom::ElementWiseUnary::Kind::kCeil,
-        .input = {.type = mojom::DataType::kUint32, .dimensions = {1, 2, 3, 4}},
-        .output = {.type = mojom::DataType::kUint32,
+        .input = {.type = OperandDataType::kUint32, .dimensions = {1, 2, 3, 4}},
+        .output = {.type = OperandDataType::kUint32,
                    .dimensions = {1, 2, 3, 4}},
         .expected = false}
         .Test();
@@ -2003,8 +1992,8 @@
     // unsupported data type.
     ElementWiseUnaryTester{
         .kind = mojom::ElementWiseUnary::Kind::kCos,
-        .input = {.type = mojom::DataType::kUint32, .dimensions = {1, 2, 3, 4}},
-        .output = {.type = mojom::DataType::kUint32,
+        .input = {.type = OperandDataType::kUint32, .dimensions = {1, 2, 3, 4}},
+        .output = {.type = OperandDataType::kUint32,
                    .dimensions = {1, 2, 3, 4}},
         .expected = false}
         .Test();
@@ -2014,8 +2003,8 @@
     // unsupported data type.
     ElementWiseUnaryTester{
         .kind = mojom::ElementWiseUnary::Kind::kExp,
-        .input = {.type = mojom::DataType::kUint8, .dimensions = {1, 2, 3, 4}},
-        .output = {.type = mojom::DataType::kUint8, .dimensions = {1, 2, 3, 4}},
+        .input = {.type = OperandDataType::kUint8, .dimensions = {1, 2, 3, 4}},
+        .output = {.type = OperandDataType::kUint8, .dimensions = {1, 2, 3, 4}},
         .expected = false}
         .Test();
   }
@@ -2024,8 +2013,8 @@
     // unsupported data type.
     ElementWiseUnaryTester{
         .kind = mojom::ElementWiseUnary::Kind::kFloor,
-        .input = {.type = mojom::DataType::kInt8, .dimensions = {1, 2, 3, 4}},
-        .output = {.type = mojom::DataType::kInt8, .dimensions = {1, 2, 3, 4}},
+        .input = {.type = OperandDataType::kInt8, .dimensions = {1, 2, 3, 4}},
+        .output = {.type = OperandDataType::kInt8, .dimensions = {1, 2, 3, 4}},
         .expected = false}
         .Test();
   }
@@ -2034,8 +2023,8 @@
     // unsupported data type.
     ElementWiseUnaryTester{
         .kind = mojom::ElementWiseUnary::Kind::kLog,
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {1, 2, 3, 4}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {1, 2, 3, 4}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {1, 2, 3, 4}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {1, 2, 3, 4}},
         .expected = false}
         .Test();
   }
@@ -2044,8 +2033,8 @@
     // unsupported data type.
     ElementWiseUnaryTester{
         .kind = mojom::ElementWiseUnary::Kind::kSin,
-        .input = {.type = mojom::DataType::kUint32, .dimensions = {1, 2, 3, 4}},
-        .output = {.type = mojom::DataType::kUint32,
+        .input = {.type = OperandDataType::kUint32, .dimensions = {1, 2, 3, 4}},
+        .output = {.type = OperandDataType::kUint32,
                    .dimensions = {1, 2, 3, 4}},
         .expected = false}
         .Test();
@@ -2055,8 +2044,8 @@
     // unsupported data type.
     ElementWiseUnaryTester{
         .kind = mojom::ElementWiseUnary::Kind::kTan,
-        .input = {.type = mojom::DataType::kUint32, .dimensions = {1, 2, 3, 4}},
-        .output = {.type = mojom::DataType::kUint32,
+        .input = {.type = OperandDataType::kUint32, .dimensions = {1, 2, 3, 4}},
+        .output = {.type = OperandDataType::kUint32,
                    .dimensions = {1, 2, 3, 4}},
         .expected = false}
         .Test();
@@ -2064,9 +2053,9 @@
   {
     // Test the invalid graph for the input and output shapes don't match.
     ElementWiseUnaryTester{.kind = mojom::ElementWiseUnary::Kind::kAbs,
-                           .input = {.type = mojom::DataType::kFloat32,
+                           .input = {.type = OperandDataType::kFloat32,
                                      .dimensions = {1, 2, 3, 4}},
-                           .output = {.type = mojom::DataType::kFloat32,
+                           .output = {.type = OperandDataType::kFloat32,
                                       .dimensions = {1, 2, 3, 4, 5}},
                            .expected = false}
         .Test();
@@ -2074,9 +2063,9 @@
   {
     // Test the invalid graph for output type don't match.
     ElementWiseUnaryTester{.kind = mojom::ElementWiseUnary::Kind::kCeil,
-                           .input = {.type = mojom::DataType::kFloat32,
+                           .input = {.type = OperandDataType::kFloat32,
                                      .dimensions = {1, 2, 3, 4}},
-                           .output = {.type = mojom::DataType::kFloat16,
+                           .output = {.type = OperandDataType::kFloat16,
                                       .dimensions = {1, 2, 3, 4}},
                            .expected = false}
         .Test();
@@ -2085,8 +2074,8 @@
   {
     ElementWiseUnaryTester{
         .kind = mojom::ElementWiseUnary::Kind::kCast,
-        .input = {.type = mojom::DataType::kUint8, .dimensions = {1, 2, 3, 1}},
-        .output = {.type = mojom::DataType::kInt8, .dimensions = {1, 2, 3, 2}},
+        .input = {.type = OperandDataType::kUint8, .dimensions = {1, 2, 3, 1}},
+        .output = {.type = OperandDataType::kInt8, .dimensions = {1, 2, 3, 2}},
         .expected = false}
         .Test();
   }
@@ -2119,23 +2108,23 @@
   {
     // Test elu operator for 2-D tensor with float32 input.
     EluTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 6}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 6}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 6}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 6}},
         .expected = true}
         .Test();
   }
   {
     // Test the invalid graph when the alpha is less than or equal to 0.
-    EluTester{.input = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-              .output = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+    EluTester{.input = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+              .output = {.type = OperandDataType::kFloat32, .dimensions = {2}},
               .alpha = 0,
               .expected = false}
         .Test();
   }
   {
     // Test the invalid graph when the alpha is NAN.
-    EluTester{.input = {.type = mojom::DataType::kInt32, .dimensions = {2}},
-              .output = {.type = mojom::DataType::kInt32, .dimensions = {2}},
+    EluTester{.input = {.type = OperandDataType::kInt32, .dimensions = {2}},
+              .output = {.type = OperandDataType::kInt32, .dimensions = {2}},
               .alpha = NAN,
               .expected = false}
         .Test();
@@ -2143,23 +2132,23 @@
   {
     // Test the invalid graph for the output shapes are not as expected.
     EluTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output data types which don't match.
-    EluTester{.input = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-              .output = {.type = mojom::DataType::kInt32, .dimensions = {2}},
+    EluTester{.input = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+              .output = {.type = OperandDataType::kInt32, .dimensions = {2}},
               .expected = false}
         .Test();
   }
   {
     // Test the invalid graph when the input data type is not floating
     // point.
-    EluTester{.input = {.type = mojom::DataType::kInt32, .dimensions = {2}},
-              .output = {.type = mojom::DataType::kInt32, .dimensions = {2}},
+    EluTester{.input = {.type = OperandDataType::kInt32, .dimensions = {2}},
+              .output = {.type = OperandDataType::kInt32, .dimensions = {2}},
               .expected = false}
         .Test();
   }
@@ -2168,7 +2157,7 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {2}, OperandDataType::kFloat32);
     builder.BuildElu(input_operand_id, input_operand_id, /*alpha*/ 1.0);
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
                                                builder.GetGraphInfo()));
@@ -2202,16 +2191,16 @@
     // Test building expand with the output shapes that are the same as
     // input.
     ExpandTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 6}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 6}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 6}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 6}},
         .expected = true}
         .Test();
   }
   {
     // Test building expand with the output shapes that are broadcastable.
     ExpandTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {3, 1, 5}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {3, 4, 5}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {3, 1, 5}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {3, 4, 5}},
         .expected = true}
         .Test();
   }
@@ -2219,8 +2208,8 @@
     // Test building expand with the output shapes that are broadcastable
     // and the number of output shapes larger than input.
     ExpandTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {2, 5}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {3, 2, 5}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {2, 5}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {3, 2, 5}},
         .expected = true}
         .Test();
   }
@@ -2228,24 +2217,24 @@
     // Test the invalid graph when the input shapes are not the same as
     // output shape and not broadcastable.
     ExpandTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {3, 6, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {4, 3, 5}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {3, 6, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {4, 3, 5}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph when the input shapes are not broadcastable.
     ExpandTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {5}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {5, 4}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {5}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {5, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output data types which don't match.
     ExpandTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
@@ -2254,7 +2243,7 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {2}, OperandDataType::kFloat32);
     builder.BuildExpand(input_operand_id, input_operand_id);
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
                                                builder.GetGraphInfo()));
@@ -2294,11 +2283,11 @@
   {
     // Test gather operator with 3-D input and 2-D indices.
     GatherTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4, 5}},
-        .attributes = {.indices = {.type = mojom::DataType::kUint32,
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {3, 4, 5}},
+        .attributes = {.indices = {.type = OperandDataType::kUint32,
                                    .dimensions = {6, 7}},
                        .axis = 1},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {3, 6, 7, 5}},
         .expected = true}
         .Test();
@@ -2306,11 +2295,11 @@
   {
     // Test the invalid graph for the axis is too large.
     GatherTester{
-        .input = {.type = mojom::DataType::kFloat16, .dimensions = {3, 4, 5}},
-        .attributes = {.indices = {.type = mojom::DataType::kUint32,
+        .input = {.type = OperandDataType::kFloat16, .dimensions = {3, 4, 5}},
+        .attributes = {.indices = {.type = OperandDataType::kUint32,
                                    .dimensions = {6, 7}},
                        .axis = 3},
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {3, 4, 5, 6, 7}},
         .expected = false}
         .Test();
@@ -2318,11 +2307,11 @@
   {
     // Test the invalid graph for the indices data type is floating point.
     GatherTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4, 5}},
-        .attributes = {.indices = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {3, 4, 5}},
+        .attributes = {.indices = {.type = OperandDataType::kFloat16,
                                    .dimensions = {6, 7}},
                        .axis = 1},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {3, 6, 7, 5}},
         .expected = false}
         .Test();
@@ -2331,11 +2320,11 @@
     // Test the invalid graph for the indices data type is not one of uint32,
     // int32 or int64.
     GatherTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4, 5}},
-        .attributes = {.indices = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {3, 4, 5}},
+        .attributes = {.indices = {.type = OperandDataType::kFloat32,
                                    .dimensions = {6, 7}},
                        .axis = 1},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {3, 6, 7, 5}},
         .expected = false}
         .Test();
@@ -2343,11 +2332,11 @@
   {
     // Test the invalid graph for the output shapes are not expected.
     GatherTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4, 5}},
-        .attributes = {.indices = {.type = mojom::DataType::kUint32,
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {3, 4, 5}},
+        .attributes = {.indices = {.type = OperandDataType::kUint32,
                                    .dimensions = {6, 7}},
                        .axis = 1},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {3, 4, 6, 7, 5}},
         .expected = false}
         .Test();
@@ -2355,11 +2344,11 @@
   {
     // Test the invalid graph for output types don't match.
     GatherTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4, 5}},
-        .attributes = {.indices = {.type = mojom::DataType::kUint32,
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {3, 4, 5}},
+        .attributes = {.indices = {.type = OperandDataType::kUint32,
                                    .dimensions = {6, 7}},
                        .axis = 1},
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {3, 6, 7, 5}},
         .expected = false}
         .Test();
@@ -2369,9 +2358,9 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {2, 3}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {2, 3}, OperandDataType::kFloat32);
     uint64_t indices_operand_id =
-        builder.BuildInput("indices", {2}, mojom::DataType::kUint32);
+        builder.BuildInput("indices", {2}, OperandDataType::kUint32);
     builder.BuildGather(input_operand_id, indices_operand_id, input_operand_id,
                         /*axis*/ 0);
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
@@ -2382,9 +2371,9 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {3}, mojom::DataType::kUint32);
+        builder.BuildInput("input", {3}, OperandDataType::kUint32);
     uint64_t indices_operand_id =
-        builder.BuildInput("indices", {3}, mojom::DataType::kUint32);
+        builder.BuildInput("indices", {3}, OperandDataType::kUint32);
     builder.BuildGather(input_operand_id, indices_operand_id,
                         indices_operand_id, /*axis*/ 0);
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
@@ -2417,30 +2406,30 @@
   {
     // Test gelu operator for 3-D tensor with float32 input.
     GeluTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 6, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 6, 4}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 6, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 6, 4}},
         .expected = true}
         .Test();
   }
   {
     // Test the invalid graph when the input has data type int32.
-    GeluTester{.input = {.type = mojom::DataType::kInt32, .dimensions = {}},
-               .output = {.type = mojom::DataType::kInt32, .dimensions = {}},
+    GeluTester{.input = {.type = OperandDataType::kInt32, .dimensions = {}},
+               .output = {.type = OperandDataType::kInt32, .dimensions = {}},
                .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the output shapes are not expected.
     GeluTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output types don't match.
-    GeluTester{.input = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-               .output = {.type = mojom::DataType::kInt32, .dimensions = {2}},
+    GeluTester{.input = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+               .output = {.type = OperandDataType::kInt32, .dimensions = {2}},
                .expected = false}
         .Test();
   }
@@ -2449,7 +2438,7 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1}, mojom::DataType::kFloat16);
+        builder.BuildInput("input", {1}, OperandDataType::kFloat16);
     builder.BuildGelu(input_operand_id, input_operand_id);
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
                                                builder.GetGraphInfo()));
@@ -2496,9 +2485,9 @@
   {
     // Test building gemm with default option.
     GemmTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
-        .b = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
+        .b = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
         .expected = true}
         .Test();
   }
@@ -2507,10 +2496,10 @@
     // Transposed a_dimensions would be {3, 2} and it's compatible with
     // b_dimensions {2, 4}.
     GemmTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
-        .b = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
+        .b = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
         .attributes = {.a_transpose = true},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
         .expected = true}
         .Test();
   }
@@ -2519,10 +2508,10 @@
     // Transposed b_dimensions would be {3, 4} and it's compatible with
     // a_dimensions {2, 3}.
     GemmTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
-        .b = {.type = mojom::DataType::kFloat32, .dimensions = {4, 3}},
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
+        .b = {.type = OperandDataType::kFloat32, .dimensions = {4, 3}},
         .attributes = {.b_transpose = true},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
         .expected = true}
         .Test();
   }
@@ -2531,10 +2520,10 @@
     // The output dimensions of a * b would be {2, 4} and c_dimensions {4}
     // is able to broadcast to {2, 4}.
     GemmTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
-        .b = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
-        .c = OperandInfo{.type = mojom::DataType::kFloat32, .dimensions = {4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
+        .b = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
+        .c = OperandInfo{.type = OperandDataType::kFloat32, .dimensions = {4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
         .expected = true}
         .Test();
   }
@@ -2542,9 +2531,9 @@
     // Test building gemm with two matrices - {2, 3} and {2, 4} that can't
     // be multiplied together due to incompatible dimensions.
     GemmTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
-        .b = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
+        .b = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
         .expected = false}
         .Test();
   }
@@ -2553,11 +2542,11 @@
     // The output dimensions of a * b would be {2, 4} and c_dimension {2, 3}
     // is incompatible with {2, 4}.
     GemmTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
-        .b = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
-        .c = OperandInfo{.type = mojom::DataType::kFloat32,
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
+        .b = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
+        .c = OperandInfo{.type = OperandDataType::kFloat32,
                          .dimensions = {2, 3}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
         .expected = false}
         .Test();
   }
@@ -2566,38 +2555,38 @@
     // Set optional input C with type = int32 and it mismatches with input
     // type float32.
     GemmTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {3, 2}},
-        .b = {.type = mojom::DataType::kFloat32, .dimensions = {4, 3}},
-        .c = OperandInfo{.type = mojom::DataType::kInt32, .dimensions = {2, 4}},
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {3, 2}},
+        .b = {.type = OperandDataType::kFloat32, .dimensions = {4, 3}},
+        .c = OperandInfo{.type = OperandDataType::kInt32, .dimensions = {2, 4}},
         .attributes = {.a_transpose = true, .b_transpose = true},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph if the input is not floating point.
     GemmTester{
-        .a = {.type = mojom::DataType::kInt32, .dimensions = {2, 3}},
-        .b = {.type = mojom::DataType::kInt32, .dimensions = {3, 4}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {2, 4}},
+        .a = {.type = OperandDataType::kInt32, .dimensions = {2, 3}},
+        .b = {.type = OperandDataType::kInt32, .dimensions = {3, 4}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {2, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the output shapes are not expected.
     GemmTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
-        .b = {.type = mojom::DataType::kInt32, .dimensions = {3, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
+        .b = {.type = OperandDataType::kInt32, .dimensions = {3, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output types don't match.
     GemmTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
-        .b = {.type = mojom::DataType::kInt32, .dimensions = {3, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
+        .b = {.type = OperandDataType::kInt32, .dimensions = {3, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
         .expected = false}
         .Test();
   }
@@ -2682,30 +2671,30 @@
     uint32_t hidden_size = 4;
     uint32_t num_directions = 2;
     GruTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {num_directions, 3 * hidden_size, input_size}},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {num_directions, 3 * hidden_size,
                                             hidden_size}},
         .steps = steps,
         .hidden_size = hidden_size,
-        .bias = OperandInfo{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo{.type = OperandDataType::kFloat32,
                             .dimensions = {num_directions, 3 * hidden_size}},
         .recurrent_bias =
-            OperandInfo{.type = mojom::DataType::kFloat32,
+            OperandInfo{.type = OperandDataType::kFloat32,
                         .dimensions = {num_directions, 3 * hidden_size}},
         .initial_hidden_state =
             OperandInfo{
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {num_directions, batch_size, hidden_size}},
         .attributes = {.reset_after = true,
                        .return_sequence = true,
                        .direction = mojom::RecurrentNetworkDirection::kBoth},
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {num_directions, batch_size, hidden_size}},
-                    {.type = mojom::DataType::kFloat32,
+                    {.type = OperandDataType::kFloat32,
                      .dimensions = {steps, num_directions, batch_size,
                                     hidden_size}}},
         .expected = true}
@@ -2719,16 +2708,16 @@
     uint32_t hidden_size = 4;
     uint32_t num_directions = 1;
     GruTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {num_directions, 4 * hidden_size, input_size}},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {num_directions, 3 * hidden_size,
                                             hidden_size}},
         .steps = steps,
         .hidden_size = hidden_size,
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {num_directions, batch_size, hidden_size}}},
         .expected = false}
         .Test();
@@ -2741,11 +2730,11 @@
     uint32_t hidden_size = 4;
     uint32_t num_directions = 1;
     GruTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {num_directions, 3 * hidden_size, input_size}},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {num_directions, 3 * hidden_size,
                                             hidden_size}},
         .steps = steps,
@@ -2756,7 +2745,7 @@
                                            mojom::Activation::Tag::kSigmoid},
                             Activation{.kind = mojom::Activation::Tag::kTanh},
                             Activation{.kind = mojom::Activation::Tag::kTanh}}},
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {num_directions, batch_size, hidden_size}}},
         .expected = false}
         .Test();
@@ -2770,11 +2759,11 @@
     uint32_t hidden_size = 4;
     uint32_t num_directions = 1;
     GruTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {num_directions, 3 * hidden_size, input_size}},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {num_directions, 3 * hidden_size,
                                             hidden_size}},
         .steps = steps,
@@ -2786,7 +2775,7 @@
                              Activation{
                                  .kind = mojom::Activation::Tag::kLeakyRelu,
                                  .leaky_relu_alpha = NAN}}},
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {num_directions, batch_size, hidden_size}}},
         .expected = false}
         .Test();
@@ -2799,16 +2788,16 @@
     uint32_t hidden_size = 4;
     uint32_t num_directions = 1;
     GruTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {num_directions, 3 * hidden_size, input_size}},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {num_directions, 3 * hidden_size,
                                             hidden_size}},
         .steps = steps,
         .hidden_size = hidden_size,
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {num_directions, batch_size,
                                     3 * hidden_size}}},
         .expected = false}
@@ -2822,18 +2811,18 @@
     uint32_t hidden_size = 4;
     uint32_t num_directions = 1;
     GruTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {num_directions, 3 * hidden_size, input_size}},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {num_directions, 3 * hidden_size,
                                             hidden_size}},
         .steps = steps,
         .hidden_size = hidden_size,
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {num_directions, batch_size, hidden_size}},
-                    {.type = mojom::DataType::kFloat32,
+                    {.type = OperandDataType::kFloat32,
                      .dimensions = {steps, num_directions, batch_size,
                                     hidden_size}}},
         .expected = false}
@@ -2851,17 +2840,17 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id = builder.BuildInput(
-        "input", {steps, batch_size, input_size}, mojom::DataType::kFloat32);
+        "input", {steps, batch_size, input_size}, OperandDataType::kFloat32);
     uint64_t weight_operand_id = builder.BuildInput(
         "weight", {num_directions, 3 * hidden_size, input_size},
-        mojom::DataType::kFloat32);
+        OperandDataType::kFloat32);
     uint64_t recurrent_weight_operand_id = builder.BuildInput(
         "recurrentWeight", {num_directions, 3 * hidden_size, hidden_size},
-        mojom::DataType::kFloat32);
+        OperandDataType::kFloat32);
 
     uint64_t initial_hidden_state_operand_id = builder.BuildInput(
         "initialHiddenState", {num_directions, batch_size, hidden_size},
-        mojom::DataType::kFloat32);
+        OperandDataType::kFloat32);
 
     builder.BuildGru(
         input_operand_id, weight_operand_id, recurrent_weight_operand_id,
@@ -2935,20 +2924,20 @@
   uint32_t input_size = 4;
   uint32_t hidden_size = 6;
 
-  OperandInfo valid_input = {.type = mojom::DataType::kFloat32,
+  OperandInfo valid_input = {.type = OperandDataType::kFloat32,
                              .dimensions = {batch_size, input_size}};
-  OperandInfo valid_weight = {.type = mojom::DataType::kFloat32,
+  OperandInfo valid_weight = {.type = OperandDataType::kFloat32,
                               .dimensions = {3 * hidden_size, input_size}};
   OperandInfo valid_recurrent_weight = {
-      .type = mojom::DataType::kFloat32,
+      .type = OperandDataType::kFloat32,
       .dimensions = {3 * hidden_size, hidden_size}};
-  OperandInfo valid_hidden_state = {.type = mojom::DataType::kFloat32,
+  OperandInfo valid_hidden_state = {.type = OperandDataType::kFloat32,
                                     .dimensions = {batch_size, hidden_size}};
-  OperandInfo valid_bias = {.type = mojom::DataType::kFloat32,
+  OperandInfo valid_bias = {.type = OperandDataType::kFloat32,
                             .dimensions = {3 * hidden_size}};
-  OperandInfo valid_recurrent_bias = {.type = mojom::DataType::kFloat32,
+  OperandInfo valid_recurrent_bias = {.type = OperandDataType::kFloat32,
                                       .dimensions = {3 * hidden_size}};
-  OperandInfo valid_output = {.type = mojom::DataType::kFloat32,
+  OperandInfo valid_output = {.type = OperandDataType::kFloat32,
                               .dimensions = {batch_size, hidden_size}};
 
   {
@@ -2967,7 +2956,7 @@
   }
   {
     // Test the invalid graph when the data type of the input is incorrect.
-    GruCellTester{.input = {.type = mojom::DataType::kInt8,
+    GruCellTester{.input = {.type = OperandDataType::kInt8,
                             .dimensions = {batch_size, input_size}},
                   .weight = valid_weight,
                   .recurrent_weight = valid_recurrent_weight,
@@ -2982,7 +2971,7 @@
   }
   {
     // Test the invalid graph when the shape of the input is incorrect.
-    GruCellTester{.input = {.type = mojom::DataType::kFloat32,
+    GruCellTester{.input = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, input_size}},
                   .weight = valid_weight,
                   .recurrent_weight = valid_recurrent_weight,
@@ -2997,7 +2986,7 @@
   }
   {
     // Test the invalid graph when the rank of the input is incorrect.
-    GruCellTester{.input = {.type = mojom::DataType::kFloat32,
+    GruCellTester{.input = {.type = OperandDataType::kFloat32,
                             .dimensions = {input_size}},
                   .weight = valid_weight,
                   .recurrent_weight = valid_recurrent_weight,
@@ -3013,7 +3002,7 @@
   {
     // Test the invalid graph when the data type of the weight is incorrect.
     GruCellTester{.input = valid_input,
-                  .weight = {.type = mojom::DataType::kInt8,
+                  .weight = {.type = OperandDataType::kInt8,
                              .dimensions = {3 * hidden_size, input_size}},
                   .recurrent_weight = valid_recurrent_weight,
                   .hidden_state = valid_hidden_state,
@@ -3028,7 +3017,7 @@
   {
     // Test the invalid graph when the shape of the weight is incorrect.
     GruCellTester{.input = valid_input,
-                  .weight = {.type = mojom::DataType::kFloat32,
+                  .weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {4 * hidden_size, input_size}},
                   .recurrent_weight = valid_recurrent_weight,
                   .hidden_state = valid_hidden_state,
@@ -3043,7 +3032,7 @@
   {
     // Test the invalid graph when the rank of the weight is incorrect.
     GruCellTester{.input = valid_input,
-                  .weight = {.type = mojom::DataType::kFloat32,
+                  .weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {3 * hidden_size}},
                   .recurrent_weight = valid_recurrent_weight,
                   .hidden_state = valid_hidden_state,
@@ -3061,7 +3050,7 @@
     GruCellTester{
         .input = valid_input,
         .weight = valid_weight,
-        .recurrent_weight = {.type = mojom::DataType::kInt8,
+        .recurrent_weight = {.type = OperandDataType::kInt8,
                              .dimensions = {3 * hidden_size, hidden_size}},
         .hidden_state = valid_hidden_state,
         .hidden_size = hidden_size,
@@ -3078,7 +3067,7 @@
     GruCellTester{
         .input = valid_input,
         .weight = valid_weight,
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {3 * hidden_size, input_size}},
         .hidden_state = valid_hidden_state,
         .hidden_size = hidden_size,
@@ -3094,7 +3083,7 @@
     // incorrect.
     GruCellTester{.input = valid_input,
                   .weight = valid_weight,
-                  .recurrent_weight = {.type = mojom::DataType::kFloat32,
+                  .recurrent_weight = {.type = OperandDataType::kFloat32,
                                        .dimensions = {3 * hidden_size}},
                   .hidden_state = valid_hidden_state,
                   .hidden_size = hidden_size,
@@ -3126,7 +3115,7 @@
                   .recurrent_weight = valid_recurrent_weight,
                   .hidden_state = valid_hidden_state,
                   .hidden_size = hidden_size,
-                  .bias = OperandInfo{.type = mojom::DataType::kUint8,
+                  .bias = OperandInfo{.type = OperandDataType::kUint8,
                                       .dimensions = {3 * hidden_size}},
                   .recurrent_bias = valid_recurrent_bias,
                   .attributes = {.reset_after = true},
@@ -3141,7 +3130,7 @@
                   .recurrent_weight = valid_recurrent_weight,
                   .hidden_state = valid_hidden_state,
                   .hidden_size = hidden_size,
-                  .bias = OperandInfo{.type = mojom::DataType::kFloat32,
+                  .bias = OperandInfo{.type = OperandDataType::kFloat32,
                                       .dimensions = {4 * hidden_size}},
                   .recurrent_bias = valid_recurrent_bias,
                   .attributes = {.reset_after = true},
@@ -3157,7 +3146,7 @@
         .recurrent_weight = valid_recurrent_weight,
         .hidden_state = valid_hidden_state,
         .hidden_size = hidden_size,
-        .bias = OperandInfo{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo{.type = OperandDataType::kFloat32,
                             .dimensions = {3 * hidden_size, hidden_size}},
         .recurrent_bias = valid_recurrent_bias,
         .attributes = {.reset_after = true},
@@ -3175,7 +3164,7 @@
         .hidden_state = valid_hidden_state,
         .hidden_size = hidden_size,
         .bias = valid_bias,
-        .recurrent_bias = OperandInfo{.type = mojom::DataType::kUint8,
+        .recurrent_bias = OperandInfo{.type = OperandDataType::kUint8,
                                       .dimensions = {3 * hidden_size}},
         .attributes = {.reset_after = true},
         .output = valid_output,
@@ -3191,7 +3180,7 @@
         .hidden_state = valid_hidden_state,
         .hidden_size = hidden_size,
         .bias = valid_bias,
-        .recurrent_bias = OperandInfo{.type = mojom::DataType::kFloat32,
+        .recurrent_bias = OperandInfo{.type = OperandDataType::kFloat32,
                                       .dimensions = {4 * hidden_size}},
         .attributes = {.reset_after = true},
         .output = valid_output,
@@ -3207,7 +3196,7 @@
                   .hidden_size = hidden_size,
                   .bias = valid_bias,
                   .recurrent_bias =
-                      OperandInfo{.type = mojom::DataType::kFloat32,
+                      OperandInfo{.type = OperandDataType::kFloat32,
                                   .dimensions = {3 * hidden_size, hidden_size}},
                   .attributes = {.reset_after = true},
                   .output = valid_output,
@@ -3260,7 +3249,7 @@
                   .bias = valid_bias,
                   .recurrent_bias = valid_recurrent_bias,
                   .attributes = {.reset_after = true},
-                  .output = {.type = mojom::DataType::kInt32,
+                  .output = {.type = OperandDataType::kInt32,
                              .dimensions = {batch_size, hidden_size}},
                   .expected = false}
         .Test();
@@ -3275,7 +3264,7 @@
                   .bias = valid_bias,
                   .recurrent_bias = valid_recurrent_bias,
                   .attributes = {.reset_after = true},
-                  .output = {.type = mojom::DataType::kFloat32,
+                  .output = {.type = OperandDataType::kFloat32,
                              .dimensions = {batch_size, 3 * hidden_size}},
                   .expected = false}
         .Test();
@@ -3290,7 +3279,7 @@
                   .bias = valid_bias,
                   .recurrent_bias = valid_recurrent_bias,
                   .attributes = {.reset_after = true},
-                  .output = {.type = mojom::DataType::kFloat32,
+                  .output = {.type = OperandDataType::kFloat32,
                              .dimensions = {hidden_size}},
                   .expected = false}
         .Test();
@@ -3301,15 +3290,15 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id = builder.BuildInput(
-        "input", {batch_size, input_size}, mojom::DataType::kFloat32);
+        "input", {batch_size, input_size}, OperandDataType::kFloat32);
     uint64_t weight_operand_id = builder.BuildInput(
-        "weight", {3 * hidden_size, input_size}, mojom::DataType::kFloat32);
+        "weight", {3 * hidden_size, input_size}, OperandDataType::kFloat32);
     uint64_t recurrent_weight_operand_id =
         builder.BuildInput("recurrentWeight", {3 * hidden_size, hidden_size},
-                           mojom::DataType::kFloat32);
+                           OperandDataType::kFloat32);
 
     uint64_t hidden_state_operand_id = builder.BuildInput(
-        "hiddenState", {batch_size, hidden_size}, mojom::DataType::kFloat32);
+        "hiddenState", {batch_size, hidden_size}, OperandDataType::kFloat32);
 
     builder.BuildGruCell(input_operand_id, weight_operand_id,
                          recurrent_weight_operand_id, hidden_state_operand_id,
@@ -3364,9 +3353,9 @@
 TEST_F(WebNNGraphImplTest, InstanceNormalizationTest) {
   {
     // Test building instanceNormalization with default option.
-    InstanceNormalizationTester{.input = {.type = mojom::DataType::kFloat32,
+    InstanceNormalizationTester{.input = {.type = OperandDataType::kFloat32,
                                           .dimensions = {1, 2, 3, 3}},
-                                .output = {.type = mojom::DataType::kFloat32,
+                                .output = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 2, 3, 3}},
                                 .expected = true}
         .Test();
@@ -3374,14 +3363,14 @@
   {
     // Test building instanceNormalization with layout = kChannelsLast.
     InstanceNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
         .scale =
-            OperandInfo{.type = mojom::DataType::kFloat32, .dimensions = {3}},
+            OperandInfo{.type = OperandDataType::kFloat32, .dimensions = {3}},
         .bias =
-            OperandInfo{.type = mojom::DataType::kFloat32, .dimensions = {3}},
+            OperandInfo{.type = OperandDataType::kFloat32, .dimensions = {3}},
         .attributes = {.layout = mojom::InputOperandLayout::kChannelsLast},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = true}
         .Test();
@@ -3389,13 +3378,13 @@
   {
     // Test building instanceNormalization with default layout = kChannelsFirst.
     InstanceNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
         .scale =
-            OperandInfo{.type = mojom::DataType::kFloat32, .dimensions = {2}},
+            OperandInfo{.type = OperandDataType::kFloat32, .dimensions = {2}},
         .bias =
-            OperandInfo{.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kFloat32,
+            OperandInfo{.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = true}
         .Test();
@@ -3404,11 +3393,11 @@
     // Test instanceNormalization when input data type and scale data type
     // mismatched.
     InstanceNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
         .scale =
-            OperandInfo{.type = mojom::DataType::kInt32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kFloat32,
+            OperandInfo{.type = OperandDataType::kInt32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
@@ -3417,11 +3406,11 @@
     // Test building instanceNormalization when the size of scale is not equal
     // to the size of the feature dimension of the input.
     InstanceNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
         .scale =
-            OperandInfo{.type = mojom::DataType::kFloat32, .dimensions = {3}},
-        .output = {.type = mojom::DataType::kFloat32,
+            OperandInfo{.type = OperandDataType::kFloat32, .dimensions = {3}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
@@ -3430,10 +3419,10 @@
     // Test instanceNormalization when input data type and bias data type
     // mismatched.
     InstanceNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
-        .bias = OperandInfo{.type = mojom::DataType::kInt32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo{.type = OperandDataType::kInt32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
@@ -3442,12 +3431,12 @@
     // Test building instanceNormalization when the size of bias is not equal
     // to the size of the feature dimension of the input.
     InstanceNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
         .bias =
-            OperandInfo{.type = mojom::DataType::kFloat32, .dimensions = {2}},
+            OperandInfo{.type = OperandDataType::kFloat32, .dimensions = {2}},
         .attributes = {.layout = mojom::InputOperandLayout::kChannelsLast},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
@@ -3455,17 +3444,17 @@
   {
     // Test the invalid graph for output type is not the same as input type.
     InstanceNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 3}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {1, 2, 3, 3}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output shape is not the same as input shape.
-    InstanceNormalizationTester{.input = {.type = mojom::DataType::kFloat32,
+    InstanceNormalizationTester{.input = {.type = OperandDataType::kFloat32,
                                           .dimensions = {1, 2, 3, 3}},
-                                .output = {.type = mojom::DataType::kFloat32,
+                                .output = {.type = OperandDataType::kFloat32,
                                            .dimensions = {1, 1, 3, 3}},
                                 .expected = false}
         .Test();
@@ -3473,8 +3462,8 @@
   {
     // Test the invalid graph for input is not a 4-D tensor.
     InstanceNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {1, 2, 3}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {1, 2, 3}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {1, 2, 3}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {1, 2, 3}},
         .expected = false}
         .Test();
   }
@@ -3483,7 +3472,7 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
     builder.BuildInstanceNormalization(
         input_operand_id, input_operand_id,
         InstanceNormalizationTester::InstanceNormalizationAttributes{});
@@ -3495,9 +3484,9 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
     uint64_t scale_operand_id =
-        builder.BuildInput("scale", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("scale", {2}, OperandDataType::kFloat32);
 
     InstanceNormalizationTester::InstanceNormalizationAttributes attributes;
     attributes.scale_operand_id = scale_operand_id;
@@ -3512,9 +3501,9 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
     uint64_t bias_operand_id =
-        builder.BuildInput("bias", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("bias", {2}, OperandDataType::kFloat32);
 
     InstanceNormalizationTester::InstanceNormalizationAttributes attributes;
     attributes.bias_operand_id = bias_operand_id;
@@ -3570,23 +3559,23 @@
   {
     // Test building layerNormalization with default option for scalar input.
     LayerNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {}},
         .attributes = {.axes = {}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {}},
         .expected = true}
         .Test();
   }
   {
     // Test building layerNormalization with 4-D input.
     LayerNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 2, 3, 4}},
-        .scale = OperandInfo{.type = mojom::DataType::kFloat16,
+        .scale = OperandInfo{.type = OperandDataType::kFloat16,
                              .dimensions = {3, 4}},
-        .bias = OperandInfo{.type = mojom::DataType::kFloat16,
+        .bias = OperandInfo{.type = OperandDataType::kFloat16,
                             .dimensions = {3, 4}},
         .attributes = {.axes = {2, 3}},
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 2, 3, 4}},
         .expected = true}
         .Test();
@@ -3595,48 +3584,48 @@
     // Test the invalid graph when the input is a scalar and the axes is not
     // empty.
     LayerNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {}},
         .attributes = {.axes = {0}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the input data type is int64.
     LayerNormalizationTester{
-        .input = {.type = mojom::DataType::kInt64, .dimensions = {1}},
+        .input = {.type = OperandDataType::kInt64, .dimensions = {1}},
         .attributes = {.axes = {}},
-        .output = {.type = mojom::DataType::kInt64, .dimensions = {1}},
+        .output = {.type = OperandDataType::kInt64, .dimensions = {1}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the axes have duplications.
     LayerNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {1, 2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {1, 2}},
         .attributes = {.axes = {0, 0}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {1, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {1, 2}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the axis is greater than the input rank.
     LayerNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {1, 2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {1, 2}},
         .attributes = {.axes = {2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {1, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {1, 2}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the bias type doesn't match the input type.
     LayerNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 2, 3, 4}},
-        .bias = OperandInfo{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo{.type = OperandDataType::kFloat32,
                             .dimensions = {3, 4}},
         .attributes = {.axes = {2, 3}},
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 2, 3, 4}},
         .expected = false}
         .Test();
@@ -3645,32 +3634,32 @@
     // Test the invalid graph for the scale shape doesn't match the reduction
     // dimensions.
     LayerNormalizationTester{
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 2, 3, 4}},
-        .scale = OperandInfo{.type = mojom::DataType::kFloat16,
+        .scale = OperandInfo{.type = OperandDataType::kFloat16,
                              .dimensions = {2, 3}},
         .attributes = {.axes = {2, 3}},
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 2, 3, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the output shapes are not expected.
-    LayerNormalizationTester{.input = {.type = mojom::DataType::kFloat16,
+    LayerNormalizationTester{.input = {.type = OperandDataType::kFloat16,
                                        .dimensions = {1, 2, 3, 4}},
                              .attributes = {.axes = {}},
-                             .output = {.type = mojom::DataType::kFloat16,
+                             .output = {.type = OperandDataType::kFloat16,
                                         .dimensions = {1, 2, 3, 3}},
                              .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the output type doesn't match the input type.
-    LayerNormalizationTester{.input = {.type = mojom::DataType::kFloat16,
+    LayerNormalizationTester{.input = {.type = OperandDataType::kFloat16,
                                        .dimensions = {1, 2, 3, 4}},
                              .attributes = {.axes = {}},
-                             .output = {.type = mojom::DataType::kFloat32,
+                             .output = {.type = OperandDataType::kFloat32,
                                         .dimensions = {1, 2, 3, 4}},
                              .expected = false}
         .Test();
@@ -3680,7 +3669,7 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
     builder.BuildLayerNormalization(
         input_operand_id, input_operand_id,
         LayerNormalizationTester::LayerNormalizationAttributes{});
@@ -3692,9 +3681,9 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
     uint64_t scale_operand_id =
-        builder.BuildInput("scale", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("scale", {1, 2, 3, 4}, OperandDataType::kFloat32);
 
     LayerNormalizationTester::LayerNormalizationAttributes attributes;
     attributes.scale_operand_id = scale_operand_id;
@@ -3710,9 +3699,9 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 2, 3, 4}, OperandDataType::kFloat32);
     uint64_t bias_operand_id =
-        builder.BuildInput("bias", {1, 2, 3, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("bias", {1, 2, 3, 4}, OperandDataType::kFloat32);
 
     LayerNormalizationTester::LayerNormalizationAttributes attributes;
     attributes.bias_operand_id = bias_operand_id;
@@ -3818,39 +3807,39 @@
     uint32_t hidden_size = 4;
     uint32_t direction_count = 2;
     LstmTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {direction_count, 4 * hidden_size,
                                   input_size}},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {direction_count, 4 * hidden_size,
                                             hidden_size}},
         .steps = steps,
         .hidden_size = hidden_size,
-        .bias = OperandInfo{.type = mojom::DataType::kFloat32,
+        .bias = OperandInfo{.type = OperandDataType::kFloat32,
                             .dimensions = {direction_count, 4 * hidden_size}},
         .recurrent_bias =
-            OperandInfo{.type = mojom::DataType::kFloat32,
+            OperandInfo{.type = OperandDataType::kFloat32,
                         .dimensions = {direction_count, 4 * hidden_size}},
         .peephole_weight =
-            OperandInfo{.type = mojom::DataType::kFloat32,
+            OperandInfo{.type = OperandDataType::kFloat32,
                         .dimensions = {direction_count, 3 * hidden_size}},
         .initial_hidden_state =
             OperandInfo{
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {direction_count, batch_size, hidden_size}},
         .initial_cell_state =
             OperandInfo{
-                .type = mojom::DataType::kFloat32,
+                .type = OperandDataType::kFloat32,
                 .dimensions = {direction_count, batch_size, hidden_size}},
         .attributes = {.return_sequence = true,
                        .direction = mojom::RecurrentNetworkDirection::kBoth},
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {direction_count, batch_size, hidden_size}},
-                    {.type = mojom::DataType::kFloat32,
+                    {.type = OperandDataType::kFloat32,
                      .dimensions = {direction_count, batch_size, hidden_size}},
-                    {.type = mojom::DataType::kFloat32,
+                    {.type = OperandDataType::kFloat32,
                      .dimensions = {steps, direction_count, batch_size,
                                     hidden_size}}},
         .expected = true}
@@ -3864,18 +3853,18 @@
     uint32_t hidden_size = 4;
     uint32_t direction_count = 1;
     LstmTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {direction_count, 4 * hidden_size, 1000}},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {direction_count, 4 * hidden_size,
                                             hidden_size}},
         .steps = steps,
         .hidden_size = hidden_size,
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {direction_count, batch_size, hidden_size}},
-                    {.type = mojom::DataType::kFloat32,
+                    {.type = OperandDataType::kFloat32,
                      .dimensions = {direction_count, batch_size, hidden_size}}},
         .expected = false}
         .Test();
@@ -3889,12 +3878,12 @@
     uint32_t hidden_size = 4;
     uint32_t direction_count = 1;
     LstmTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {direction_count, 4 * hidden_size,
                                   input_size}},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {direction_count, 4 * hidden_size,
                                             hidden_size}},
         .steps = steps,
@@ -3907,9 +3896,9 @@
                              Activation{
                                  .kind = mojom::Activation::Tag::kLeakyRelu,
                                  .leaky_relu_alpha = NAN}}},
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {direction_count, batch_size, hidden_size}},
-                    {.type = mojom::DataType::kFloat32,
+                    {.type = OperandDataType::kFloat32,
                      .dimensions = {direction_count, batch_size, hidden_size}}},
         .expected = false}
         .Test();
@@ -3922,19 +3911,19 @@
     uint32_t hidden_size = 4;
     uint32_t direction_count = 1;
     LstmTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {steps, batch_size, input_size}},
-        .weight = {.type = mojom::DataType::kFloat32,
+        .weight = {.type = OperandDataType::kFloat32,
                    .dimensions = {direction_count, 4 * hidden_size,
                                   input_size}},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
+        .recurrent_weight = {.type = OperandDataType::kFloat32,
                              .dimensions = {direction_count, 4 * hidden_size,
                                             hidden_size}},
         .steps = steps,
         .hidden_size = hidden_size,
-        .outputs = {{.type = mojom::DataType::kFloat32,
+        .outputs = {{.type = OperandDataType::kFloat32,
                      .dimensions = {direction_count, batch_size, hidden_size}},
-                    {.type = mojom::DataType::kFloat32,
+                    {.type = OperandDataType::kFloat32,
                      .dimensions = {direction_count, batch_size, 1000}}},
         .expected = false}
         .Test();
@@ -3951,17 +3940,17 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id = builder.BuildInput(
-        "input", {steps, batch_size, input_size}, mojom::DataType::kFloat32);
+        "input", {steps, batch_size, input_size}, OperandDataType::kFloat32);
     uint64_t weight_operand_id = builder.BuildInput(
         "weight", {direction_count, 4 * hidden_size, input_size},
-        mojom::DataType::kFloat32);
+        OperandDataType::kFloat32);
     uint64_t recurrent_weight_operand_id = builder.BuildInput(
         "recurrentWeight", {direction_count, 4 * hidden_size, hidden_size},
-        mojom::DataType::kFloat32);
+        OperandDataType::kFloat32);
 
     uint64_t output_operand_id = builder.BuildOutput(
         "output", {direction_count, batch_size, hidden_size},
-        mojom::DataType::kFloat32);
+        OperandDataType::kFloat32);
     builder.BuildLstm(input_operand_id, weight_operand_id,
                       recurrent_weight_operand_id,
                       {output_operand_id, recurrent_weight_operand_id}, steps,
@@ -3981,20 +3970,20 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id = builder.BuildInput(
-        "input", {steps, batch_size, input_size}, mojom::DataType::kFloat32);
+        "input", {steps, batch_size, input_size}, OperandDataType::kFloat32);
     uint64_t weight_operand_id = builder.BuildInput(
         "weight", {direction_count, 4 * hidden_size, input_size},
-        mojom::DataType::kFloat32);
+        OperandDataType::kFloat32);
     uint64_t recurrent_weight_operand_id = builder.BuildInput(
         "recurrentWeight", {direction_count, 4 * hidden_size, hidden_size},
-        mojom::DataType::kFloat32);
+        OperandDataType::kFloat32);
 
     uint64_t initial_cell_state_operand_id = builder.BuildInput(
         "initialCellState", {direction_count, batch_size, hidden_size},
-        mojom::DataType::kFloat32);
+        OperandDataType::kFloat32);
     uint64_t output_operand_id = builder.BuildOutput(
         "output", {direction_count, batch_size, hidden_size},
-        mojom::DataType::kFloat32);
+        OperandDataType::kFloat32);
 
     builder.BuildLstm(
         input_operand_id, weight_operand_id, recurrent_weight_operand_id,
@@ -4083,27 +4072,27 @@
   uint32_t input_size = 12;
   uint32_t hidden_size = 20;
 
-  OperandInfo valid_input = {.type = mojom::DataType::kFloat32,
+  OperandInfo valid_input = {.type = OperandDataType::kFloat32,
                              .dimensions = {batch_size, input_size}};
-  OperandInfo valid_weight = {.type = mojom::DataType::kFloat32,
+  OperandInfo valid_weight = {.type = OperandDataType::kFloat32,
                               .dimensions = {4 * hidden_size, input_size}};
   OperandInfo valid_recurrent_weight = {
-      .type = mojom::DataType::kFloat32,
+      .type = OperandDataType::kFloat32,
       .dimensions = {4 * hidden_size, hidden_size}};
-  OperandInfo valid_hidden_state = {.type = mojom::DataType::kFloat32,
+  OperandInfo valid_hidden_state = {.type = OperandDataType::kFloat32,
                                     .dimensions = {batch_size, hidden_size}};
-  OperandInfo valid_cell_state = {.type = mojom::DataType::kFloat32,
+  OperandInfo valid_cell_state = {.type = OperandDataType::kFloat32,
                                   .dimensions = {batch_size, hidden_size}};
-  OperandInfo valid_bias = {.type = mojom::DataType::kFloat32,
+  OperandInfo valid_bias = {.type = OperandDataType::kFloat32,
                             .dimensions = {4 * hidden_size}};
-  OperandInfo valid_recurrent_bias = {.type = mojom::DataType::kFloat32,
+  OperandInfo valid_recurrent_bias = {.type = OperandDataType::kFloat32,
                                       .dimensions = {4 * hidden_size}};
-  OperandInfo valid_peephole_weight = {.type = mojom::DataType::kFloat32,
+  OperandInfo valid_peephole_weight = {.type = OperandDataType::kFloat32,
                                        .dimensions = {3 * hidden_size}};
   std::vector<OperandInfo> valid_outputs = {
-      {.type = mojom::DataType::kFloat32,
+      {.type = OperandDataType::kFloat32,
        .dimensions = {batch_size, hidden_size}},
-      {.type = mojom::DataType::kFloat32,
+      {.type = OperandDataType::kFloat32,
        .dimensions = {batch_size, hidden_size}}};
   {
     // Test a valid lstmCell operator.
@@ -4123,7 +4112,7 @@
   {
     // Test the invalid graph when the data type of the input is not one of the
     // floating point types.
-    LstmCellTester{.input = {.type = mojom::DataType::kUint32,
+    LstmCellTester{.input = {.type = OperandDataType::kUint32,
                              .dimensions = {batch_size, input_size}},
                    .weight = valid_weight,
                    .recurrent_weight = valid_recurrent_weight,
@@ -4137,7 +4126,7 @@
   {
     // Test the invalid graph when the data type of the weight is incorrect.
     LstmCellTester{.input = valid_input,
-                   .weight = {.type = mojom::DataType::kFloat16,
+                   .weight = {.type = OperandDataType::kFloat16,
                               .dimensions = {4 * hidden_size, input_size}},
                    .recurrent_weight = valid_recurrent_weight,
                    .hidden_state = valid_hidden_state,
@@ -4152,7 +4141,7 @@
     // incorrect.
     LstmCellTester{.input = valid_input,
                    .weight = valid_weight,
-                   .recurrent_weight = {.type = mojom::DataType::kFloat32,
+                   .recurrent_weight = {.type = OperandDataType::kFloat32,
                                         .dimensions = {4 * hidden_size}},
                    .hidden_state = valid_hidden_state,
                    .cell_state = valid_cell_state,
@@ -4166,7 +4155,7 @@
     LstmCellTester{.input = valid_input,
                    .weight = valid_weight,
                    .recurrent_weight = valid_recurrent_weight,
-                   .hidden_state = {.type = mojom::DataType::kFloat32,
+                   .hidden_state = {.type = OperandDataType::kFloat32,
                                     .dimensions = {batch_size, 1000}},
                    .cell_state = valid_cell_state,
                    .hidden_size = hidden_size,
@@ -4181,7 +4170,7 @@
         .weight = valid_weight,
         .recurrent_weight = valid_recurrent_weight,
         .hidden_state = valid_hidden_state,
-        .cell_state = {.type = mojom::DataType::kFloat32,
+        .cell_state = {.type = OperandDataType::kFloat32,
                        .dimensions = {batch_size, hidden_size, 1000}},
         .hidden_size = hidden_size,
         .outputs = valid_outputs,
@@ -4196,7 +4185,7 @@
                    .hidden_state = valid_hidden_state,
                    .cell_state = valid_cell_state,
                    .hidden_size = hidden_size,
-                   .bias = OperandInfo{.type = mojom::DataType::kUint32,
+                   .bias = OperandInfo{.type = OperandDataType::kUint32,
                                        .dimensions = {4 * hidden_size}},
                    .outputs = valid_outputs,
                    .expected = false}
@@ -4211,7 +4200,7 @@
         .hidden_state = valid_hidden_state,
         .cell_state = valid_cell_state,
         .hidden_size = hidden_size,
-        .recurrent_bias = OperandInfo{.type = mojom::DataType::kFloat32,
+        .recurrent_bias = OperandInfo{.type = OperandDataType::kFloat32,
                                       .dimensions = {1000}},
         .outputs = valid_outputs,
         .expected = false}
@@ -4227,7 +4216,7 @@
         .hidden_state = valid_hidden_state,
         .cell_state = valid_cell_state,
         .hidden_size = hidden_size,
-        .peephole_weight = OperandInfo{.type = mojom::DataType::kInt64,
+        .peephole_weight = OperandInfo{.type = OperandDataType::kInt64,
                                        .dimensions = {3 * hidden_size}},
         .outputs = valid_outputs,
         .expected = false}
@@ -4241,9 +4230,9 @@
                    .hidden_state = valid_hidden_state,
                    .cell_state = valid_cell_state,
                    .hidden_size = hidden_size,
-                   .outputs = {{.type = mojom::DataType::kInt8,
+                   .outputs = {{.type = OperandDataType::kInt8,
                                 .dimensions = {batch_size, hidden_size}},
-                               {.type = mojom::DataType::kInt8,
+                               {.type = OperandDataType::kInt8,
                                 .dimensions = {batch_size, hidden_size}}},
                    .expected = false}
         .Test();
@@ -4270,45 +4259,23 @@
         .Test();
   }
   {
-    // Test the invalid graph when the hidden size is too large.
-    uint32_t invalid_hidden_size = 1431655765;
-    LstmCellTester{
-        .input = valid_input,
-        .weight = {.type = mojom::DataType::kFloat32,
-                   .dimensions = {4 * invalid_hidden_size, input_size}},
-        .recurrent_weight = {.type = mojom::DataType::kFloat32,
-                             .dimensions = {4 * invalid_hidden_size,
-                                            invalid_hidden_size}},
-        .hidden_state = {.type = mojom::DataType::kFloat32,
-                         .dimensions = {batch_size, invalid_hidden_size}},
-        .cell_state = {.type = mojom::DataType::kFloat32,
-                       .dimensions = {batch_size, invalid_hidden_size}},
-        .hidden_size = invalid_hidden_size,
-        .outputs = {{.type = mojom::DataType::kFloat32,
-                     .dimensions = {batch_size, invalid_hidden_size}},
-                    {.type = mojom::DataType::kFloat32,
-                     .dimensions = {batch_size, invalid_hidden_size}}},
-        .expected = false}
-        .Test();
-  }
-  {
     // Test the invalid graph when the cell state has the same id as
     // one of the outputs.
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id = builder.BuildInput(
-        "input", {batch_size, input_size}, mojom::DataType::kFloat32);
+        "input", {batch_size, input_size}, OperandDataType::kFloat32);
     uint64_t weight_operand_id = builder.BuildInput(
-        "weight", {4 * hidden_size, input_size}, mojom::DataType::kFloat32);
+        "weight", {4 * hidden_size, input_size}, OperandDataType::kFloat32);
     uint64_t recurrent_weight_operand_id =
         builder.BuildInput("recurrentWeight", {4 * hidden_size, hidden_size},
-                           mojom::DataType::kFloat32);
+                           OperandDataType::kFloat32);
     uint64_t hidden_state_operand_id = builder.BuildInput(
-        "hiddenState", {batch_size, hidden_size}, mojom::DataType::kFloat32);
+        "hiddenState", {batch_size, hidden_size}, OperandDataType::kFloat32);
     uint64_t cell_state_operand_id = builder.BuildInput(
-        "cellState", {batch_size, hidden_size}, mojom::DataType::kFloat32);
+        "cellState", {batch_size, hidden_size}, OperandDataType::kFloat32);
     uint64_t output_operand_id = builder.BuildOutput(
-        "output", {batch_size, hidden_size}, mojom::DataType::kFloat32);
+        "output", {batch_size, hidden_size}, OperandDataType::kFloat32);
 
     builder.BuildLstmCell(input_operand_id, weight_operand_id,
                           recurrent_weight_operand_id, hidden_state_operand_id,
@@ -4347,18 +4314,18 @@
   {
     // Test building matmul with 2-D * 2-D.
     MatmulTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
-        .b = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
+        .b = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
         .expected = true}
         .Test();
   }
   {
     // Test building matmul with 2-D * 4-D.
     MatmulTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
-        .b = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3, 3, 4}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
+        .b = {.type = OperandDataType::kFloat32, .dimensions = {2, 3, 3, 4}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {2, 3, 2, 4}},
         .expected = true}
         .Test();
@@ -4366,9 +4333,9 @@
   {
     // Test building matmul with 3-D * 4-D using broadcasting.
     MatmulTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {2, 2, 3}},
-        .b = {.type = mojom::DataType::kFloat32, .dimensions = {3, 1, 3, 4}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {2, 2, 3}},
+        .b = {.type = OperandDataType::kFloat32, .dimensions = {3, 1, 3, 4}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {3, 2, 2, 4}},
         .expected = true}
         .Test();
@@ -4376,9 +4343,9 @@
   {
     // Test the invalid graph for one input rank is smaller than 2.
     MatmulTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {3}},
-        .b = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {3}},
+        .b = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
         .expected = false}
         .Test();
   }
@@ -4386,54 +4353,54 @@
     // Test the invalid graph for the number of columns in first matrix
     // mismatches with the number of rows in second matrix.
     MatmulTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {3, 2}},
-        .b = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {3, 2}},
+        .b = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the input shapes are not broadcastable.
     MatmulTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {3, 2, 3}},
-        .b = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {3, 2, 3}},
+        .b = {.type = OperandDataType::kFloat32, .dimensions = {2, 3, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph if the input is not floating point.
     MatmulTester{
-        .a = {.type = mojom::DataType::kUint8, .dimensions = {2, 3}},
-        .b = {.type = mojom::DataType::kUint8, .dimensions = {3, 4}},
-        .output = {.type = mojom::DataType::kUint8, .dimensions = {2, 4}},
+        .a = {.type = OperandDataType::kUint8, .dimensions = {2, 3}},
+        .b = {.type = OperandDataType::kUint8, .dimensions = {3, 4}},
+        .output = {.type = OperandDataType::kUint8, .dimensions = {2, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the output shapes are not expected.
     MatmulTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
-        .b = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
+        .b = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for input types are not same.
     MatmulTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
-        .b = {.type = mojom::DataType::kInt32, .dimensions = {3, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
+        .b = {.type = OperandDataType::kInt32, .dimensions = {3, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output type is not the same as input type.
     MatmulTester{
-        .a = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
-        .b = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {2, 4}},
+        .a = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
+        .b = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {2, 4}},
         .expected = false}
         .Test();
   }
@@ -4442,9 +4409,9 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t a_operand_id =
-        builder.BuildInput("a", {2, 3}, mojom::DataType::kFloat32);
+        builder.BuildInput("a", {2, 3}, OperandDataType::kFloat32);
     uint64_t b_operand_id =
-        builder.BuildInput("b", {3, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("b", {3, 4}, OperandDataType::kFloat32);
     builder.BuildMatmul(a_operand_id, b_operand_id, a_operand_id);
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
                                                builder.GetGraphInfo()));
@@ -4482,10 +4449,10 @@
     // Test pad with default options, beginningPadding = {1, 2} and
     // endingPadding = {1, 2}.
     PadTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
         .beginning_padding = {1, 2},
         .ending_padding = {1, 2},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {4, 7}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {4, 7}},
         .expected = true}
         .Test();
   }
@@ -4493,11 +4460,11 @@
     // Test pad with mode = "edge", beginningPadding = {1, 2} and
     // endingPadding = {1, 2}.
     PadTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
         .beginning_padding = {1, 2},
         .ending_padding = {1, 2},
         .mode = mojom::PaddingMode::Tag::kEdge,
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {4, 7}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {4, 7}},
         .expected = true}
         .Test();
   }
@@ -4505,11 +4472,11 @@
     // Test pad with value = 1, beginningPadding = {1, 2} and
     // endingPadding = {1, 2}.
     PadTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
         .beginning_padding = {1, 2},
         .ending_padding = {1, 2},
         .value = 1,
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {4, 7}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {4, 7}},
         .expected = true}
         .Test();
   }
@@ -4517,10 +4484,10 @@
     // Test the invalid graph when the length of beginningPadding is not
     // equal to the input rank.
     PadTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
         .beginning_padding = {1},
         .ending_padding = {1, 2},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {4, 7}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {4, 7}},
         .expected = false}
         .Test();
   }
@@ -4528,22 +4495,10 @@
     // Test the invalid graph when the length of endingPadding is not equal
     // to the input rank.
     PadTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
         .beginning_padding = {1, 0},
         .ending_padding = {1, 2, 0},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {4, 7}},
-        .expected = false}
-        .Test();
-  }
-  {
-    // Test the invalid graph when the padding of one dimension is too
-    // large.
-    PadTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
-        .beginning_padding = {2294967295, 0},
-        .ending_padding = {3294967295, 2},
-        .output = {.type = mojom::DataType::kFloat32,
-                   .dimensions = {1294967294, 5}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {4, 7}},
         .expected = false}
         .Test();
   }
@@ -4552,7 +4507,7 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {2, 3}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {2, 3}, OperandDataType::kFloat32);
     builder.BuildPad(input_operand_id, input_operand_id, {1, 1}, {1, 1},
                      mojom::PaddingMode::Tag::kConstant, 0);
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
@@ -4599,44 +4554,44 @@
 TEST_F(WebNNGraphImplTest, Pool2dTest) {
   {
     // Test pool2d with default attributes.
-    Pool2dTester{.input = {.type = mojom::DataType::kFloat32,
+    Pool2dTester{.input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 3, 4, 4}},
                  .attributes = {.window_dimensions = {1, 1}, .strides = {1, 1}},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 3, 4, 4}},
                  .expected = true}
         .Test();
   }
   {
     // Test pool2d with window dimensions.
-    Pool2dTester{.input = {.type = mojom::DataType::kFloat32,
+    Pool2dTester{.input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 3, 5, 5}},
                  .attributes = {.window_dimensions = {2, 2}, .strides = {2, 2}},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 3, 3, 3}},
                  .expected = true}
         .Test();
   }
   {
     // Test pool2d with strides=2, padding=1 and floor rounding.
-    Pool2dTester{.input = {.type = mojom::DataType::kFloat16,
+    Pool2dTester{.input = {.type = OperandDataType::kFloat16,
                            .dimensions = {1, 3, 7, 7}},
                  .attributes = {.window_dimensions = {4, 4},
                                 .padding = {1, 1, 1, 1},
                                 .strides = {2, 2}},
-                 .output = {.type = mojom::DataType::kFloat16,
+                 .output = {.type = OperandDataType::kFloat16,
                             .dimensions = {1, 3, 3, 3}},
                  .expected = true}
         .Test();
   }
   {
     // Test pool2d with strides=2, padding=1 and ceil rounding.
-    Pool2dTester{.input = {.type = mojom::DataType::kFloat32,
+    Pool2dTester{.input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 3, 7, 7}},
                  .attributes = {.window_dimensions = {4, 4},
                                 .padding = {1, 1, 1, 1},
                                 .strides = {2, 2}},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 3, 4, 4}},
                  .expected = true}
         .Test();
@@ -4644,12 +4599,12 @@
   {
     // Test pool2d with layout="nhwc".
     Pool2dTester{
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 5, 5, 2}},
         .attributes = {.window_dimensions = {3, 3},
                        .strides = {1, 1},
                        .layout = mojom::InputOperandLayout::kChannelsLast},
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 3, 3, 2}},
         .expected = true}
         .Test();
@@ -4657,62 +4612,62 @@
   {
     // Test the invalid graph when the input is not a 4-D tensor.
     Pool2dTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {3, 5, 5}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {3, 5, 5}},
         .attributes = {.window_dimensions = {5, 5},
                        .padding = {2, 2, 2, 2},
                        .strides = {1, 1}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {3, 5, 5}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {3, 5, 5}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph when window dimensions are 0.
-    Pool2dTester{.input = {.type = mojom::DataType::kFloat32,
+    Pool2dTester{.input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 3, 4, 4}},
                  .attributes = {.window_dimensions = {0, 0}, .strides = {1, 1}},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 3, 4, 4}},
                  .expected = false}
         .Test();
   }
   {
     // Test the invalid graph when strides are 0.
-    Pool2dTester{.input = {.type = mojom::DataType::kFloat32,
+    Pool2dTester{.input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 3, 4, 4}},
                  .attributes = {.window_dimensions = {1, 1}, .strides = {0, 0}},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 3, 4, 4}},
                  .expected = false}
         .Test();
   }
   {
     // Test the invalid graph when dilations are 0.
-    Pool2dTester{.input = {.type = mojom::DataType::kFloat32,
+    Pool2dTester{.input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 3, 4, 4}},
                  .attributes = {.window_dimensions = {1, 1},
                                 .strides = {1, 1},
                                 .dilations = {0, 0}},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 3, 4, 4}},
                  .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the output shapes are not expected.
-    Pool2dTester{.input = {.type = mojom::DataType::kFloat32,
+    Pool2dTester{.input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 3, 4, 4}},
                  .attributes = {.window_dimensions = {4, 4}, .strides = {1, 1}},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 2, 1, 1}},
                  .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output types don't match.
-    Pool2dTester{.input = {.type = mojom::DataType::kFloat32,
+    Pool2dTester{.input = {.type = OperandDataType::kFloat32,
                            .dimensions = {1, 3, 4, 4}},
                  .attributes = {.window_dimensions = {4, 4}, .strides = {1, 1}},
-                 .output = {.type = mojom::DataType::kFloat16,
+                 .output = {.type = OperandDataType::kFloat16,
                             .dimensions = {1, 3, 1, 1}},
                  .expected = false}
         .Test();
@@ -4721,9 +4676,9 @@
     // Test the invalid graph if the input data type is not floating point for
     // averagePool2d.
     Pool2dTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {1, 3, 4, 4}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {1, 3, 4, 4}},
         .attributes = {.window_dimensions = {4, 4}, .strides = {1, 1}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {1, 3, 1, 1}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {1, 3, 1, 1}},
         .expected = false}
         .Test(mojom::Pool2d::Kind::kAveragePool2d);
   }
@@ -4731,9 +4686,9 @@
     // Test the invalid graph if the input data type is not floating point for
     // l2Pool2d.
     Pool2dTester{
-        .input = {.type = mojom::DataType::kInt8, .dimensions = {1, 3, 4, 4}},
+        .input = {.type = OperandDataType::kInt8, .dimensions = {1, 3, 4, 4}},
         .attributes = {.window_dimensions = {4, 4}, .strides = {1, 1}},
-        .output = {.type = mojom::DataType::kInt8, .dimensions = {1, 3, 1, 1}},
+        .output = {.type = OperandDataType::kInt8, .dimensions = {1, 3, 1, 1}},
         .expected = false}
         .Test(mojom::Pool2d::Kind::kL2Pool2d);
   }
@@ -4767,54 +4722,54 @@
   {
     // Test prelu operator when the input and the slope have the same shape.
     PreluTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {3, 2, 5}},
-        .slope = {.type = mojom::DataType::kFloat32, .dimensions = {3, 2, 5}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {3, 2, 5}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {3, 2, 5}},
+        .slope = {.type = OperandDataType::kFloat32, .dimensions = {3, 2, 5}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {3, 2, 5}},
         .expected = true}
         .Test();
   }
   {
     // Test prelu operator with a broadcastable slope.
     PreluTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {3, 2, 5}},
-        .slope = {.type = mojom::DataType::kFloat32, .dimensions = {3, 1, 5}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {3, 2, 5}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {3, 2, 5}},
+        .slope = {.type = OperandDataType::kFloat32, .dimensions = {3, 1, 5}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {3, 2, 5}},
         .expected = true}
         .Test();
   }
   {
     // Test the invalid graph with an invalid slope.
     PreluTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {3, 2, 5}},
-        .slope = {.type = mojom::DataType::kFloat32, .dimensions = {3, 5}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {3, 2, 5}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {3, 2, 5}},
+        .slope = {.type = OperandDataType::kFloat32, .dimensions = {3, 5}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {3, 2, 5}},
         .expected = false}
         .Test();
   }
   {
     // Test prelu operator with input data type and slope data type = int32.
     PreluTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {3, 2, 5}},
-        .slope = {.type = mojom::DataType::kInt32, .dimensions = {3, 2, 5}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {3, 2, 5}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {3, 2, 5}},
+        .slope = {.type = OperandDataType::kInt32, .dimensions = {3, 2, 5}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {3, 2, 5}},
         .expected = true}
         .Test();
   }
   {
     // Test prelu operator with input data type and slope data type = float16.
     PreluTester{
-        .input = {.type = mojom::DataType::kFloat16, .dimensions = {3, 2, 5}},
-        .slope = {.type = mojom::DataType::kFloat16, .dimensions = {3, 2, 5}},
-        .output = {.type = mojom::DataType::kFloat16, .dimensions = {3, 2, 5}},
+        .input = {.type = OperandDataType::kFloat16, .dimensions = {3, 2, 5}},
+        .slope = {.type = OperandDataType::kFloat16, .dimensions = {3, 2, 5}},
+        .output = {.type = OperandDataType::kFloat16, .dimensions = {3, 2, 5}},
         .expected = true}
         .Test();
   }
   {
     // Test prelu operator with input data type and slope data type = int8.
     PreluTester{
-        .input = {.type = mojom::DataType::kInt8, .dimensions = {3, 2, 5}},
-        .slope = {.type = mojom::DataType::kInt8, .dimensions = {3, 2, 5}},
-        .output = {.type = mojom::DataType::kInt8, .dimensions = {3, 2, 5}},
+        .input = {.type = OperandDataType::kInt8, .dimensions = {3, 2, 5}},
+        .slope = {.type = OperandDataType::kInt8, .dimensions = {3, 2, 5}},
+        .output = {.type = OperandDataType::kInt8, .dimensions = {3, 2, 5}},
         .expected = true}
         .Test();
   }
@@ -4822,9 +4777,9 @@
     // Test the invalid graph when the slope datatype doesn't match the
     // input's datatype.
     PreluTester{
-        .input = {.type = mojom::DataType::kFloat16, .dimensions = {3, 2, 5}},
-        .slope = {.type = mojom::DataType::kFloat32, .dimensions = {3, 2, 5}},
-        .output = {.type = mojom::DataType::kFloat16, .dimensions = {3, 2, 5}},
+        .input = {.type = OperandDataType::kFloat16, .dimensions = {3, 2, 5}},
+        .slope = {.type = OperandDataType::kFloat32, .dimensions = {3, 2, 5}},
+        .output = {.type = OperandDataType::kFloat16, .dimensions = {3, 2, 5}},
         .expected = false}
         .Test();
   }
@@ -4832,9 +4787,9 @@
     // Test the invalid graph when the input data type and slope data type =
     // uint32.
     PreluTester{
-        .input = {.type = mojom::DataType::kUint32, .dimensions = {3, 2, 5}},
-        .slope = {.type = mojom::DataType::kUint32, .dimensions = {3, 2, 5}},
-        .output = {.type = mojom::DataType::kUint32, .dimensions = {3, 2, 5}},
+        .input = {.type = OperandDataType::kUint32, .dimensions = {3, 2, 5}},
+        .slope = {.type = OperandDataType::kUint32, .dimensions = {3, 2, 5}},
+        .output = {.type = OperandDataType::kUint32, .dimensions = {3, 2, 5}},
         .expected = false}
         .Test();
   }
@@ -4842,18 +4797,18 @@
     // Test the invalid graph when the output datatype doesn't match the
     // input's datatype.
     PreluTester{
-        .input = {.type = mojom::DataType::kFloat16, .dimensions = {3, 2, 5}},
-        .slope = {.type = mojom::DataType::kFloat16, .dimensions = {3, 2, 5}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {3, 2, 5}},
+        .input = {.type = OperandDataType::kFloat16, .dimensions = {3, 2, 5}},
+        .slope = {.type = OperandDataType::kFloat16, .dimensions = {3, 2, 5}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {3, 2, 5}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the output shapes are not expected.
     PreluTester{
-        .input = {.type = mojom::DataType::kFloat16, .dimensions = {3, 2, 5}},
-        .slope = {.type = mojom::DataType::kFloat16, .dimensions = {3, 2, 5}},
-        .output = {.type = mojom::DataType::kFloat16, .dimensions = {3, 2, 6}},
+        .input = {.type = OperandDataType::kFloat16, .dimensions = {3, 2, 5}},
+        .slope = {.type = OperandDataType::kFloat16, .dimensions = {3, 2, 5}},
+        .output = {.type = OperandDataType::kFloat16, .dimensions = {3, 2, 6}},
         .expected = false}
         .Test();
   }
@@ -4862,9 +4817,9 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {2, 3}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {2, 3}, OperandDataType::kFloat32);
     uint64_t slope_operand_id =
-        builder.BuildInput("slope", {2, 3}, mojom::DataType::kFloat32);
+        builder.BuildInput("slope", {2, 3}, OperandDataType::kFloat32);
     builder.BuildPrelu(input_operand_id, slope_operand_id, input_operand_id);
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
                                                builder.GetGraphInfo()));
@@ -4874,9 +4829,9 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {2, 3}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {2, 3}, OperandDataType::kFloat32);
     uint64_t output_operand_id =
-        builder.BuildOutput("output", {2, 3}, mojom::DataType::kFloat32);
+        builder.BuildOutput("output", {2, 3}, OperandDataType::kFloat32);
     builder.BuildPrelu(input_operand_id, output_operand_id, output_operand_id);
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
                                                builder.GetGraphInfo()));
@@ -4913,11 +4868,11 @@
   {
     // Test reduce operator with axes = {0, 2} and keep_dimensions = true.
     ReduceTester{.kind = mojom::Reduce::Kind::kL1,
-                 .input = {.type = mojom::DataType::kFloat32,
+                 .input = {.type = OperandDataType::kFloat32,
                            .dimensions = {2, 3, 4, 5}},
                  .axes = {0, 2},
                  .keep_dimensions = true,
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 3, 1, 5}},
                  .expected = true}
         .Test();
@@ -4926,10 +4881,10 @@
     // Test reduceL1 operator with input_data_type = int32.
     ReduceTester{
         .kind = mojom::Reduce::Kind::kL1,
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {2, 3, 4, 5}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {2, 3, 4, 5}},
         .axes = {0, 2},
         .keep_dimensions = true,
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {1, 3, 1, 5}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {1, 3, 1, 5}},
         .expected = true}
         .Test();
   }
@@ -4937,21 +4892,21 @@
     // Test reduce operator with axes = {2} and keep_dimensions = false.
     ReduceTester{
         .kind = mojom::Reduce::Kind::kL2,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 3, 4, 5}},
         .axes = {2},
         .keep_dimensions = false,
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3, 5}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 3, 5}},
         .expected = true}
         .Test();
   }
   {
     ReduceTester{
         .kind = mojom::Reduce::Kind::kMin,
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {2, 3, 4, 5}},
         .axes = {0, 1, 2, 3},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {}},
         .expected = true}
         .Test();
   }
@@ -4959,9 +4914,9 @@
   {
     ReduceTester{
         .kind = mojom::Reduce::Kind::kMin,
-        .input = {.type = mojom::DataType::kInt64, .dimensions = {2, 3, 4, 5}},
+        .input = {.type = OperandDataType::kInt64, .dimensions = {2, 3, 4, 5}},
         .axes = {0, 1, 2, 3},
-        .output = {.type = mojom::DataType::kInt64, .dimensions = {}},
+        .output = {.type = OperandDataType::kInt64, .dimensions = {}},
         .expected = true}
         .Test();
   }
@@ -4969,19 +4924,19 @@
   {
     ReduceTester{
         .kind = mojom::Reduce::Kind::kSum,
-        .input = {.type = mojom::DataType::kInt64, .dimensions = {2, 3, 4, 5}},
+        .input = {.type = OperandDataType::kInt64, .dimensions = {2, 3, 4, 5}},
         .axes = {0, 1, 2, 3},
-        .output = {.type = mojom::DataType::kInt64, .dimensions = {}},
+        .output = {.type = OperandDataType::kInt64, .dimensions = {}},
         .expected = true}
         .Test();
   }
   {
     // Test reduce operator with empty axes = {}.
     ReduceTester{.kind = mojom::Reduce::Kind::kMin,
-                 .input = {.type = mojom::DataType::kFloat32,
+                 .input = {.type = OperandDataType::kFloat32,
                            .dimensions = {2, 3, 4, 5}},
                  .axes = {},
-                 .output = {.type = mojom::DataType::kFloat32,
+                 .output = {.type = OperandDataType::kFloat32,
                             .dimensions = {2, 3, 4, 5}},
                  .expected = true}
         .Test();
@@ -4991,10 +4946,10 @@
     // input rank.
     ReduceTester{
         .kind = mojom::Reduce::Kind::kMax,
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
         .axes = {0, 1, 2},
         .keep_dimensions = false,
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
         .expected = false}
         .Test();
   }
@@ -5002,10 +4957,10 @@
     // Test the invalid graph when the axes contains duplicate values.
     ReduceTester{
         .kind = mojom::Reduce::Kind::kMean,
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
         .axes = {1, 1},
         .keep_dimensions = false,
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
         .expected = false}
         .Test();
   }
@@ -5014,10 +4969,10 @@
     // input_rank - 1.
     ReduceTester{
         .kind = mojom::Reduce::Kind::kSum,
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
         .axes = {2},
         .keep_dimensions = false,
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
         .expected = false}
         .Test();
   }
@@ -5025,10 +4980,10 @@
     // Test the invalid graph for output shapes are not expected.
     ReduceTester{
         .kind = mojom::Reduce::Kind::kProduct,
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
         .axes = {0},
         .keep_dimensions = false,
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {1, 3}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {1, 3}},
         .expected = false}
         .Test();
   }
@@ -5036,10 +4991,10 @@
     // Test the invalid graph for output types don't match.
     ReduceTester{
         .kind = mojom::Reduce::Kind::kLogSum,
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
         .axes = {0},
         .keep_dimensions = false,
-        .output = {.type = mojom::DataType::kFloat16, .dimensions = {3}},
+        .output = {.type = OperandDataType::kFloat16, .dimensions = {3}},
         .expected = false}
         .Test();
   }
@@ -5048,10 +5003,10 @@
     // for reduceLogSum.
     ReduceTester{
         .kind = mojom::Reduce::Kind::kLogSum,
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {2, 3}},
         .axes = {0},
         .keep_dimensions = false,
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {3}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {3}},
         .expected = false}
         .Test();
   }
@@ -5060,10 +5015,10 @@
     // for reduceLogSumExp.
     ReduceTester{
         .kind = mojom::Reduce::Kind::kLogSumExp,
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {2, 3}},
         .axes = {0},
         .keep_dimensions = false,
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {3}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {3}},
         .expected = false}
         .Test();
   }
@@ -5072,10 +5027,10 @@
     // for reduceL2.
     ReduceTester{
         .kind = mojom::Reduce::Kind::kL2,
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {2, 3}},
         .axes = {0},
         .keep_dimensions = false,
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {3}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {3}},
         .expected = false}
         .Test();
   }
@@ -5084,10 +5039,10 @@
     // for reduceMean.
     ReduceTester{
         .kind = mojom::Reduce::Kind::kMean,
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {2, 3}},
         .axes = {0},
         .keep_dimensions = false,
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {3}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {3}},
         .expected = false}
         .Test();
   }
@@ -5096,10 +5051,10 @@
     // float16, int32, uint32, int64, uint64} types for reduceProduce.
     ReduceTester{
         .kind = mojom::Reduce::Kind::kProduct,
-        .input = {.type = mojom::DataType::kInt8, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kInt8, .dimensions = {2, 3}},
         .axes = {0},
         .keep_dimensions = false,
-        .output = {.type = mojom::DataType::kInt8, .dimensions = {3}},
+        .output = {.type = OperandDataType::kInt8, .dimensions = {3}},
         .expected = false}
         .Test();
   }
@@ -5108,10 +5063,10 @@
     // float16, int32, uint32, int64, uint64} types for reduceL1.
     ReduceTester{
         .kind = mojom::Reduce::Kind::kL1,
-        .input = {.type = mojom::DataType::kUint8, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kUint8, .dimensions = {2, 3}},
         .axes = {0},
         .keep_dimensions = false,
-        .output = {.type = mojom::DataType::kUint8, .dimensions = {3}},
+        .output = {.type = OperandDataType::kUint8, .dimensions = {3}},
         .expected = false}
         .Test();
   }
@@ -5120,10 +5075,10 @@
     // float16, int32, uint32, int64, uint64} types for reduceSum.
     ReduceTester{
         .kind = mojom::Reduce::Kind::kSum,
-        .input = {.type = mojom::DataType::kUint8, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kUint8, .dimensions = {2, 3}},
         .axes = {0},
         .keep_dimensions = false,
-        .output = {.type = mojom::DataType::kUint8, .dimensions = {3}},
+        .output = {.type = OperandDataType::kUint8, .dimensions = {3}},
         .expected = false}
         .Test();
   }
@@ -5132,10 +5087,10 @@
     // float16, int32, uint32, int64, uint64} types for reduceSumSquare.
     ReduceTester{
         .kind = mojom::Reduce::Kind::kSumSquare,
-        .input = {.type = mojom::DataType::kInt8, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kInt8, .dimensions = {2, 3}},
         .axes = {0},
         .keep_dimensions = false,
-        .output = {.type = mojom::DataType::kInt8, .dimensions = {3}},
+        .output = {.type = OperandDataType::kInt8, .dimensions = {3}},
         .expected = false}
         .Test();
   }
@@ -5144,10 +5099,10 @@
     // same.
     ReduceTester{
         .kind = mojom::Reduce::Kind::kLogSum,
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
         .axes = {0},
         .keep_dimensions = false,
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {3}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {3}},
         .expected = false}
         .Test();
   }
@@ -5156,7 +5111,7 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {2, 3}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {2, 3}, OperandDataType::kFloat32);
     builder.BuildReduce(mojom::Reduce::Kind::kSumSquare, input_operand_id,
                         input_operand_id, {0}, false);
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
@@ -5189,39 +5144,39 @@
   {
     // Test relu operator for 3-D tensor with float32 input.
     ReluTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 6, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 6, 4}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 6, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 6, 4}},
         .expected = true}
         .Test();
   }
   {
     // Test relu operator for 4-D tensor with int32 input.
     ReluTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {1, 5, 3, 7}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {1, 5, 3, 7}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {1, 5, 3, 7}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {1, 5, 3, 7}},
         .expected = true}
         .Test();
   }
   {
     // Test the invalid graph if the data type is not supported.
     ReluTester{
-        .input = {.type = mojom::DataType::kUint32, .dimensions = {4, 2}},
-        .output = {.type = mojom::DataType::kUint32, .dimensions = {4, 2}},
+        .input = {.type = OperandDataType::kUint32, .dimensions = {4, 2}},
+        .output = {.type = OperandDataType::kUint32, .dimensions = {4, 2}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the output shapes are not expected.
     ReluTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output types don't match.
-    ReluTester{.input = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-               .output = {.type = mojom::DataType::kInt32, .dimensions = {2}},
+    ReluTester{.input = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+               .output = {.type = OperandDataType::kInt32, .dimensions = {2}},
                .expected = false}
         .Test();
   }
@@ -5258,9 +5213,9 @@
 TEST_F(WebNNGraphImplTest, Resample2dTest) {
   {
     // Test resample2d with "NearestNeighbor" mode and axes = [2, 3].
-    Resample2dTester{.input = {.type = mojom::DataType::kFloat32,
+    Resample2dTester{.input = {.type = OperandDataType::kFloat32,
                                .dimensions = {1, 1, 2, 4}},
-                     .output = {.type = mojom::DataType::kFloat32,
+                     .output = {.type = OperandDataType::kFloat32,
                                 .dimensions = {1, 1, 2, 4}},
                      .expected = true}
         .Test();
@@ -5269,12 +5224,12 @@
     // Test resample2d with "Linear" mode, axes = [1, 2] and explicit scales
     // = [2, 2], input_data_type = float32.
     Resample2dTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 4, 1}},
         .attributes = {.mode = mojom::Resample2d::InterpolationMode::kLinear,
                        .scales = std::vector<float>{2, 2},
                        .axes = {1, 2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 4, 8, 1}},
         .expected = true}
         .Test();
@@ -5283,12 +5238,12 @@
     // Test resample2d with "Linear" mode, axes = [1, 2] and explicit scales
     // = [2, 2], input_data_type = float16.
     Resample2dTester{
-        .input = {.type = mojom::DataType::kFloat16,
+        .input = {.type = OperandDataType::kFloat16,
                   .dimensions = {1, 2, 4, 1}},
         .attributes = {.mode = mojom::Resample2d::InterpolationMode::kLinear,
                        .scales = std::vector<float>{2, 2},
                        .axes = {1, 2}},
-        .output = {.type = mojom::DataType::kFloat16,
+        .output = {.type = OperandDataType::kFloat16,
                    .dimensions = {1, 4, 8, 1}},
         .expected = true}
         .Test();
@@ -5297,21 +5252,21 @@
     // Test resample2d with "Linear" mode, axes = [1, 2] and explicit scales
     // = [2, 2.2] which is not exactly output dimensions / input dimensions.
     Resample2dTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 4, 1}},
         .attributes = {.mode = mojom::Resample2d::InterpolationMode::kLinear,
                        .scales = std::vector<float>{2, 2.2},
                        .axes = {1, 2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 4, 8, 1}},
         .expected = true}
         .Test();
   }
   {
     // Test the invalid graph for output types don't match.
-    Resample2dTester{.input = {.type = mojom::DataType::kFloat32,
+    Resample2dTester{.input = {.type = OperandDataType::kFloat32,
                                .dimensions = {1, 1, 2, 4}},
-                     .output = {.type = mojom::DataType::kFloat16,
+                     .output = {.type = OperandDataType::kFloat16,
                                 .dimensions = {1, 1, 4, 8}},
                      .expected = false}
         .Test();
@@ -5319,16 +5274,16 @@
   {
     // Test the invalid graph if the input is not floating point.
     Resample2dTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {1, 1, 2, 4}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {1, 1, 4, 8}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {1, 1, 2, 4}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {1, 1, 4, 8}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for input is not a 4-D tensor.
     Resample2dTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {1, 1, 2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {1, 1, 2}},
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 2, 4}},
         .expected = false}
         .Test();
@@ -5336,9 +5291,9 @@
   {
     // Test the invalid graph for output is not a 4-D tensor.
     Resample2dTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 2, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {1, 1, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {1, 1, 2}},
         .expected = false}
         .Test();
   }
@@ -5346,12 +5301,12 @@
     // Test the invalid graph for output dimensions that don't match the
     // calculated dimensions by scales.
     Resample2dTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 4, 1}},
         .attributes = {.mode = mojom::Resample2d::InterpolationMode::kLinear,
                        .scales = std::vector<float>{2, 2},
                        .axes = {1, 2}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 5, 8, 1}},
         .expected = false}
         .Test();
@@ -5359,11 +5314,11 @@
   {
     // Test the invalid graph when the scale height is too large.
     Resample2dTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 34902, 23243}},
         .attributes = {.mode = mojom::Resample2d::InterpolationMode::kLinear,
                        .scales = std::vector<float>{232433, 4}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 2, 4}},
         .expected = false}
         .Test();
@@ -5371,23 +5326,23 @@
   {
     // Test the invalid graph when the scale height is too small.
     Resample2dTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 2, 4}},
         .attributes = {.mode = mojom::Resample2d::InterpolationMode::kLinear,
                        .scales = std::vector<float>{0.02, 0.8}},
-        .output = {.type = mojom::DataType::kFloat32,
-                   .dimensions = {1, 1, 0, 3}},
+        .output = {.type = OperandDataType::kFloat32,
+                   .dimensions = {1, 1, 2, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph when the scale width is too large.
     Resample2dTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 34902, 23243}},
         .attributes = {.mode = mojom::Resample2d::InterpolationMode::kLinear,
                        .scales = std::vector<float>{20, 434324}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 1, 2, 4}},
         .expected = false}
         .Test();
@@ -5395,21 +5350,21 @@
   {
     // Test the invalid graph when the scale width is too small.
     Resample2dTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 2, 4}},
         .attributes = {.mode = mojom::Resample2d::InterpolationMode::kLinear,
                        .scales = std::vector<float>{0.7, 0.1}},
-        .output = {.type = mojom::DataType::kFloat32,
-                   .dimensions = {1, 1, 1, 0}},
+        .output = {.type = OperandDataType::kFloat32,
+                   .dimensions = {1, 1, 2, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph when the scales are negative.
-    Resample2dTester{.input = {.type = mojom::DataType::kFloat32,
+    Resample2dTester{.input = {.type = OperandDataType::kFloat32,
                                .dimensions = {1, 1, 2, 4}},
                      .attributes{.scales = std::vector<float>{1.0, -2.0}},
-                     .output = {.type = mojom::DataType::kFloat32,
+                     .output = {.type = OperandDataType::kFloat32,
                                 .dimensions = {1, 2, 4, 4}},
                      .expected = false}
         .Test();
@@ -5418,20 +5373,20 @@
   // the interpolation algorithm applies are not two consecutive dimensions.
   {
     // With axes = [1, 3].
-    Resample2dTester{.input = {.type = mojom::DataType::kFloat32,
+    Resample2dTester{.input = {.type = OperandDataType::kFloat32,
                                .dimensions = {1, 1, 2, 4}},
                      .attributes = {.axes = {1, 3}},
-                     .output = {.type = mojom::DataType::kFloat32,
+                     .output = {.type = OperandDataType::kFloat32,
                                 .dimensions = {1, 2, 2, 8}},
                      .expected = false}
         .Test();
   }
   {
     // With axes = [1, 2, 3]
-    Resample2dTester{.input = {.type = mojom::DataType::kFloat32,
+    Resample2dTester{.input = {.type = OperandDataType::kFloat32,
                                .dimensions = {1, 1, 2, 4}},
                      .attributes = {.axes = {1, 2, 3}},
-                     .output = {.type = mojom::DataType::kFloat32,
+                     .output = {.type = OperandDataType::kFloat32,
                                 .dimensions = {1, 2, 4, 8}},
                      .expected = false}
         .Test();
@@ -5441,20 +5396,20 @@
   {
     // With explicit scales.
     Resample2dTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 1, 2, 4}},
         .attributes = {.scales = std::vector<float>{2, 2}, .axes = {2, 3}},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 4, 8}},
         .expected = false}
         .Test();
   }
   {
     // Without explicit scales.
-    Resample2dTester{.input = {.type = mojom::DataType::kFloat32,
+    Resample2dTester{.input = {.type = OperandDataType::kFloat32,
                                .dimensions = {1, 1, 2, 4}},
                      .attributes = {.axes = {2, 3}},
-                     .output = {.type = mojom::DataType::kFloat32,
+                     .output = {.type = OperandDataType::kFloat32,
                                 .dimensions = {1, 2, 4, 8}},
                      .expected = false}
         .Test();
@@ -5464,7 +5419,7 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {1, 1, 2, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {1, 1, 2, 4}, OperandDataType::kFloat32);
     builder.BuildResample2d(input_operand_id, input_operand_id,
                             Resample2dTester::Resample2dAttributes{});
 
@@ -5498,41 +5453,33 @@
   {
     // Test reshape operator from 2-D tensor to 1-D tensor.
     ReshapeTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {8}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {8}},
         .expected = true}
         .Test();
   }
   {
     // Test reshape operator from 4-D tensor to 2-D tensor.
     ReshapeTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {1, 3, 2, 1}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {1, 6}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {1, 3, 2, 1}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {1, 6}},
         .expected = true}
         .Test();
   }
   {
-    // Test the invalid graph when one value of new shape is 0.
-    ReshapeTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 0}},
-        .expected = false}
-        .Test();
-  }
-  {
     // Test the invalid graph when the number of input elements are not
     // equal to the number of output elements.
     ReshapeTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3, 4}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {3, 5}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 3, 4}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {3, 5}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output types don't match.
     ReshapeTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
@@ -5571,54 +5518,54 @@
   {
     // Test slice with output dimensions equal to input dimensions.
     SliceTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {4, 4}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {4, 4}},
         .attributes = {.starts = {0, 0}, .sizes = {4, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {4, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {4, 4}},
         .expected = true}
         .Test();
   }
   {
     // Test 4x4 2-D Tensor to 2x2 slice
     SliceTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {4, 4}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {4, 4}},
         .attributes = {.starts = {0, 0}, .sizes = {2, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 2}},
         .expected = true}
         .Test();
   }
   {
     // Test 4x4 2-D Tensor to 2x2 slice with offsets
     SliceTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {4, 4}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {4, 4}},
         .attributes = {.starts = {2, 2}, .sizes = {2, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 2}},
         .expected = true}
         .Test();
   }
   {
     // Test that going out-of-bounds of the input tensor fails.
     SliceTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 2}},
         .attributes = {.starts = {1, 0}, .sizes = {2, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 2}},
         .expected = false}
         .Test();
   }
   {
     // Test that mismatched output dimensions and size attribute will fail.
     SliceTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 2}},
         .attributes = {.starts = {0, 0}, .sizes = {1, 1}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 1}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 1}},
         .expected = false}
         .Test();
   }
   {
     // Test that using size zero will result in failure.
     SliceTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 2}},
         .attributes = {.starts = {0, 0}, .sizes = {0, 1}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {1}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {1}},
         .expected = false}
         .Test();
   }
@@ -5626,9 +5573,9 @@
     // Test that having starts and sizes lengths not equal to the input rank
     // will fail.
     SliceTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {4, 4}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {4, 4}},
         .attributes = {.starts = {0}, .sizes = {4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {4, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {4, 4}},
         .expected = false}
         .Test();
   }
@@ -5636,9 +5583,9 @@
     // Test that input data type not equal to the output data type will
     // fail.
     SliceTester{
-        .input = {.type = mojom::DataType::kFloat16, .dimensions = {4, 4}},
+        .input = {.type = OperandDataType::kFloat16, .dimensions = {4, 4}},
         .attributes = {.starts = {0, 0}, .sizes = {4, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {4, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {4, 4}},
         .expected = false}
         .Test();
   }
@@ -5703,32 +5650,32 @@
   {
     // Test the operator for 2-D tensor with float32 input.
     FloatingPointUnaryTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 6}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 6}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 6}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 6}},
         .expected = true}
         .Test();
   }
   {
     // Test the operator for 3-D tensor with float16 input.
     FloatingPointUnaryTester{
-        .input = {.type = mojom::DataType::kFloat16, .dimensions = {2, 6, 4}},
-        .output = {.type = mojom::DataType::kFloat16, .dimensions = {2, 6, 4}},
+        .input = {.type = OperandDataType::kFloat16, .dimensions = {2, 6, 4}},
+        .output = {.type = OperandDataType::kFloat16, .dimensions = {2, 6, 4}},
         .expected = true}
         .Test();
   }
   {
     // Test the invalid graph for the output shapes are not as expected.
     FloatingPointUnaryTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output data types which don't match.
     FloatingPointUnaryTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
@@ -5736,8 +5683,8 @@
     // Test the invalid graph when the input data type is not floating
     // point.
     FloatingPointUnaryTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {2}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {2}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {2}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
@@ -5747,7 +5694,7 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {2}, OperandDataType::kFloat32);
     builder.BuildLeakyRelu(input_operand_id, input_operand_id,
                            /*alpha*/ 1.0);
 
@@ -5759,9 +5706,9 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {2}, OperandDataType::kFloat32);
     uint64_t output_operand_id =
-        builder.BuildOutput("output", {2}, mojom::DataType::kFloat32);
+        builder.BuildOutput("output", {2}, OperandDataType::kFloat32);
     builder.BuildLeakyRelu(input_operand_id, output_operand_id,
                            /*alpha*/ NAN);
 
@@ -5773,7 +5720,7 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {2}, OperandDataType::kFloat32);
     builder.BuildLinear(input_operand_id, input_operand_id,
                         /*alpha*/ 1.0, /*beta*/ 0.0);
 
@@ -5785,9 +5732,9 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {2}, OperandDataType::kFloat32);
     uint64_t output_operand_id =
-        builder.BuildOutput("output", {2}, mojom::DataType::kFloat32);
+        builder.BuildOutput("output", {2}, OperandDataType::kFloat32);
     builder.BuildLinear(input_operand_id, output_operand_id,
                         /*alpha*/ NAN, /*beta*/ 0.0);
 
@@ -5799,9 +5746,9 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {2}, OperandDataType::kFloat32);
     uint64_t output_operand_id =
-        builder.BuildOutput("output", {2}, mojom::DataType::kFloat32);
+        builder.BuildOutput("output", {2}, OperandDataType::kFloat32);
     builder.BuildLinear(input_operand_id, output_operand_id,
                         /*alpha*/ 1.0, /*beta*/ NAN);
 
@@ -5814,7 +5761,7 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {2}, OperandDataType::kFloat32);
     builder.BuildSigmoid(input_operand_id, input_operand_id);
 
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
@@ -5825,7 +5772,7 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {2}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {2}, OperandDataType::kFloat32);
     builder.BuildTanh(input_operand_id, input_operand_id);
 
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
@@ -5859,8 +5806,8 @@
   {
     // Test softmax operator for input operand with [2, 2] dimensions.
     SoftmaxTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 2}},
         .axis = 1,
         .expected = true}
         .Test();
@@ -5868,17 +5815,17 @@
   {
     // Test softmax operator for input operand with [1, 4] dimensions.
     SoftmaxTester{
-        .input = {.type = mojom::DataType::kFloat16, .dimensions = {1, 4}},
-        .output = {.type = mojom::DataType::kFloat16, .dimensions = {1, 4}},
+        .input = {.type = OperandDataType::kFloat16, .dimensions = {1, 4}},
+        .output = {.type = OperandDataType::kFloat16, .dimensions = {1, 4}},
         .axis = 1,
         .expected = true}
         .Test();
   }
   {
     // Test softmax operator for input operand with [1, 1, 4, 2] dimensions.
-    SoftmaxTester{.input = {.type = mojom::DataType::kFloat32,
+    SoftmaxTester{.input = {.type = OperandDataType::kFloat32,
                             .dimensions = {1, 1, 4, 2}},
-                  .output = {.type = mojom::DataType::kFloat32,
+                  .output = {.type = OperandDataType::kFloat32,
                              .dimensions = {1, 1, 4, 2}},
                   .axis = 3,
                   .expected = true}
@@ -5887,8 +5834,8 @@
   {
     // Test the invalid graph when building softmax with int32 input.
     SoftmaxTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {2, 3}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {2, 3}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {2, 3}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {2, 3}},
         .axis = 1,
         .expected = false}
         .Test();
@@ -5896,8 +5843,8 @@
   {
     // Test the invalid graph for axis is not less than the input rank.
     SoftmaxTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 5}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 5}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 5}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 5}},
         .axis = 2,
         .expected = false}
         .Test();
@@ -5905,8 +5852,8 @@
   {
     // Test the invalid graph for the output shapes are not expected.
     SoftmaxTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .axis = 1,
         .expected = false}
         .Test();
@@ -5914,8 +5861,8 @@
   {
     // Test the invalid graph for output types don't match.
     SoftmaxTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 5}},
-        .output = {.type = mojom::DataType::kFloat16, .dimensions = {2, 5}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 5}},
+        .output = {.type = OperandDataType::kFloat16, .dimensions = {2, 5}},
         .axis = 1,
         .expected = false}
         .Test();
@@ -5947,32 +5894,32 @@
   {
     // Test softplus operator.
     SoftplusTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 2}},
         .expected = true}
         .Test();
   }
   {
     // Test the invalid graph for invalid data type.
     SoftplusTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {4, 2}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {4, 2}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {4, 2}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {4, 2}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the output shapes are not expected.
     SoftplusTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output types don't match.
     SoftplusTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 5}},
-        .output = {.type = mojom::DataType::kFloat16, .dimensions = {2, 5}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 5}},
+        .output = {.type = OperandDataType::kFloat16, .dimensions = {2, 5}},
         .expected = false}
         .Test();
   }
@@ -5981,7 +5928,7 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {4, 6}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {4, 6}, OperandDataType::kFloat32);
     builder.BuildSoftplus(input_operand_id, input_operand_id);
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
                                                builder.GetGraphInfo()));
@@ -6014,32 +5961,32 @@
     // Test softsign operator with input dimensions = [2, 4] and data type
     // float32.
     SoftsignTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
         .expected = true}
         .Test();
   }
   {
     // Test the invalid graph for invalid data type.
     SoftsignTester{
-        .input = {.type = mojom::DataType::kInt32, .dimensions = {4, 2}},
-        .output = {.type = mojom::DataType::kInt32, .dimensions = {4, 2}},
+        .input = {.type = OperandDataType::kInt32, .dimensions = {4, 2}},
+        .output = {.type = OperandDataType::kInt32, .dimensions = {4, 2}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for the output shapes are not expected.
     SoftsignTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output types don't match.
     SoftsignTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 5}},
-        .output = {.type = mojom::DataType::kFloat16, .dimensions = {2, 5}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 5}},
+        .output = {.type = OperandDataType::kFloat16, .dimensions = {2, 5}},
         .expected = false}
         .Test();
   }
@@ -6048,7 +5995,7 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {4, 6}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {4, 6}, OperandDataType::kFloat32);
     builder.BuildSoftsign(input_operand_id, input_operand_id);
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
                                                builder.GetGraphInfo()));
@@ -6083,7 +6030,7 @@
 };
 
 TEST_F(WebNNGraphImplTest, ValidateSplitTest) {
-  using mojom::DataType::kFloat32;
+  using OperandDataType::kFloat32;
   {
     // Tests default axis split.
     SplitTester{.input = {.type = kFloat32, .dimensions = {2, 2}},
@@ -6107,7 +6054,7 @@
     SplitTester{
         .input = {.type = kFloat32, .dimensions = {2, 2}},
         .outputs = {{.type = kFloat32, .dimensions = {1, 2}},
-                    {.type = mojom::DataType::kFloat16, .dimensions = {1, 2}}},
+                    {.type = OperandDataType::kFloat16, .dimensions = {1, 2}}},
         .expected = false}
         .Test();
   }
@@ -6144,14 +6091,6 @@
         .Test();
   }
   {
-    // Tests for an invalid graph where a split of size 0 is specified.
-    SplitTester{.input = {.type = kFloat32, .dimensions = {2, 2}},
-                .outputs = {{.type = kFloat32, .dimensions = {0, 2}},
-                            {.type = kFloat32, .dimensions = {2, 2}}},
-                .expected = false}
-        .Test();
-  }
-  {
     // Tests for an invalid graph where a split as specified along multiple
     // axis.
     SplitTester{.input = {.type = kFloat32, .dimensions = {4, 6}},
@@ -6200,10 +6139,10 @@
 TEST_F(WebNNGraphImplTest, TransposeTest) {
   {
     // Test transpose operator with permutation [2, 3, 1, 0].
-    TransposeTester{.input = {.type = mojom::DataType::kFloat32,
+    TransposeTester{.input = {.type = OperandDataType::kFloat32,
                               .dimensions = {1, 2, 3, 4}},
                     .permutation = {2, 3, 1, 0},
-                    .output = {.type = mojom::DataType::kFloat32,
+                    .output = {.type = OperandDataType::kFloat32,
                                .dimensions = {3, 4, 2, 1}},
                     .expected = true}
         .Test();
@@ -6212,9 +6151,9 @@
     // Test the invalid graph when the rank of permutation is larger than
     // the input rank.
     TransposeTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {1, 2, 3}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {1, 2, 3}},
         .permutation = {0, 1, 2, 2},
-        .output = {.type = mojom::DataType::kFloat32,
+        .output = {.type = OperandDataType::kFloat32,
                    .dimensions = {1, 2, 3, 3}},
         .expected = false}
         .Test();
@@ -6222,10 +6161,10 @@
   {
     // Test the invalid graph when the permutation contains duplicate
     // values.
-    TransposeTester{.input = {.type = mojom::DataType::kFloat32,
+    TransposeTester{.input = {.type = OperandDataType::kFloat32,
                               .dimensions = {1, 2, 3, 4}},
                     .permutation = {0, 1, 2, 2},
-                    .output = {.type = mojom::DataType::kFloat32,
+                    .output = {.type = OperandDataType::kFloat32,
                                .dimensions = {1, 2, 3, 3}},
                     .expected = false}
         .Test();
@@ -6233,10 +6172,10 @@
   {
     // Test the invalid graph when one value in permutation is greater than
     // input_rank - 1.
-    TransposeTester{.input = {.type = mojom::DataType::kFloat16,
+    TransposeTester{.input = {.type = OperandDataType::kFloat16,
                               .dimensions = {1, 2, 3, 4}},
                     .permutation = {0, 1, 2, 4},
-                    .output = {.type = mojom::DataType::kFloat16,
+                    .output = {.type = OperandDataType::kFloat16,
                                .dimensions = {1, 2, 3, 4}},
                     .expected = false}
         .Test();
@@ -6244,19 +6183,19 @@
   {
     // Test the invalid graph for output shapes are not expected.
     TransposeTester{
-        .input = {.type = mojom::DataType::kFloat32,
+        .input = {.type = OperandDataType::kFloat32,
                   .dimensions = {1, 2, 3, 4}},
         .permutation = {0, 1, 2, 3},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {1, 2, 3}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {1, 2, 3}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output types don't match.
-    TransposeTester{.input = {.type = mojom::DataType::kFloat32,
+    TransposeTester{.input = {.type = OperandDataType::kFloat32,
                               .dimensions = {1, 2, 3, 4}},
                     .permutation = {0, 1, 2, 3},
-                    .output = {.type = mojom::DataType::kFloat16,
+                    .output = {.type = OperandDataType::kFloat16,
                                .dimensions = {1, 2, 3, 4}},
                     .expected = false}
         .Test();
@@ -6291,26 +6230,26 @@
   {
     // Test triangular operator with upper = true and diagonal = 2.
     TriangularTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 2}},
         .upper = true,
         .diagonal = 2,
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 2}},
         .expected = true}
         .Test();
   }
   {
     // Test the invalid graph for the output shapes are not expected.
     TriangularTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {4, 2}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {4, 2}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph for output types don't match.
     TriangularTester{
-        .input = {.type = mojom::DataType::kFloat32, .dimensions = {2, 5}},
-        .output = {.type = mojom::DataType::kFloat16, .dimensions = {2, 5}},
+        .input = {.type = OperandDataType::kFloat32, .dimensions = {2, 5}},
+        .output = {.type = OperandDataType::kFloat16, .dimensions = {2, 5}},
         .expected = false}
         .Test();
   }
@@ -6319,7 +6258,7 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t input_operand_id =
-        builder.BuildInput("input", {4, 6}, mojom::DataType::kFloat32);
+        builder.BuildInput("input", {4, 6}, OperandDataType::kFloat32);
 
     builder.BuildTriangular(input_operand_id, input_operand_id,
                             /*upper*/ true, /*diagonal*/ -1);
@@ -6360,11 +6299,11 @@
   {
     // Test the invalid graph when the condition data type is not uint8.
     WhereTester{
-        .condition = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
-        .true_value = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
-        .false_value = {.type = mojom::DataType::kFloat32,
+        .condition = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
+        .true_value = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
+        .false_value = {.type = OperandDataType::kFloat32,
                         .dimensions = {2, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
         .expected = false}
         .Test();
   }
@@ -6372,11 +6311,11 @@
     // Test the invalid graph when the the data types of true_value and
     // false_value don't match.
     WhereTester{
-        .condition = {.type = mojom::DataType::kUint8, .dimensions = {2, 4}},
-        .true_value = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
-        .false_value = {.type = mojom::DataType::kFloat16,
+        .condition = {.type = OperandDataType::kUint8, .dimensions = {2, 4}},
+        .true_value = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
+        .false_value = {.type = OperandDataType::kFloat16,
                         .dimensions = {2, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
         .expected = false}
         .Test();
   }
@@ -6384,22 +6323,22 @@
     // Test the invalid graph when the the data types of output and
     // true_value don't match.
     WhereTester{
-        .condition = {.type = mojom::DataType::kUint8, .dimensions = {2, 4}},
-        .true_value = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
-        .false_value = {.type = mojom::DataType::kFloat32,
+        .condition = {.type = OperandDataType::kUint8, .dimensions = {2, 4}},
+        .true_value = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
+        .false_value = {.type = OperandDataType::kFloat32,
                         .dimensions = {2, 4}},
-        .output = {.type = mojom::DataType::kFloat16, .dimensions = {2, 4}},
+        .output = {.type = OperandDataType::kFloat16, .dimensions = {2, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph when the the shape of output is wrong.
     WhereTester{
-        .condition = {.type = mojom::DataType::kUint8, .dimensions = {2, 4}},
-        .true_value = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
-        .false_value = {.type = mojom::DataType::kFloat32,
+        .condition = {.type = OperandDataType::kUint8, .dimensions = {2, 4}},
+        .true_value = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
+        .false_value = {.type = OperandDataType::kFloat32,
                         .dimensions = {2, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 5}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 5}},
         .expected = false}
         .Test();
   }
@@ -6407,22 +6346,22 @@
     // Test the invalid graph when the shapes of true_value and false_value
     // are not broadcastable.
     WhereTester{
-        .condition = {.type = mojom::DataType::kUint8, .dimensions = {2, 4}},
-        .true_value = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
-        .false_value = {.type = mojom::DataType::kFloat32,
+        .condition = {.type = OperandDataType::kUint8, .dimensions = {2, 4}},
+        .true_value = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
+        .false_value = {.type = OperandDataType::kFloat32,
                         .dimensions = {2, 3}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
         .expected = false}
         .Test();
   }
   {
     // Test the invalid graph when the condition shape is not broadcastable.
     WhereTester{
-        .condition = {.type = mojom::DataType::kUint8, .dimensions = {2, 4}},
-        .true_value = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3}},
-        .false_value = {.type = mojom::DataType::kFloat32,
+        .condition = {.type = OperandDataType::kUint8, .dimensions = {2, 4}},
+        .true_value = {.type = OperandDataType::kFloat32, .dimensions = {2, 3}},
+        .false_value = {.type = OperandDataType::kFloat32,
                         .dimensions = {2, 1}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
         .expected = false}
         .Test();
   }
@@ -6430,11 +6369,11 @@
     // Test where with 2-D condition, 2-D true_value and 2-D false_value using
     // broadcast.
     WhereTester{
-        .condition = {.type = mojom::DataType::kUint8, .dimensions = {2, 1}},
-        .true_value = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
-        .false_value = {.type = mojom::DataType::kFloat32,
+        .condition = {.type = OperandDataType::kUint8, .dimensions = {2, 1}},
+        .true_value = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
+        .false_value = {.type = OperandDataType::kFloat32,
                         .dimensions = {2, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 4}},
         .expected = true}
         .Test();
   }
@@ -6442,11 +6381,11 @@
     // Test where with 2-D condition, 2-D true_value and 3-D false_value using
     // broadcast.
     WhereTester{
-        .condition = {.type = mojom::DataType::kUint8, .dimensions = {1, 4}},
-        .true_value = {.type = mojom::DataType::kFloat32, .dimensions = {3, 4}},
-        .false_value = {.type = mojom::DataType::kFloat32,
+        .condition = {.type = OperandDataType::kUint8, .dimensions = {1, 4}},
+        .true_value = {.type = OperandDataType::kFloat32, .dimensions = {3, 4}},
+        .false_value = {.type = OperandDataType::kFloat32,
                         .dimensions = {2, 3, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 3, 4}},
         .expected = true}
         .Test();
   }
@@ -6454,25 +6393,25 @@
     // Test where with 3-D condition, 3-D true_value and 3-D false_value using
     // broadcast.
     WhereTester{
-        .condition = {.type = mojom::DataType::kUint8, .dimensions = {2, 1, 4}},
-        .true_value = {.type = mojom::DataType::kFloat32,
+        .condition = {.type = OperandDataType::kUint8, .dimensions = {2, 1, 4}},
+        .true_value = {.type = OperandDataType::kFloat32,
                        .dimensions = {2, 3, 4}},
-        .false_value = {.type = mojom::DataType::kFloat32,
+        .false_value = {.type = OperandDataType::kFloat32,
                         .dimensions = {1, 4}},
-        .output = {.type = mojom::DataType::kFloat32, .dimensions = {2, 3, 4}},
+        .output = {.type = OperandDataType::kFloat32, .dimensions = {2, 3, 4}},
         .expected = true}
         .Test();
   }
   {
     // Test where with 4-D condition, 3-D true_value and 2-D false_value using
     // broadcast.
-    WhereTester{.condition = {.type = mojom::DataType::kUint8,
+    WhereTester{.condition = {.type = OperandDataType::kUint8,
                               .dimensions = {2, 3, 4, 5}},
-                .true_value = {.type = mojom::DataType::kFloat32,
+                .true_value = {.type = OperandDataType::kFloat32,
                                .dimensions = {3, 4, 5}},
-                .false_value = {.type = mojom::DataType::kFloat32,
+                .false_value = {.type = OperandDataType::kFloat32,
                                 .dimensions = {4, 5}},
-                .output = {.type = mojom::DataType::kFloat32,
+                .output = {.type = OperandDataType::kFloat32,
                            .dimensions = {2, 3, 4, 5}},
                 .expected = true}
         .Test();
@@ -6482,11 +6421,11 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t condition_operand_id =
-        builder.BuildInput("condition", {2, 4}, mojom::DataType::kUint8);
+        builder.BuildInput("condition", {2, 4}, OperandDataType::kUint8);
     uint64_t true_value_operand_id =
-        builder.BuildInput("true_value", {2, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("true_value", {2, 4}, OperandDataType::kFloat32);
     uint64_t false_value_operand_id =
-        builder.BuildInput("false_value", {2, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("false_value", {2, 4}, OperandDataType::kFloat32);
     builder.BuildWhere(condition_operand_id, true_value_operand_id,
                        false_value_operand_id, condition_operand_id);
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
@@ -6497,11 +6436,11 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t condition_operand_id =
-        builder.BuildInput("condition", {2, 4}, mojom::DataType::kUint8);
+        builder.BuildInput("condition", {2, 4}, OperandDataType::kUint8);
     uint64_t true_value_operand_id =
-        builder.BuildInput("true_value", {2, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("true_value", {2, 4}, OperandDataType::kFloat32);
     uint64_t false_value_operand_id =
-        builder.BuildInput("false_value", {2, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("false_value", {2, 4}, OperandDataType::kFloat32);
     builder.BuildWhere(condition_operand_id, true_value_operand_id,
                        false_value_operand_id, true_value_operand_id);
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
@@ -6512,11 +6451,11 @@
     auto context_properties = GetContextPropertiesForTesting();
     GraphInfoBuilder builder;
     uint64_t condition_operand_id =
-        builder.BuildInput("condition", {2, 4}, mojom::DataType::kUint8);
+        builder.BuildInput("condition", {2, 4}, OperandDataType::kUint8);
     uint64_t true_value_operand_id =
-        builder.BuildInput("true_value", {2, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("true_value", {2, 4}, OperandDataType::kFloat32);
     uint64_t false_value_operand_id =
-        builder.BuildInput("false_value", {2, 4}, mojom::DataType::kFloat32);
+        builder.BuildInput("false_value", {2, 4}, OperandDataType::kFloat32);
     builder.BuildWhere(condition_operand_id, true_value_operand_id,
                        false_value_operand_id, false_value_operand_id);
     EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
@@ -6530,11 +6469,11 @@
   // Build the graph with mojo type.
   GraphInfoBuilder builder;
   uint64_t lhs_operand_id =
-      builder.BuildInput("lhs", dimensions, mojom::DataType::kUint8);
+      builder.BuildInput("lhs", dimensions, OperandDataType::kUint8);
   uint64_t rhs_operand_id =
-      builder.BuildInput("rhs", dimensions, mojom::DataType::kUint8);
+      builder.BuildInput("rhs", dimensions, OperandDataType::kUint8);
   uint64_t output_operand_id =
-      builder.BuildOutput("output", dimensions, mojom::DataType::kUint8);
+      builder.BuildOutput("output", dimensions, OperandDataType::kUint8);
   builder.BuildElementWiseBinary(mojom::ElementWiseBinary::Kind::kAdd,
                                  lhs_operand_id, rhs_operand_id,
                                  output_operand_id);
@@ -6587,7 +6526,7 @@
 TEST_F(WebNNGraphImplTest, ValidateDispatchTest) {
   auto context_properties = GetContextPropertiesForTesting();
   // TODO(crbug.com/325598628): De-dup these data type constants.
-  const mojom::DataType kMojoDataType = mojom::DataType::kUint8;
+  const OperandDataType kMojoDataType = OperandDataType::kUint8;
   const OperandDataType kDataType = OperandDataType::kUint8;
   const std::vector<uint32_t> kShape = {3, 5};
   // Build the graph with mojo type.
@@ -6798,11 +6737,11 @@
     // Build the graph with mojo type.
     GraphInfoBuilder builder;
     uint64_t lhs_operand_id =
-        builder.BuildInput("lhs", dimensions, mojom::DataType::kUint8);
+        builder.BuildInput("lhs", dimensions, OperandDataType::kUint8);
     uint64_t rhs_operand_id =
-        builder.BuildConstant(dimensions, mojom::DataType::kUint8, values);
+        builder.BuildConstant(dimensions, OperandDataType::kUint8, values);
     uint64_t output_operand_id =
-        builder.BuildOutput("output", dimensions, mojom::DataType::kUint8);
+        builder.BuildOutput("output", dimensions, OperandDataType::kUint8);
     builder.BuildElementWiseBinary(mojom::ElementWiseBinary::Kind::kAdd,
                                    lhs_operand_id, rhs_operand_id,
                                    output_operand_id);
@@ -6839,24 +6778,24 @@
   GraphInfoBuilder builder;
   // The graph outputs are built first, and then inputs / constants.
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {2, 2}, OperandDataType::kFloat32);
   uint64_t input_a_operand_id =
-      builder.BuildInput("input_a", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_a", {2, 2}, OperandDataType::kFloat32);
   std::vector<float> constant_data = {5.0, 6.0, 7.0, 8.0};
   uint64_t constant_a_operand_id = builder.BuildConstant(
-      {2, 2}, mojom::DataType::kFloat32, base::as_byte_span(constant_data));
+      {2, 2}, OperandDataType::kFloat32, base::as_byte_span(constant_data));
 
   uint64_t intermediate_1_operand_id =
-      builder.BuildIntermediateOperand({2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({2, 2}, OperandDataType::kFloat32);
   builder.BuildGemm(input_a_operand_id, constant_a_operand_id,
                     intermediate_1_operand_id, GemmTester::GemmAttributes());
 
   uint64_t input_b_operand_id =
-      builder.BuildInput("input_b", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_b", {2, 2}, OperandDataType::kFloat32);
   uint64_t constant_b_operand_id = builder.BuildConstant(
-      {2, 2}, mojom::DataType::kFloat32, base::as_byte_span(constant_data));
+      {2, 2}, OperandDataType::kFloat32, base::as_byte_span(constant_data));
   uint64_t intermediate_2_operand_id =
-      builder.BuildIntermediateOperand({2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({2, 2}, OperandDataType::kFloat32);
   builder.BuildGemm(input_b_operand_id, constant_b_operand_id,
                     intermediate_2_operand_id, GemmTester::GemmAttributes());
   builder.BuildGemm(intermediate_1_operand_id, intermediate_2_operand_id,
@@ -6878,23 +6817,23 @@
   GraphInfoBuilder builder;
   // The graph outputs are built first, and then inputs / constants.
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildOutput("output", {2, 2}, OperandDataType::kFloat32);
   std::vector<float> constant_data = {5.0, 6.0, 7.0, 8.0};
   uint64_t constant_a_operand_id = builder.BuildConstant(
-      {2, 2}, mojom::DataType::kFloat32, base::as_byte_span(constant_data));
+      {2, 2}, OperandDataType::kFloat32, base::as_byte_span(constant_data));
   uint64_t input_a_operand_id =
-      builder.BuildInput("input_a", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_a", {2, 2}, OperandDataType::kFloat32);
   uint64_t intermediate_1_operand_id =
-      builder.BuildIntermediateOperand({2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({2, 2}, OperandDataType::kFloat32);
   builder.BuildGemm(constant_a_operand_id, input_a_operand_id,
                     intermediate_1_operand_id, GemmTester::GemmAttributes());
 
   uint64_t input_b_operand_id =
-      builder.BuildInput("input_b", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_b", {2, 2}, OperandDataType::kFloat32);
   uint64_t constant_b_operand_id = builder.BuildConstant(
-      {2, 2}, mojom::DataType::kFloat32, base::as_byte_span(constant_data));
+      {2, 2}, OperandDataType::kFloat32, base::as_byte_span(constant_data));
   uint64_t intermediate_2_operand_id =
-      builder.BuildIntermediateOperand({2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({2, 2}, OperandDataType::kFloat32);
   builder.BuildGemm(constant_b_operand_id, input_b_operand_id,
                     intermediate_2_operand_id, GemmTester::GemmAttributes());
 
@@ -6908,12 +6847,12 @@
   auto context_properties = GetContextPropertiesForTesting();
   GraphInfoBuilder builder;
   uint64_t input_operand_id =
-      builder.BuildInput("input_a", {2, 2}, mojom::DataType::kFloat32);
+      builder.BuildInput("input_a", {2, 2}, OperandDataType::kFloat32);
 
   uint64_t intermediate_operand_id =
-      builder.BuildIntermediateOperand({2, 2}, mojom::DataType::kFloat32);
+      builder.BuildIntermediateOperand({2, 2}, OperandDataType::kFloat32);
   uint64_t output_operand_id =
-      builder.BuildOutput("output", {2, 2}, mojom::DataType::kUint8);
+      builder.BuildOutput("output", {2, 2}, OperandDataType::kUint8);
   builder.BuildRelu(intermediate_operand_id, output_operand_id);
   builder.BuildRelu(input_operand_id, intermediate_operand_id);
   EXPECT_FALSE(WebNNGraphImpl::ValidateGraph(*context_properties,
diff --git a/services/webnn/webnn_test_utils.cc b/services/webnn/webnn_test_utils.cc
index a716552..d832158 100644
--- a/services/webnn/webnn_test_utils.cc
+++ b/services/webnn/webnn_test_utils.cc
@@ -14,11 +14,11 @@
 GraphInfoBuilder::~GraphInfoBuilder() = default;
 
 uint64_t GraphInfoBuilder::BuildOperand(const std::vector<uint32_t>& dimensions,
-                                        mojom::DataType type,
+                                        OperandDataType type,
                                         mojom::Operand::Kind kind) {
   mojom::OperandPtr operand = mojom::Operand::New();
-  operand->data_type = type;
-  operand->dimensions = dimensions;
+
+  operand->descriptor = *OperandDescriptor::Create(type, dimensions);
   operand->kind = kind;
 
   CHECK(graph_info_->id_to_operand_map.find(operand_id_) ==
@@ -29,13 +29,13 @@
 
 uint64_t GraphInfoBuilder::BuildIntermediateOperand(
     const std::vector<uint32_t>& dimensions,
-    mojom::DataType type) {
+    OperandDataType type) {
   return BuildOperand(dimensions, type, mojom::Operand::Kind::kOutput);
 }
 
 uint64_t GraphInfoBuilder::BuildInput(const std::string& name,
                                       const std::vector<uint32_t>& dimensions,
-                                      mojom::DataType type) {
+                                      OperandDataType type) {
   uint64_t operand_id =
       BuildOperand(dimensions, type, mojom::Operand::Kind::kInput);
   graph_info_->id_to_operand_map[operand_id]->name = name;
@@ -45,7 +45,7 @@
 
 uint64_t GraphInfoBuilder::BuildConstant(
     const std::vector<uint32_t>& dimensions,
-    mojom::DataType type,
+    OperandDataType type,
     base::span<const uint8_t> values) {
   uint64_t operand_id =
       BuildOperand(dimensions, type, mojom::Operand::Kind::kConstant);
@@ -61,7 +61,7 @@
 
 uint64_t GraphInfoBuilder::BuildOutput(const std::string& name,
                                        const std::vector<uint32_t>& dimensions,
-                                       mojom::DataType type) {
+                                       OperandDataType type) {
   uint64_t operand_id = BuildOperand(dimensions, type);
   AddOutput(name, operand_id);
   return operand_id;
diff --git a/services/webnn/webnn_test_utils.h b/services/webnn/webnn_test_utils.h
index 6268de63..7d80b61 100644
--- a/services/webnn/webnn_test_utils.h
+++ b/services/webnn/webnn_test_utils.h
@@ -8,6 +8,7 @@
 #include <string>
 #include <vector>
 
+#include "services/webnn/public/cpp/operand_descriptor.h"
 #include "services/webnn/public/mojom/webnn_context_provider.mojom.h"
 #include "services/webnn/public/mojom/webnn_graph.mojom.h"
 
@@ -25,21 +26,21 @@
   ~GraphInfoBuilder();
 
   uint64_t BuildIntermediateOperand(const std::vector<uint32_t>& dimensions,
-                                    mojom::DataType type);
+                                    OperandDataType type);
 
   uint64_t BuildInput(const std::string& name,
                       const std::vector<uint32_t>& dimensions,
-                      mojom::DataType type);
+                      OperandDataType type);
 
   uint64_t BuildConstant(const std::vector<uint32_t>& dimensions,
-                         mojom::DataType type,
+                         OperandDataType type,
                          base::span<const uint8_t> values);
 
   void AddOutput(const std::string& name, uint64_t operand_id);
 
   uint64_t BuildOutput(const std::string& name,
                        const std::vector<uint32_t>& dimensions,
-                       mojom::DataType type);
+                       OperandDataType type);
 
   // An `Activation` type should have the following members:
   // struct Activation {
@@ -594,7 +595,7 @@
  private:
   uint64_t BuildOperand(
       const std::vector<uint32_t>& dimensions,
-      mojom::DataType type,
+      OperandDataType type,
       mojom::Operand::Kind kind = mojom::Operand::Kind::kOutput);
 
   mojom::GraphInfoPtr graph_info_;
diff --git a/services/webnn/webnn_utils.cc b/services/webnn/webnn_utils.cc
index 12eb5558..b3a3365 100644
--- a/services/webnn/webnn_utils.cc
+++ b/services/webnn/webnn_utils.cc
@@ -248,23 +248,23 @@
   }
 }
 
-std::string DataTypeToString(mojom::DataType type) {
+std::string DataTypeToString(OperandDataType type) {
   switch (type) {
-    case mojom::DataType::kFloat32:
+    case OperandDataType::kFloat32:
       return "float32";
-    case mojom::DataType::kFloat16:
+    case OperandDataType::kFloat16:
       return "float16";
-    case mojom::DataType::kInt32:
+    case OperandDataType::kInt32:
       return "int32";
-    case mojom::DataType::kUint32:
+    case OperandDataType::kUint32:
       return "uint32";
-    case mojom::DataType::kInt8:
+    case OperandDataType::kInt8:
       return "int8";
-    case mojom::DataType::kUint8:
+    case OperandDataType::kUint8:
       return "uint8";
-    case mojom::DataType::kInt64:
+    case OperandDataType::kInt64:
       return "int64";
-    case mojom::DataType::kUint64:
+    case OperandDataType::kUint64:
       return "uint64";
   }
 }
@@ -299,31 +299,31 @@
 
 std::string NotSupportedArgumentTypeError(std::string_view op_name,
                                           std::string_view argument_name,
-                                          mojom::DataType type) {
+                                          OperandDataType type) {
   return base::StrCat({"Unsupported data type ", DataTypeToString(type),
                        " for ", op_name, " argument ", argument_name, "."});
 }
 
-std::string NotSupportedConstantTypeError(mojom::DataType type) {
+std::string NotSupportedConstantTypeError(OperandDataType type) {
   return base::StrCat(
       {"Unsupported data type ", DataTypeToString(type), " for constant."});
 }
 
 std::string NotSupportedInputArgumentTypeError(std::string_view op_name,
-                                               mojom::DataType type) {
+                                               OperandDataType type) {
   return base::StrCat({"Unsupported data type ", DataTypeToString(type),
                        " for ", op_name, " argument input."});
 }
 
 std::string NotSupportedInputTypeError(std::string_view input_name,
-                                       mojom::DataType type) {
+                                       OperandDataType type) {
   return base::StrCat({"Unsupported data type ", DataTypeToString(type),
                        " for input operand ", input_name});
 }
 
 std::string NotSupportedOptionTypeError(std::string_view op_name,
                                         std::string_view option_name,
-                                        mojom::DataType type) {
+                                        OperandDataType type) {
   return base::StrCat({"Unsupported data type ", DataTypeToString(type),
                        " for ", op_name, " option ", option_name});
 }
@@ -342,25 +342,4 @@
   return permuted_array;
 }
 
-OperandDataType ToOperandDataType(mojom::DataType data_type) {
-  switch (data_type) {
-    case mojom::DataType::kFloat32:
-      return OperandDataType::kFloat32;
-    case mojom::DataType::kFloat16:
-      return OperandDataType::kFloat16;
-    case mojom::DataType::kInt32:
-      return OperandDataType::kInt32;
-    case mojom::DataType::kUint32:
-      return OperandDataType::kUint32;
-    case mojom::DataType::kInt64:
-      return OperandDataType::kInt64;
-    case mojom::DataType::kUint64:
-      return OperandDataType::kUint64;
-    case mojom::DataType::kInt8:
-      return OperandDataType::kInt8;
-    case mojom::DataType::kUint8:
-      return OperandDataType::kUint8;
-  }
-}
-
 }  // namespace webnn
diff --git a/services/webnn/webnn_utils.h b/services/webnn/webnn_utils.h
index dce0ee5..de4446f5 100644
--- a/services/webnn/webnn_utils.h
+++ b/services/webnn/webnn_utils.h
@@ -117,7 +117,7 @@
 std::string COMPONENT_EXPORT(WEBNN_UTILS)
     OpKindToString(mojom::Reduce::Kind kind);
 std::string COMPONENT_EXPORT(WEBNN_UTILS)
-    DataTypeToString(mojom::DataType type);
+    DataTypeToString(OperandDataType type);
 std::string COMPONENT_EXPORT(WEBNN_UTILS) GetOpName(const mojom::Operation& op);
 std::string COMPONENT_EXPORT(WEBNN_UTILS)
     NotSupportedOperatorError(const mojom::Operation& op);
@@ -126,19 +126,19 @@
 std::string COMPONENT_EXPORT(WEBNN_UTILS)
     NotSupportedArgumentTypeError(std::string_view op_name,
                                   std::string_view argument_name,
-                                  mojom::DataType type);
+                                  OperandDataType type);
 std::string COMPONENT_EXPORT(WEBNN_UTILS)
-    NotSupportedConstantTypeError(mojom::DataType type);
+    NotSupportedConstantTypeError(OperandDataType type);
 std::string COMPONENT_EXPORT(WEBNN_UTILS)
     NotSupportedInputArgumentTypeError(std::string_view op_name,
-                                       mojom::DataType type);
+                                       OperandDataType type);
 std::string COMPONENT_EXPORT(WEBNN_UTILS)
     NotSupportedInputTypeError(std::string_view input_name,
-                               mojom::DataType type);
+                               OperandDataType type);
 std::string COMPONENT_EXPORT(WEBNN_UTILS)
     NotSupportedOptionTypeError(std::string_view op_name,
                                 std::string_view option_name,
-                                mojom::DataType type);
+                                OperandDataType type);
 
 // The length of `permutation` must be the same as `array`. The values in
 // `permutation` must be within the range [0, N-1] where N is the length of
@@ -150,11 +150,6 @@
     PermuteArray(base::span<const uint32_t> array,
                  base::span<const uint32_t> permutation);
 
-// TOOD(crbug.com/325598628): Remove this method once `mojom::DataType` is no
-// longer in use.
-OperandDataType COMPONENT_EXPORT(WEBNN_UTILS)
-    ToOperandDataType(mojom::DataType data_type);
-
 }  // namespace webnn
 
 #endif  // SERVICES_WEBNN_WEBNN_UTILS_H_
diff --git a/testing/android/instrumentation/BUILD.gn b/testing/android/instrumentation/BUILD.gn
index f8964c2d..4897718 100644
--- a/testing/android/instrumentation/BUILD.gn
+++ b/testing/android/instrumentation/BUILD.gn
@@ -4,16 +4,22 @@
 
 import("//build/config/android/rules.gni")
 
-android_library("instrumentation_test_runner_java") {
+android_library("test_runner_java") {
   testonly = true
   sources = [
     "java/src/org/chromium/testing/TestListInstrumentationRunListener.java",
   ]
-  mergeable_android_manifests = [ "java/AndroidManifest.xml" ]
+  mergeable_android_manifests = [ "java/AndroidManifest_runner.xml" ]
   deps = [
+    ":test_runner_permissions_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_test_monitor_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/junit:junit",
   ]
 }
+
+# Split into its own target because it is also needed by any APK that is an "apk_under_test".
+java_group("test_runner_permissions_java") {
+  mergeable_android_manifests = [ "java/AndroidManifest_permissions.xml" ]
+}
diff --git a/testing/android/instrumentation/java/AndroidManifest_permissions.xml b/testing/android/instrumentation/java/AndroidManifest_permissions.xml
new file mode 100644
index 0000000..e5dce69
--- /dev/null
+++ b/testing/android/instrumentation/java/AndroidManifest_permissions.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2024 The Chromium Authors
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    package="org.chromium.instrumentation">
+    <!-- To write post-test screenshots, coverage data, profiling data. -->
+    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <!-- To read side-loaded test data (test runtime deps). -->
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <!-- For @Restriction(RESTRICTION_TYPE_INTERNET). -->
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+    <!-- For TestAnimations (disabling Android window animations). -->
+    <uses-permission android:name="android.permission.SET_ANIMATION_SCALE" tools:ignore="ProtectedPermissions" />
+    <!-- Needed to run tests. -->
+    <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" />
+
+    <!-- To avoid scoped storage in Android 10:
+         https://developer.android.com/training/data-storage#scoped-storage
+         https://developer.android.com/training/data-storage/compatibility -->
+    <application android:requestLegacyExternalStorage="true"></application>
+</manifest>
diff --git a/testing/android/instrumentation/java/AndroidManifest.xml b/testing/android/instrumentation/java/AndroidManifest_runner.xml
similarity index 100%
rename from testing/android/instrumentation/java/AndroidManifest.xml
rename to testing/android/instrumentation/java/AndroidManifest_runner.xml
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index 8a56204..c74bad0 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -13147,7 +13147,9 @@
     "isolated_scripts": [
       {
         "args": [
-          "--avd-config=../../tools/android/avd/proto/android_33_google_apis_x64.textpb"
+          "--avd-config=../../tools/android/avd/proto/android_33_google_apis_x64.textpb",
+          "--test-list",
+          "../../third_party/blink/web_tests/TestLists/android.filter"
         ],
         "description": "Run with android_33_google_apis_x64",
         "merge": {
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 5cff71a2..91e7482 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -27152,7 +27152,7 @@
             }
           },
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 33
+          "shards": 29
         },
         "test": "webview_instrumentation_test_apk",
         "test_id_prefix": "ninja://android_webview/test:webview_instrumentation_test_apk/"
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 9ac4506..3ab811c 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -3452,7 +3452,7 @@
             "os": "Ubuntu-22.04"
           },
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 10
+          "shards": 11
         },
         "test": "browser_tests",
         "test_id_prefix": "ninja://chrome/test:browser_tests/"
@@ -5487,9 +5487,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6541.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6542.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 128.0.6541.0",
+        "description": "Run with ash-chrome version 128.0.6542.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5499,8 +5499,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v128.0.6541.0",
-              "revision": "version:128.0.6541.0"
+              "location": "lacros_version_skew_tests_v128.0.6542.0",
+              "revision": "version:128.0.6542.0"
             }
           ],
           "dimensions": {
@@ -5643,9 +5643,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6541.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6542.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 128.0.6541.0",
+        "description": "Run with ash-chrome version 128.0.6542.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5655,8 +5655,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v128.0.6541.0",
-              "revision": "version:128.0.6541.0"
+              "location": "lacros_version_skew_tests_v128.0.6542.0",
+              "revision": "version:128.0.6542.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json
index 4ae624c..9285e5bb 100644
--- a/testing/buildbot/chromium.coverage.json
+++ b/testing/buildbot/chromium.coverage.json
@@ -19667,9 +19667,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6541.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6542.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 128.0.6541.0",
+        "description": "Run with ash-chrome version 128.0.6542.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -19679,8 +19679,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v128.0.6541.0",
-              "revision": "version:128.0.6541.0"
+              "location": "lacros_version_skew_tests_v128.0.6542.0",
+              "revision": "version:128.0.6542.0"
             }
           ],
           "dimensions": {
@@ -19823,9 +19823,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6541.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6542.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 128.0.6541.0",
+        "description": "Run with ash-chrome version 128.0.6542.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -19835,8 +19835,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v128.0.6541.0",
-              "revision": "version:128.0.6541.0"
+              "location": "lacros_version_skew_tests_v128.0.6542.0",
+              "revision": "version:128.0.6542.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index aede34d9..e567149 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -42583,9 +42583,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6541.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6542.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 128.0.6541.0",
+        "description": "Run with ash-chrome version 128.0.6542.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -42594,8 +42594,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v128.0.6541.0",
-              "revision": "version:128.0.6541.0"
+              "location": "lacros_version_skew_tests_v128.0.6542.0",
+              "revision": "version:128.0.6542.0"
             }
           ],
           "dimensions": {
@@ -42733,9 +42733,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6541.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6542.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 128.0.6541.0",
+        "description": "Run with ash-chrome version 128.0.6542.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -42744,8 +42744,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v128.0.6541.0",
-              "revision": "version:128.0.6541.0"
+              "location": "lacros_version_skew_tests_v128.0.6542.0",
+              "revision": "version:128.0.6542.0"
             }
           ],
           "dimensions": {
@@ -44082,9 +44082,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6541.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6542.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 128.0.6541.0",
+        "description": "Run with ash-chrome version 128.0.6542.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -44094,8 +44094,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v128.0.6541.0",
-              "revision": "version:128.0.6541.0"
+              "location": "lacros_version_skew_tests_v128.0.6542.0",
+              "revision": "version:128.0.6542.0"
             }
           ],
           "dimensions": {
@@ -44238,9 +44238,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6541.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6542.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 128.0.6541.0",
+        "description": "Run with ash-chrome version 128.0.6542.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -44250,8 +44250,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v128.0.6541.0",
-              "revision": "version:128.0.6541.0"
+              "location": "lacros_version_skew_tests_v128.0.6542.0",
+              "revision": "version:128.0.6542.0"
             }
           ],
           "dimensions": {
@@ -45563,9 +45563,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6541.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6542.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 128.0.6541.0",
+        "description": "Run with ash-chrome version 128.0.6542.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -45574,8 +45574,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v128.0.6541.0",
-              "revision": "version:128.0.6541.0"
+              "location": "lacros_version_skew_tests_v128.0.6542.0",
+              "revision": "version:128.0.6542.0"
             }
           ],
           "dimensions": {
@@ -45713,9 +45713,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6541.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6542.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 128.0.6541.0",
+        "description": "Run with ash-chrome version 128.0.6542.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -45724,8 +45724,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v128.0.6541.0",
-              "revision": "version:128.0.6541.0"
+              "location": "lacros_version_skew_tests_v128.0.6542.0",
+              "revision": "version:128.0.6542.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index b1cd0a35..bfc7c9f 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -15763,12 +15763,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6541.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6542.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 128.0.6541.0",
+        "description": "Run with ash-chrome version 128.0.6542.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -15778,8 +15778,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v128.0.6541.0",
-              "revision": "version:128.0.6541.0"
+              "location": "lacros_version_skew_tests_v128.0.6542.0",
+              "revision": "version:128.0.6542.0"
             }
           ],
           "dimensions": {
@@ -15939,12 +15939,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6541.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6542.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 128.0.6541.0",
+        "description": "Run with ash-chrome version 128.0.6542.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -15954,8 +15954,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v128.0.6541.0",
-              "revision": "version:128.0.6541.0"
+              "location": "lacros_version_skew_tests_v128.0.6542.0",
+              "revision": "version:128.0.6542.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/filters/ios.use_blink.components_unittests.filter b/testing/buildbot/filters/ios.use_blink.components_unittests.filter
index 50c651d..c992c7c 100644
--- a/testing/buildbot/filters/ios.use_blink.components_unittests.filter
+++ b/testing/buildbot/filters/ios.use_blink.components_unittests.filter
@@ -247,3 +247,50 @@
 -ProfileInteractionManagerTestSuiteInstantiation/ProfileInteractionManagerTest.OnPageActivationComputesLevelAndDecision/FPFEnabled_UserOptIn_NoException
 -ProfileInteractionManagerTestSuiteInstantiation/ProfileInteractionManagerTest.OnPageActivationComputesLevelAndDecision/FPFEnabled_UserOptIn_NoException_EnableOn3pcBlocked_3pcBlocked
 -ProfileInteractionManagerTestSuiteInstantiation/ProfileInteractionManagerTest.OnPageActivationComputesLevelAndDecision/FPFEnabled_UserOptOut_Exception
+
+#TODO(crbug.com/347197919): ThrottleManagerEnabledTest has been failing since
+# https://crrev.com/c/5527553. Need to consider if we can support the
+# fingerprinting protection feature.
+-All/ThrottleManagerEnabledTest.ActivateMainFrameAndFilterDryRun/0
+-All/ThrottleManagerEnabledTest.ActivateMainFrameAndFilterDryRun/1
+-All/ThrottleManagerEnabledTest.ActivateMainFrameAndFilterFencedFrameNavigation/0
+-All/ThrottleManagerEnabledTest.ActivateMainFrameAndFilterFencedFrameNavigation/1
+-All/ThrottleManagerEnabledTest.ActivateMainFrameAndFilterFencedFrameNavigationOnRedirect/0
+-All/ThrottleManagerEnabledTest.ActivateMainFrameAndFilterFencedFrameNavigationOnRedirect/1
+-All/ThrottleManagerEnabledTest.ActivateMainFrameAndFilterSubframeNavigation/0
+-All/ThrottleManagerEnabledTest.ActivateMainFrameAndFilterSubframeNavigation/1
+-All/ThrottleManagerEnabledTest.ActivateMainFrameAndFilterSubframeNavigationOnRedirect/0
+-All/ThrottleManagerEnabledTest.ActivateMainFrameAndFilterSubframeNavigationOnRedirect/1
+-All/ThrottleManagerEnabledTest.ActivateMainFrameAndFilterTwoSubframeNavigations/0
+-All/ThrottleManagerEnabledTest.ActivateMainFrameAndFilterTwoSubframeNavigations/1
+-All/ThrottleManagerEnabledTest.ActivateTwoMainFramesAndFilterTwoSubframeNavigations/0
+-All/ThrottleManagerEnabledTest.ActivateTwoMainFramesAndFilterTwoSubframeNavigations/1
+-All/ThrottleManagerEnabledTest.ActivationPropagation/0
+-All/ThrottleManagerEnabledTest.ActivationPropagation/1
+-All/ThrottleManagerEnabledTest.ActivationPropagation_FencedFrame/0
+-All/ThrottleManagerEnabledTest.ActivationPropagation_FencedFrame/1
+-All/ThrottleManagerEnabledTest.CreateHelperForWebContents/0
+-All/ThrottleManagerEnabledTest.CreateHelperForWebContents/1
+-All/ThrottleManagerEnabledTest.DoNotFilterForInactiveFrame/0
+-All/ThrottleManagerEnabledTest.DoNotFilterForInactiveFrame/1
+-All/ThrottleManagerEnabledTest.FailedNavigationToErrorPage_NoActivation/0
+-All/ThrottleManagerEnabledTest.FailedNavigationToErrorPage_NoActivation/1
+-All/ThrottleManagerEnabledTest.NoPageActivation/0
+-All/ThrottleManagerEnabledTest.NoPageActivation/1
+-All/ThrottleManagerEnabledTest.SafeBrowsingThrottleCreation/0
+-All/ThrottleManagerEnabledTest.SafeBrowsingThrottleCreation/1
+-All/ThrottleManagerEnabledTest.SameSiteFailedNavigation_MaintainActivation/0
+-All/ThrottleManagerEnabledTest.SameSiteFailedNavigation_MaintainActivation/1
+-All/ThrottleManagerEnabledTest.SameSiteNavigationStopsActivation/0
+-All/ThrottleManagerEnabledTest.SameSiteNavigationStopsActivation/1
+-All/ThrottleManagerEnabledTest.SameSiteNavigation_RulesetIsPreserved/0
+-All/ThrottleManagerEnabledTest.SameSiteNavigation_RulesetIsPreserved/1
+-All/ThrottleManagerEnabledTest.ThrottleManagerLifetime_Basic/0
+-All/ThrottleManagerEnabledTest.ThrottleManagerLifetime_Basic/1
+-All/ThrottleManagerEnabledTest.ThrottleManagerLifetime_FencedFrame/0
+-All/ThrottleManagerEnabledTest.ThrottleManagerLifetime_FencedFrame/1
+-All/ThrottleManagerEnabledTest.ThrottleManagerLifetime_SameDocument/0
+-All/ThrottleManagerEnabledTest.ThrottleManagerLifetime_SameDocument/1
+-All/ThrottleManagerEnabledTest.ThrottleManagerLifetime_Subframe/0
+-All/ThrottleManagerEnabledTest.ThrottleManagerLifetime_Subframe/1
+-FingerprintingProtectionPageActivationThrottleTest.FlagEnabledDefaultActivatedParams_IsActivated
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 7736508d..f88ceb8 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1585,6 +1585,12 @@
   },
   'chrome_public_wpt': {
     'modifications': {
+      'android-chrome-13-x64-wpt-android-specific': {
+        'args': [
+          '--test-list',
+          '../../third_party/blink/web_tests/TestLists/android.filter'
+        ]
+      },
       'android-chrome-pie-x86-wpt-fyi-rel': {
         'args': [
           '--use-upstream-wpt',
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 58cb665..4aa14c1 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -267,16 +267,16 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'identifier': 'Lacros version skew testing ash canary',
-    'description': 'Run with ash-chrome version 128.0.6541.0',
+    'description': 'Run with ash-chrome version 128.0.6542.0',
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6541.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v128.0.6542.0/test_ash_chrome',
     ],
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v128.0.6541.0',
-          'revision': 'version:128.0.6541.0',
+          'location': 'lacros_version_skew_tests_v128.0.6542.0',
+          'revision': 'version:128.0.6542.0',
         },
       ],
     },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index be9c90b0..06a3c98 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -3619,6 +3619,29 @@
             ]
         }
     ],
+    "CanvasHibernationExperiments": [
+        {
+            "platforms": [
+                "android",
+                "chromeos",
+                "chromeos_lacros",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "Canvas2DHibernation",
+                        "Canvas2DHibernationReleaseTransferMemory",
+                        "ClearCanvasResourcesInBackground",
+                        "EvictionUnlocksResources"
+                    ]
+                }
+            ]
+        }
+    ],
     "CanvasOutOfProcessRasterization": [
         {
             "platforms": [
@@ -7517,31 +7540,6 @@
             ]
         }
     ],
-    "DevToolsConsoleInsights": [
-        {
-            "platforms": [
-                "chromeos",
-                "chromeos_lacros",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "DevToolsConsoleInsights_Enabled_Dogfood",
-                    "params": {
-                        "aida_api_key": "someRandomAPIKey",
-                        "aida_endpoint": "https://www.example.com/aida",
-                        "aida_model_id": "aida_model_id",
-                        "aida_scope": "https://www.example.com/auth/"
-                    },
-                    "enable_features": [
-                        "DevToolsConsoleInsights"
-                    ]
-                }
-            ]
-        }
-    ],
     "DevToolsConsoleInsightsDogfood": [
         {
             "platforms": [
@@ -11386,6 +11384,21 @@
             ]
         }
     ],
+    "IOSParcelTrackingCarrierNumberDetection": [
+        {
+            "platforms": [
+                "ios"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "EnableNewParcelTrackingNumberDetection"
+                    ]
+                }
+            ]
+        }
+    ],
     "IOSPartitionAllocBackupRefPtr": [
         {
             "platforms": [
@@ -22580,26 +22593,6 @@
             ]
         }
     ],
-    "UseMultiPlaneFormatForHardwareVideo": [
-        {
-            "platforms": [
-                "mac",
-                "windows",
-                "chromeos",
-                "chromeos_lacros",
-                "linux",
-                "fuchsia"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "UseMultiPlaneFormatForHardwareVideo"
-                    ]
-                }
-            ]
-        }
-    ],
     "UseMultiPlaneFormatForSoftwareVideo": [
         {
             "platforms": [
diff --git a/third_party/angle b/third_party/angle
index d521dd0..cdc541d 160000
--- a/third_party/angle
+++ b/third_party/angle
@@ -1 +1 @@
-Subproject commit d521dd08bef4dc5769690e8ec7c996b2cdd40e27
+Subproject commit cdc541de11ed11364cc990293c459faa348ed1d5
diff --git a/third_party/aosp_dalvik/3pp/3pp.pb b/third_party/aosp_dalvik/3pp/3pp.pb
index 234d92ad..fe9365b 100644
--- a/third_party/aosp_dalvik/3pp/3pp.pb
+++ b/third_party/aosp_dalvik/3pp/3pp.pb
@@ -4,7 +4,7 @@
       download_url: "https://android.googlesource.com/platform/dalvik/+archive/090cb5952bab050da27003badb2d27e279e62115.tar.gz"
       version: "13.0.0_r24"
     }
-    patch_version: 'cr1'
+    patch_version: 'cr2'
     subdir: 'lib'
     unpack_archive: true
   }
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index c25473017..e7d2ea6 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -2599,6 +2599,10 @@
   return base::FeatureList::IsEnabled(blink::features::kAllowURNsInIframes);
 }
 
+bool IsCanvas2DHibernationEnabled() {
+  return base::FeatureList::IsEnabled(features::kCanvas2DHibernation);
+}
+
 bool DisplayWarningDeprecateURNIframesUseFencedFrames() {
   return base::FeatureList::IsEnabled(
       blink::features::kDisplayWarningDeprecateURNIframesUseFencedFrames);
diff --git a/third_party/blink/manual_tests/dom/dom-parts-api-4.html b/third_party/blink/manual_tests/dom/dom-parts-api-4.html
new file mode 100644
index 0000000..1b97cc1
--- /dev/null
+++ b/third_party/blink/manual_tests/dom/dom-parts-api-4.html
@@ -0,0 +1,257 @@
+<!DOCTYPE html>
+
+<p>This is the <b>"Minimal"</b> version of this benchmark.</p>
+<fieldset style="display:flex; border:0" id="controls">
+  <div>
+    <button id="run_baseline"></button>
+    <pre id=baseline_log></pre>
+    <input type=number hidden id=last_baseline_total value=0 autocomplete=off>
+  </div>
+  <div>
+    <button id="run_parts"></button>
+    <pre id=parts_log></pre>
+    <input type=number hidden id=last_parts_total value=0 autocomplete=off>
+  </div>
+</fieldset>
+<pre id=overall_log></pre>
+
+<table style="display:none">
+  <tbody>
+  </tbody>
+</table>
+
+<script type="text/javascript">
+const nRows = 1000;
+const nRuns = 500;
+document.querySelector(
+  "button#run_baseline"
+).textContent = `BASELINE: Create ${nRows} rows, ${nRuns} runs`;
+document.querySelector(
+  "button#run_parts"
+).textContent = `PARTS: Create ${nRows} rows, ${nRuns} runs`;
+
+// Feature detection.
+if (typeof document.getPartRoot !== "function") {
+  document.write('<h3>Error: The DOM Parts API is not supported in this browser. Please enable Experimental Web Platform Features.</h3>');
+}
+if (!self.gc) {
+  document.write('<h3>Error: This benchmark requires <pre style="display:inline">--js-flags="--expose-gc"</pre> on the command line.</h3>');
+}
+
+function template(tplStr) {
+  const tplEl = document.createElement("template");
+  tplEl.parseparts = true;
+  tplEl.innerHTML = tplStr;
+  return tplEl;
+}
+const tbodyEl = document.querySelector("tbody");
+const rowTplBaseline = template(
+  `<tr><td class="td-num-1"><div class=decoration><span>content</span></div></td><td class="td-num2"><div class=flex><span>Some text</span><a href="#">link text</a></div></td><td class="td-num-3"><span></span><span><a href="#"></span><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></a></td><td class="td-num-4"><div><span><div>content</div></span></div></td></tr>`
+);
+// The space at the front of this template works around crbug.com/1490375, and can be removed once that's fixed:
+const rowTplParts = template(
+  ` <tr {{}}><td class="td-num-1"><div class=decoration><span {{}}>content</span></div></td><td class="td-num-2"><div class=flex><span>Some text</span><a {{}} href="#">link text</a></div></td><td class="td-num-3"><span></span><span><a {{}} href="#"></span><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></a></td><td class="td-num-4"><div><span><div {{}}>content</div></span></div></td></tr>`
+);
+
+
+
+const partRoot = rowTplParts.content.getPartRoot();
+
+let tbodyPart;
+function resetTable() {
+  const c1 = document.createComment("");
+  const c2 = document.createComment("");
+  tbodyEl.replaceChildren(c1,c2);
+  document.getPartRoot().getParts().forEach(part => part.disconnect());
+  tbodyPart = new ChildNodePart(document.getPartRoot(),c1,c2);
+  self.gc && self.gc();
+}
+
+let selected = 5;
+
+function createRowBaseline(i) {
+  const perfs = [];
+  let now = performance.now();
+  let next = now;
+  // this code is run in the CREATE mode
+
+  // step (1): clone template
+  const tplClone = rowTplBaseline.content.cloneNode(true);
+  next = performance.now();
+  perfs.push(next - now); // cloning
+  now = next;
+  // step (2): find references to the "interesting" elements
+  perfs.push(0); // getNodePartNodes
+  const trEl = tplClone.firstChild;
+  const labelTxtNode = trEl.firstChild.firstChild.firstChild.firstChild;
+  // I don't actually know if frameworks do this level of optimization:
+  const secondTd = trEl.firstChild.nextSibling;
+  const aEl1 = secondTd.firstChild.firstChild.nextSibling;
+  const thirdTd = secondTd.nextSibling;
+  const aEl2 = thirdTd.firstChild.nextSibling.firstChild;
+  const fourthTd = thirdTd.nextSibling;
+  const divEl = fourthTd.firstChild.firstChild.firstChild;
+  next = performance.now();
+  perfs.push(next - now); // accessNodes
+  now = next;
+
+  // step (3): add event listeners
+  aEl1.addEventListener("click", () => {
+    console.log("click first");
+  });
+  aEl2.addEventListener("click", () => {
+    console.log("click second");
+  });
+
+  // this code is run in the UPDATE mode
+  if (i === selected) {
+    trEl.classList.add("table-danger");
+  }
+  labelTxtNode.nodeValue = "foo " + i;
+  divEl.textContent = 'replacement';
+  next = performance.now();
+  perfs.push(next - now); // operations
+  now = next;
+  return [tplClone, perfs];
+}
+
+function createRowParts(i) {
+  const perfs = [];
+  let now = performance.now();
+  let next = now;
+  // this code is run in the CREATE mode
+
+  // step (1): clone template
+  const tplCloneRoot = rowTplParts.content.getPartRoot().clone();
+  const tplClone = tplCloneRoot.rootContainer
+  next = performance.now();
+  perfs.push(next - now); // cloning
+  now = next;
+
+  // step (2): get parts
+  const partNodes = tplCloneRoot.getNodePartNodes();
+  next = performance.now();
+  perfs.push(next - now); // getNodePartNodes
+  now = next;
+
+  const trEl = partNodes[0];
+  const labelTxtNode = partNodes[1].firstChild;
+  const aEl1 = partNodes[2];
+  const aEl2 = partNodes[3];
+  const divEl = partNodes[4];
+  next = performance.now();
+  perfs.push(next - now); // accessNodes
+  now = next;
+
+  // step (3): add event listeners
+  aEl1.addEventListener("click", () => {
+    console.log("click first");
+  });
+  aEl2.addEventListener("click", () => {
+    console.log("click second");
+  });
+  // this code is run in the UPDATE mode
+  if (i === selected) {
+    trEl.classList.add('table-danger');
+  }
+  labelTxtNode.nodeValue = "foo " + i;
+  divEl.textContent = 'replacement';
+  next = performance.now();
+  perfs.push(next - now); // operations
+  return [tplClone, perfs];
+}
+
+function runScenario(createRowFn,tbodyRef) {
+  const numbers = {
+    cloning: 0,
+    getNodePartNodes: 0,
+    accessNodes: 0,
+    operations: 0,
+    replaceChildren: 0,
+  };
+  const rows = [];
+  for (let i = 0; i < nRows; i++) {
+    const [rowEl, perfs] = createRowFn(i);
+    rows.push(rowEl);
+    numbers["cloning"] += perfs[0];
+    numbers["getNodePartNodes"] += perfs[1];
+    numbers["accessNodes"] += perfs[2];
+    numbers["operations"] += perfs[3];
+  }
+  const now = performance.now();
+  tbodyRef.replaceChildren(...rows);
+  numbers["replaceChildren"] = performance.now() - now;
+  return numbers;
+}
+
+function updateRatio() {
+  const baselineVal = Number(document.getElementById("last_baseline_total").value);
+  const partsVal = Number(document.getElementById("last_parts_total").value);
+  if (baselineVal && partsVal) {
+    const logEl = document.getElementById("overall_log");
+    if (baselineVal < partsVal) {
+      logEl.textContent = `Parts are slower than Manual by ${(100*(partsVal - baselineVal)/baselineVal).toFixed(1)}%`;
+    } else {
+      logEl.textContent = `Manual is slower than Parts by ${(100*(baselineVal - partsVal)/partsVal).toFixed(1)}%`;
+    }
+  }
+}
+function connectButton(button,createRowFn,tbodyRefFn,logIdref) {
+  button.addEventListener("click", async () => {
+    const numbers = {
+      cloning: [],
+      getNodePartNodes: [],
+      accessNodes: [],
+      operations: [],
+      replaceChildren: [],
+      total: []
+    };
+    controls.disabled = true;
+    await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
+    setTimeout(() => {controls.disabled = false;},0);
+    for (let i = 0; i < nRuns; i++) {
+        resetTable();
+        const prev = performance.now();
+        const perfs = runScenario(createRowFn,tbodyRefFn());
+        numbers["total"].push(performance.now() - prev);
+        Object.keys(perfs).forEach((key) => {
+          numbers[key].push(perfs[key]);
+        });
+    }
+    Object.keys(numbers).forEach(key => {
+      numbers[key] = average(numbers[key]);
+    });
+    const logEl = document.querySelector(logIdref);
+    logEl.textContent = `
+cloning: ${(1000 * numbers.cloning / nRows).toFixed(3)} us/call
+getNodePartNodes: ${(1000 * numbers.getNodePartNodes / nRows).toFixed(3)} us/call
+accessNodes: ${(1000 * numbers.accessNodes / nRows).toFixed(3)} us/call
+operations: ${(1000 * numbers.operations / nRows).toFixed(3)} us/call
+replaceChildren: ${(numbers.replaceChildren).toFixed(3)} ms/call
+total: ${(numbers.total).toFixed(3)} ms (for ${nRows} rows)
+`;
+    const storageEl = logEl.nextElementSibling;
+    storageEl.value = numbers.total;
+    updateRatio();
+  });
+}
+connectButton(
+  document.querySelector("button#run_baseline"),
+  createRowBaseline,
+  () => tbodyEl,
+  "#baseline_log"
+);
+connectButton(
+  document.querySelector("button#run_parts"),
+  createRowParts,
+  () => tbodyPart,
+  "#parts_log"
+);
+function average(values) {
+  if (values.length === 0) {
+    throw new Error("Input array is empty");
+  }
+  const sum = values.reduce((a, b) => a + b,0);
+  return sum / values.length;
+}
+</script>
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
index af226db..65736cf 100644
--- a/third_party/blink/public/common/features.h
+++ b/third_party/blink/public/common/features.h
@@ -1678,6 +1678,8 @@
 
 BLINK_COMMON_EXPORT bool IsAllowURNsInIframeEnabled();
 
+BLINK_COMMON_EXPORT bool IsCanvas2DHibernationEnabled();
+
 BLINK_COMMON_EXPORT bool DisplayWarningDeprecateURNIframesUseFencedFrames();
 
 BLINK_COMMON_EXPORT bool IsFencedFramesEnabled();
diff --git a/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc b/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc
index e6c8bc3..6ed6a884 100644
--- a/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc
+++ b/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc
@@ -454,8 +454,9 @@
 v8::Local<v8::Value> DeserializeIDBValueData(v8::Isolate* isolate,
                                              const IDBValue* value) {
   DCHECK(isolate->InContext());
-  if (!value || value->IsNull())
+  if (!value) {
     return v8::Null(isolate);
+  }
 
   scoped_refptr<SerializedScriptValue> serialized_value =
       value->CreateSerializedValue();
@@ -486,8 +487,9 @@
                                          const IDBValue* value) {
   v8::Isolate* isolate = script_state->GetIsolate();
   DCHECK(isolate->InContext());
-  if (!value || value->IsNull())
+  if (!value) {
     return v8::Null(isolate);
+  }
 
   v8::Local<v8::Value> v8_value = DeserializeIDBValueData(isolate, value);
   if (value->PrimaryKey()) {
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc
index 26b838e..67ef8fa 100644
--- a/third_party/blink/renderer/core/css/style_engine.cc
+++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -808,12 +808,16 @@
   // Manually update list item ordinals here.
   if (LayoutObject* layout_object = element.GetLayoutObject()) {
     if (auto* ng_list_item = DynamicTo<LayoutListItem>(layout_object)) {
-      ng_list_item->Ordinal().MarkDirty();
-      ng_list_item->OrdinalValueChanged();
+      if (!ng_list_item->Ordinal().ExplicitValue().has_value()) {
+        ng_list_item->Ordinal().MarkDirty();
+        ng_list_item->OrdinalValueChanged();
+      }
     } else if (auto* inline_list_item =
                    DynamicTo<LayoutInlineListItem>(layout_object)) {
-      inline_list_item->Ordinal().MarkDirty();
-      inline_list_item->OrdinalValueChanged();
+      if (!inline_list_item->Ordinal().ExplicitValue().has_value()) {
+        inline_list_item->Ordinal().MarkDirty();
+        inline_list_item->OrdinalValueChanged();
+      }
     }
     if (element.GetComputedStyle() &&
         !element.GetComputedStyle()->ContentBehavesAsNormal()) {
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 4f62b4e3..683659f 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -6960,7 +6960,8 @@
             template_element->hasAttribute(html_names::kParsepartsAttr);
       }
       ReplaceChildrenWithFragment(container, fragment, exception_state);
-      if (swap_dom_parts) {
+      if (swap_dom_parts &&
+          !RuntimeEnabledFeatures::DOMPartsAPIMinimalEnabled()) {
         // Move the parts list over to the template's content document's
         // DocumentPartRoot.
         To<DocumentFragment>(*container)
diff --git a/third_party/blink/renderer/core/dom/part.cc b/third_party/blink/renderer/core/dom/part.cc
index c3395d8..bdee27c 100644
--- a/third_party/blink/renderer/core/dom/part.cc
+++ b/third_party/blink/renderer/core/dom/part.cc
@@ -3,12 +3,14 @@
 // found in the LICENSE file.
 
 #include "third_party/blink/renderer/core/dom/part.h"
+
 #include "third_party/blink/renderer/core/dom/child_node_part.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/document_fragment.h"
 #include "third_party/blink/renderer/core/dom/document_part_root.h"
 #include "third_party/blink/renderer/core/dom/part_root.h"
 #include "third_party/blink/renderer/core/dom/tree_scope.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
 namespace blink {
@@ -20,9 +22,11 @@
 }
 
 void Part::disconnect() {
-  CHECK(connected_) << "disconnect should be overridden";
+  DCHECK(connected_) << "disconnect should be overridden";
   if (root_) {
-    root_->MarkPartsDirty();
+    if (!RuntimeEnabledFeatures::DOMPartsAPIMinimalEnabled()) {
+      root_->MarkPartsDirty();
+    }
     root_ = nullptr;
   }
   connected_ = false;
diff --git a/third_party/blink/renderer/core/dom/part_root.cc b/third_party/blink/renderer/core/dom/part_root.cc
index b318b90..3a43a8ae 100644
--- a/third_party/blink/renderer/core/dom/part_root.cc
+++ b/third_party/blink/renderer/core/dom/part_root.cc
@@ -101,6 +101,7 @@
 }
 
 void PartRoot::SwapPartsList(PartRoot& other) {
+  DCHECK(!RuntimeEnabledFeatures::DOMPartsAPIMinimalEnabled());
   cached_ordered_parts_.swap(other.cached_ordered_parts_);
   std::swap(cached_parts_list_dirty_, other.cached_parts_list_dirty_);
 }
@@ -119,8 +120,8 @@
 // any Parts we find. If we find a ChildNodePart (or other PartRoot), we ignore
 // Parts until we exit the Partroot.
 void PartRoot::RebuildPartsList() {
-  DCHECK(cached_parts_list_dirty_);
   DCHECK(!RuntimeEnabledFeatures::DOMPartsAPIMinimalEnabled());
+  DCHECK(cached_parts_list_dirty_);
   cached_ordered_parts_.clear();
   // Then traverse the tree under the root container and add parts in the order
   // they're found in the tree, and for the same Node, in the order they were
@@ -182,21 +183,22 @@
   }
 }
 
+namespace {
+
 // This is used only in the case of DOMPartsAPIMinimal enabled, and it just
-// fresh-builds the parts list every time.
-void PartRoot::BuildPartsList() {
+// fresh-builds the parts list, and/or just the node lists, every time with no
+// caching.
+void BuildPartsList(PartRoot& part_root,
+                    HeapVector<Member<Part>>* part_list,
+                    HeapVector<Member<Node>>* node_part_nodes,
+                    HeapVector<Member<Node>>* child_node_part_nodes) {
   DCHECK(RuntimeEnabledFeatures::DOMPartsAPIMinimalEnabled());
-  // Use |cached_ordered_parts_| for the data.
-  cached_ordered_parts_.clear();
-  // Then traverse the tree under the root container and add parts in the order
-  // they're found in the tree, and for the same Node, in the order they were
-  // constructed.
-  Node* node = FirstIncludedChildNode();
-  Node* end_node = LastIncludedChildNode();
+  Node* node = part_root.FirstIncludedChildNode();
+  Node* end_node = part_root.LastIncludedChildNode();
   if (!node || !end_node) {
-    return;  // Empty list
+    return;  // Empty lists
   }
-  if (!IsDocumentPartRoot()) {
+  if (!part_root.IsDocumentPartRoot()) {
     // This is a ChildNodePart, so we need to skip the first start node, or
     // we'll just re-detect this ChildNodePart. If `node` doesn't have a
     // nextSibling (i.e. this ChildNodePart is mal-formed), then `node` will be
@@ -207,7 +209,6 @@
   }
   while (node != end_node) {
     if (node->HasNodePart()) {
-      Vector<String> metadata;
       if (Comment* start_comment = DynamicTo<Comment>(node);
           start_comment &&
           start_comment->data() == kChildNodePartStartCommentData) {
@@ -226,9 +227,15 @@
           if (LIKELY(end_comment.data() == kChildNodePartEndCommentData)) {
             if (LIKELY(!nested_child_node_part_count)) {
               // Found the end of the child node part.
-              cached_ordered_parts_.push_back(
-                  MakeGarbageCollected<ChildNodePart>(*this, *start_comment,
-                                                      end_comment, metadata));
+              if (part_list) {
+                Vector<String> metadata;
+                part_list->push_back(MakeGarbageCollected<ChildNodePart>(
+                    part_root, *start_comment, end_comment, metadata));
+              }
+              if (child_node_part_nodes) {
+                child_node_part_nodes->push_back(start_comment);
+                child_node_part_nodes->push_back(&end_comment);
+              }
               break;
             }
             --nested_child_node_part_count;
@@ -237,21 +244,45 @@
           }
         }
       } else {
-        // Plain NodePart
-        cached_ordered_parts_.push_back(
-            MakeGarbageCollected<NodePart>(*this, *node, metadata));
+        // This is just a NodePart.
+        if (part_list) {
+          Vector<String> metadata;
+          part_list->push_back(
+              MakeGarbageCollected<NodePart>(part_root, *node, metadata));
+        }
+        if (node_part_nodes) {
+          node_part_nodes->push_back(node);
+        }
       }
     }
     node = NodeTraversal::Next(*node);
   }
 }
 
+}  // namespace
+
+HeapVector<Member<Node>> PartRoot::getNodePartNodes() {
+  DCHECK(RuntimeEnabledFeatures::DOMPartsAPIMinimalEnabled());
+  HeapVector<Member<Node>> nodes;
+  BuildPartsList(*this, nullptr, &nodes, nullptr);
+  return nodes;
+}
+
+HeapVector<Member<Node>> PartRoot::getChildNodePartNodes() {
+  DCHECK(RuntimeEnabledFeatures::DOMPartsAPIMinimalEnabled());
+  HeapVector<Member<Node>> nodes;
+  BuildPartsList(*this, nullptr, nullptr, &nodes);
+  return nodes;
+}
+
 const HeapVector<Member<Part>>& PartRoot::getParts() {
   if (RuntimeEnabledFeatures::DOMPartsAPIMinimalEnabled()) {
-    // For minimal mode, always traverse the tree and return parts. No caching
-    // at all. For now, this *only* returns NodeParts, and does not take
-    // ChildNodeParts into account.
-    BuildPartsList();
+    DCHECK(cached_ordered_parts_.empty());
+    DCHECK(!cached_parts_list_dirty_);
+    HeapVector<Member<Part>>* parts =
+        MakeGarbageCollected<HeapVector<Member<Part>>>();
+    BuildPartsList(*this, parts, nullptr, nullptr);
+    return *parts;
   } else if (cached_parts_list_dirty_) {
     RebuildPartsList();
     cached_parts_list_dirty_ = false;
@@ -277,14 +308,6 @@
   return cached_ordered_parts_;
 }
 
-Node* PartRoot::getPartNode(unsigned index) {
-  auto& parts = getParts();
-  if (index >= parts.size()) {
-    return nullptr;
-  }
-  return parts[index]->NodeToSortBy();
-}
-
 // static
 PartRoot* PartRoot::GetPartRootFromUnion(PartRootUnion* root_union) {
   if (root_union->IsChildNodePart()) {
diff --git a/third_party/blink/renderer/core/dom/part_root.h b/third_party/blink/renderer/core/dom/part_root.h
index 895b5b56..cb9dff6 100644
--- a/third_party/blink/renderer/core/dom/part_root.h
+++ b/third_party/blink/renderer/core/dom/part_root.h
@@ -41,7 +41,10 @@
   static void CloneParts(const Node& source_node,
                          Node& destination_node,
                          NodeCloningData& data);
-  void MarkPartsDirty() { cached_parts_list_dirty_ = true; }
+  void MarkPartsDirty() {
+    DCHECK(!RuntimeEnabledFeatures::DOMPartsAPIMinimalEnabled());
+    cached_parts_list_dirty_ = true;
+  }
   void SwapPartsList(PartRoot& other);
 
   virtual Document& GetDocument() const = 0;
@@ -58,7 +61,8 @@
 
   // PartRoot API
   const HeapVector<Member<Part>>& getParts();
-  Node* getPartNode(unsigned index);
+  HeapVector<Member<Node>> getNodePartNodes();
+  HeapVector<Member<Node>> getChildNodePartNodes();
   virtual ContainerNode* rootContainer() const = 0;
 
  protected:
@@ -67,7 +71,6 @@
 
  private:
   void RebuildPartsList();
-  void BuildPartsList();
   HeapVector<Member<Part>> cached_ordered_parts_;
   bool cached_parts_list_dirty_{false};
 };
diff --git a/third_party/blink/renderer/core/dom/part_root.idl b/third_party/blink/renderer/core/dom/part_root.idl
index b647ecdc..9078415 100644
--- a/third_party/blink/renderer/core/dom/part_root.idl
+++ b/third_party/blink/renderer/core/dom/part_root.idl
@@ -11,8 +11,13 @@
   // Retrieve the parts list for this PartRoot, always in tree order breaking
   // ties for a Node using the order Parts were constructed.
   sequence<Part> getParts();
-  // Retrieve getParts()[index].NodeToSortBy. This is experimental.
-  [PerWorldBindings] Node getPartNode(unsigned long index);
+  // Retrieve the Nodes corresponding to the NodeParts returned by getParts(),
+  // without building the Part objects.
+  [RuntimeEnabled=DOMPartsAPIMinimal] sequence<Node> getNodePartNodes();
+  // Retrieve the pairs of previous/next Nodes corresponding to the
+  // ChildNodeParts returned by getParts(), without building the Part objects.
+  // Nodes are paired, so for 3 ChildNodeParts, 6 Nodes will be returned.
+  [RuntimeEnabled=DOMPartsAPIMinimal] sequence<Node> getChildNodePartNodes();
   // This clones the PartRoot, and also clones the Node tree itself, starting
   // at the RootContainer. In the case of a DocumentPartRoot, the entire
   // document tree is cloned. In the case of a ChildPartRoot, only the children
diff --git a/third_party/blink/renderer/core/fileapi/file_reader_loader.cc b/third_party/blink/renderer/core/fileapi/file_reader_loader.cc
index b6f8b3a5..51883bd 100644
--- a/third_party/blink/renderer/core/fileapi/file_reader_loader.cc
+++ b/third_party/blink/renderer/core/fileapi/file_reader_loader.cc
@@ -36,6 +36,7 @@
 
 #include "base/auto_reset.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/task/single_thread_task_runner.h"
 #include "mojo/public/cpp/system/wait.h"
@@ -92,7 +93,7 @@
   mojo::ScopedDataPipeProducerHandle producer_handle;
   MojoResult rv = CreateDataPipe(&options, producer_handle, consumer_handle_);
   if (rv != MOJO_RESULT_OK) {
-    Failed(FileErrorCode::kNotReadableErr);
+    Failed(FileErrorCode::kNotReadableErr, FailureType::kMojoPipeCreation);
     return;
   }
 
@@ -106,14 +107,16 @@
     if (received_on_complete_)
       return;
     if (!received_all_data_) {
-      Failed(FileErrorCode::kNotReadableErr);
+      Failed(FileErrorCode::kNotReadableErr,
+             FailureType::kSyncDataNotAllLoaded);
       return;
     }
 
     // Wait for OnComplete
     receiver_.WaitForIncomingCall();
     if (!received_on_complete_) {
-      Failed(FileErrorCode::kNotReadableErr);
+      Failed(FileErrorCode::kNotReadableErr,
+             FailureType::kSyncOnCompleteNotReceived);
     }
   }
 }
@@ -129,11 +132,13 @@
   receiver_.reset();
 }
 
-void FileReaderLoader::Failed(FileErrorCode error_code) {
+void FileReaderLoader::Failed(FileErrorCode error_code, FailureType type) {
   // If an error was already reported, don't report this error again.
   if (error_code_ != FileErrorCode::kOK)
     return;
   error_code_ = error_code;
+  base::UmaHistogramEnumeration("Storage.Blob.FileReaderLoader.FailureType2",
+                                type);
   Cleanup();
   client_->DidFail(error_code_);
 }
@@ -150,7 +155,7 @@
 
   if (auto err = client_->DidStartLoading(expected_content_size);
       err != FileErrorCode::kOK) {
-    Failed(err);
+    Failed(err, FailureType::kClientFailure);
     return;
   }
 
@@ -170,14 +175,18 @@
 }
 
 void FileReaderLoader::OnComplete(int32_t status, uint64_t data_length) {
+  base::UmaHistogramSparse("Storage.Blob.FileReaderLoader.ReadError2",
+                           std::max(0, -net_error_));
+
   if (status != net::OK) {
     net_error_ = status;
     Failed(status == net::ERR_FILE_NOT_FOUND ? FileErrorCode::kNotFoundErr
-                                             : FileErrorCode::kNotReadableErr);
+                                             : FileErrorCode::kNotReadableErr,
+           FailureType::kBackendReadError);
     return;
   }
   if (data_length != total_bytes_) {
-    Failed(FileErrorCode::kNotReadableErr);
+    Failed(FileErrorCode::kNotReadableErr, FailureType::kReadSizesIncorrect);
     return;
   }
 
@@ -189,7 +198,8 @@
 void FileReaderLoader::OnDataPipeReadable(MojoResult result) {
   if (result != MOJO_RESULT_OK) {
     if (!received_all_data_) {
-      Failed(FileErrorCode::kNotReadableErr);
+      Failed(FileErrorCode::kNotReadableErr,
+             FailureType::kDataPipeNotReadableWithBytesLeft);
     }
     return;
   }
@@ -211,12 +221,14 @@
     if (pipe_result == MOJO_RESULT_FAILED_PRECONDITION) {
       // Pipe closed.
       if (!received_all_data_) {
-        Failed(FileErrorCode::kNotReadableErr);
+        Failed(FileErrorCode::kNotReadableErr,
+               FailureType::kMojoPipeClosedEarly);
       }
       return;
     }
     if (pipe_result != MOJO_RESULT_OK) {
-      Failed(FileErrorCode::kNotReadableErr);
+      Failed(FileErrorCode::kNotReadableErr,
+             FailureType::kMojoPipeUnexpectedReadError);
       return;
     }
 
@@ -229,7 +241,7 @@
     if (auto err = client_->DidReceiveData(
             data, base::checked_cast<unsigned>(num_bytes));
         err != FileErrorCode::kOK) {
-      Failed(err);
+      Failed(err, FailureType::kClientFailure);
       return;
     }
 
diff --git a/third_party/blink/renderer/core/fileapi/file_reader_loader.h b/third_party/blink/renderer/core/fileapi/file_reader_loader.h
index 4109d741..33122e2 100644
--- a/third_party/blink/renderer/core/fileapi/file_reader_loader.h
+++ b/third_party/blink/renderer/core/fileapi/file_reader_loader.h
@@ -96,8 +96,27 @@
 
  private:
   void StartInternal(scoped_refptr<BlobDataHandle>, bool is_sync);
+
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused.
+  enum class FailureType {
+    kMojoPipeCreation = 0,
+    kSyncDataNotAllLoaded = 1,
+    kSyncOnCompleteNotReceived = 2,
+    kBackendReadError = 3,
+    kReadSizesIncorrect = 4,
+    kDataPipeNotReadableWithBytesLeft = 5,
+    kMojoPipeClosedEarly = 6,
+    // Any MojoResult error we aren't expecting during data pipe reading falls
+    // into this bucket. If there are a large number of errors reported here,
+    // then there can be a new enumeration reported for mojo pipe errors.
+    kMojoPipeUnexpectedReadError = 7,
+    kClientFailure = 8,
+    kMaxValue = kClientFailure,
+  };
+
   void Cleanup();
-  void Failed(FileErrorCode);
+  void Failed(FileErrorCode, FailureType type);
 
   bool IsSyncLoad() { return is_sync_; }
 
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 48225f3d..624babb 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -2643,6 +2643,11 @@
 }
 
 SmoothScrollSequencer* LocalFrame::CreateNewSmoothScrollSequence() {
+  if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled()) {
+    // If MultiSmoothScrollIntoView is enabled, we run smooth scrolls in
+    // parallel, not in sequence.
+    return nullptr;
+  }
   if (!IsLocalRoot()) {
     return LocalFrameRoot().CreateNewSmoothScrollSequence();
   }
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport.cc b/third_party/blink/renderer/core/frame/root_frame_viewport.cc
index 423a316..7a6f9d9 100644
--- a/third_party/blink/renderer/core/frame/root_frame_viewport.cc
+++ b/third_party/blink/renderer/core/frame/root_frame_viewport.cc
@@ -385,13 +385,18 @@
 
   if (new_scroll_offset != GetScrollOffset()) {
     if (params->is_for_scroll_sequence) {
-      CHECK(GetSmoothScrollSequencer());
-      DCHECK(params->type == mojom::blink::ScrollType::kProgrammatic ||
-             params->type == mojom::blink::ScrollType::kUser);
       mojom::blink::ScrollBehavior behavior = DetermineScrollBehavior(
           params->behavior, GetLayoutBox()->StyleRef().GetScrollBehavior());
-      GetSmoothScrollSequencer()->QueueAnimation(this, new_scroll_offset,
-                                                 behavior);
+      if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled()) {
+        ScrollableArea::SetScrollOffset(new_scroll_offset, params->type,
+                                        behavior);
+      } else {
+        CHECK(GetSmoothScrollSequencer());
+        DCHECK(params->type == mojom::blink::ScrollType::kProgrammatic ||
+               params->type == mojom::blink::ScrollType::kUser);
+        GetSmoothScrollSequencer()->QueueAnimation(this, new_scroll_offset,
+                                                   behavior);
+      }
     } else {
       ScrollableArea::SetScrollOffset(new_scroll_offset, params->type);
     }
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.cc b/third_party/blink/renderer/core/frame/visual_viewport.cc
index b90e794..96eef14 100644
--- a/third_party/blink/renderer/core/frame/visual_viewport.cc
+++ b/third_party/blink/renderer/core/frame/visual_viewport.cc
@@ -795,11 +795,15 @@
 
   if (new_scroll_offset != GetScrollOffset()) {
     if (params->is_for_scroll_sequence) {
-      DCHECK(params->type == mojom::blink::ScrollType::kProgrammatic ||
-             params->type == mojom::blink::ScrollType::kUser);
-      CHECK(GetSmoothScrollSequencer());
-      GetSmoothScrollSequencer()->QueueAnimation(this, new_scroll_offset,
-                                                 params->behavior);
+      if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled()) {
+        SetScrollOffset(new_scroll_offset, params->type, params->behavior);
+      } else {
+        DCHECK(params->type == mojom::blink::ScrollType::kProgrammatic ||
+               params->type == mojom::blink::ScrollType::kUser);
+        CHECK(GetSmoothScrollSequencer());
+        GetSmoothScrollSequencer()->QueueAnimation(this, new_scroll_offset,
+                                                   params->behavior);
+      }
     } else {
       SetScrollOffset(new_scroll_offset, params->type, params->behavior,
                       ScrollCallback());
diff --git a/third_party/blink/renderer/core/frame/visual_viewport_test.cc b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
index 76ae3896..56f5b647 100644
--- a/third_party/blink/renderer/core/frame/visual_viewport_test.cc
+++ b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
@@ -2389,9 +2389,16 @@
             visual_viewport.GetScrollNode()->ContentsRect());
 }
 
-class VisualViewportScrollIntoViewTest : public VisualViewportSimTest {
+class VisualViewportScrollIntoViewTest
+    : public VisualViewportSimTest,
+      public ::testing::WithParamInterface<
+          std::vector<base::test::FeatureRef>> {
  public:
-  VisualViewportScrollIntoViewTest() {}
+  VisualViewportScrollIntoViewTest() {
+    feature_list_.InitWithFeatures(
+        GetParam(),
+        /*disabled_features=*/std::vector<base::test::FeatureRef>());
+  }
 
   void SetUp() override {
     VisualViewportSimTest::SetUp();
@@ -2422,41 +2429,41 @@
     WebView().ResizeVisualViewport(gfx::Size(400, 600 - 100));
   }
 
-  // Scrolls an element by the given name into view in the |visual_viewport|
-  // using params that optionally apply to a scroll sequence.
-  void ScrollIntoView(const WebString& element_name,
-                      bool is_for_scroll_sequence) {
-    WebDocument web_doc = WebView().MainFrameImpl()->GetDocument();
-    Element* bottom_element = web_doc.GetElementById(element_name);
-    auto scroll_params = ScrollAlignment::CreateScrollIntoViewParams(
-        ScrollAlignment::ToEdgeIfNeeded(), ScrollAlignment::ToEdgeIfNeeded(),
-        mojom::blink::ScrollType::kProgrammatic,
-        /*make_visible_in_visual_viewport=*/true,
-        mojom::blink::ScrollBehavior::kInstant, is_for_scroll_sequence);
-    GetDocument().GetFrame()->CreateNewSmoothScrollSequence();
-    WebView().GetPage()->GetVisualViewport().ScrollIntoView(
-        bottom_element->BoundingBox(), PhysicalBoxStrut(), scroll_params);
-  }
+ private:
+  base::test::ScopedFeatureList feature_list_;
 };
 
-TEST_F(VisualViewportScrollIntoViewTest,
-       ScrollingToFixedWithScrollSequenceAnimationShort) {
+INSTANTIATE_TEST_SUITE_P(
+    ,
+    VisualViewportScrollIntoViewTest,
+    testing::Values(std::vector<base::test::FeatureRef>{},
+                    std::vector<base::test::FeatureRef>{
+                        features::kMultiSmoothScrollIntoView}));
+
+TEST_P(VisualViewportScrollIntoViewTest, ScrollingToFixed) {
   VisualViewport& visual_viewport = WebView().GetPage()->GetVisualViewport();
   EXPECT_EQ(0.f, visual_viewport.GetScrollOffset().y());
-  ScrollIntoView("bottom", true);
-  visual_viewport.GetSmoothScrollSequencer()->RunQueuedAnimations();
+  WebDocument web_doc = WebView().MainFrameImpl()->GetDocument();
+  Element* bottom_element = web_doc.GetElementById("bottom");
+  bool is_for_scroll_sequence =
+      !RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled();
+  auto scroll_params = ScrollAlignment::CreateScrollIntoViewParams(
+      ScrollAlignment::ToEdgeIfNeeded(), ScrollAlignment::ToEdgeIfNeeded(),
+      mojom::blink::ScrollType::kProgrammatic,
+      /*make_visible_in_visual_viewport=*/true,
+      mojom::blink::ScrollBehavior::kInstant, is_for_scroll_sequence);
+  if (is_for_scroll_sequence) {
+    GetDocument().GetFrame()->CreateNewSmoothScrollSequence();
+  }
+  WebView().GetPage()->GetVisualViewport().ScrollIntoView(
+      bottom_element->BoundingBox(), PhysicalBoxStrut(), scroll_params);
+  if (is_for_scroll_sequence) {
+    visual_viewport.GetSmoothScrollSequencer()->RunQueuedAnimations();
+  }
   EXPECT_EQ(100.f, visual_viewport.GetScrollOffset().y());
 }
 
-TEST_F(VisualViewportScrollIntoViewTest,
-       ScrollingToFixedWithoutScrollSequenceAnimationShort) {
-  VisualViewport& visual_viewport = WebView().GetPage()->GetVisualViewport();
-  EXPECT_EQ(0.f, visual_viewport.GetScrollOffset().y());
-  ScrollIntoView("bottom", false);
-  EXPECT_EQ(100.f, visual_viewport.GetScrollOffset().y());
-}
-
-TEST_F(VisualViewportScrollIntoViewTest, ScrollingToFixedFromJavascript) {
+TEST_P(VisualViewportScrollIntoViewTest, ScrollingToFixedFromJavascript) {
   VisualViewport& visual_viewport = WebView().GetPage()->GetVisualViewport();
   EXPECT_EQ(0.f, visual_viewport.GetScrollOffset().y());
   GetDocument().getElementById(AtomicString("bottom"))->scrollIntoView();
diff --git a/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc b/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc
index 8675104..3d67193 100644
--- a/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc
+++ b/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc
@@ -52,23 +52,17 @@
 }
 
 wtf_size_t GetMaxNumberOfObservations() {
-  static const wtf_size_t max_observations = []() {
-    const base::FeatureParam<int> max_number_of_observations{
-        &features::kNavigationPredictor, "max_intersection_observations", -1};
-    int value = max_number_of_observations.Get();
-    return value >= 0 ? value : std::numeric_limits<wtf_size_t>::max();
-  }();
-  return max_observations;
+  const base::FeatureParam<int> max_number_of_observations{
+      &features::kNavigationPredictor, "max_intersection_observations", -1};
+  int value = max_number_of_observations.Get();
+  return value >= 0 ? value : std::numeric_limits<wtf_size_t>::max();
 }
 
 base::TimeDelta GetIntersectionObserverDelay() {
-  static const base::TimeDelta intersection_observer_delay = []() {
-    const base::FeatureParam<base::TimeDelta> param{
-        &features::kNavigationPredictor, "intersection_observer_delay",
-        base::Milliseconds(100)};
-    return param.Get();
-  }();
-  return intersection_observer_delay;
+  const base::FeatureParam<base::TimeDelta> param{
+      &features::kNavigationPredictor, "intersection_observer_delay",
+      base::Milliseconds(100)};
+  return param.Get();
 }
 
 bool ShouldReportViewportPositions() {
@@ -241,6 +235,8 @@
           blink::features::kNavigationPredictor,
           "random_anchor_sampling_period",
           100)),
+      max_number_of_observations_(GetMaxNumberOfObservations()),
+      intersection_observer_delay_(GetIntersectionObserverDelay()),
       clock_(base::DefaultTickClock::GetInstance()),
       position_update_timer_(
           document.GetExecutionContext()->GetTaskRunner(
@@ -257,7 +253,7 @@
                          WrapWeakPersistent(this)),
       LocalFrameUkmAggregator::kAnchorElementMetricsIntersectionObserver,
       {.thresholds = {kIntersectionRatioThreshold},
-       .delay = GetIntersectionObserverDelay()});
+       .delay = intersection_observer_delay_});
 }
 
 void AnchorElementMetricsSender::SetNowAsNavigationStartForTesting() {
@@ -424,7 +420,7 @@
   // At this point, we're unsure of whether we have the latest
   // IntersectionObserver data or not (|intersection_observer_| is configured
   // with a delay), and the post-scroll intersection computations may or may not
-  // have happened yet. We set a timer for |GetIntersectionObserverDelay()| and
+  // have happened yet. We set a timer for |intersection_observer_delay_| and
   // wait for either:
   // 1) UpdateVisibleAnchors to be called before the timer (we stop the timer)
   // 2) The timer finishes (no intersection changes and UpdateVisibleAnchors
@@ -435,7 +431,7 @@
   // |position_update_timer_| might already be active in a scenario where a
   // second scroll completes before the timer finishes.
   if (!position_update_timer_.IsActive()) {
-    position_update_timer_.StartOneShot(GetIntersectionObserverDelay(),
+    position_update_timer_.StartOneShot(intersection_observer_delay_,
                                         FROM_HERE);
   }
 }
@@ -552,7 +548,6 @@
     return;
   }
 
-  const wtf_size_t max_num_observations = GetMaxNumberOfObservations();
   for (const auto& member_element : anchor_elements_to_report_) {
     HTMLAnchorElement& anchor_element = *member_element;
 
@@ -580,7 +575,7 @@
         // by avoiding intersection computations altogether in such pages. This
         // could be revisited in the future.
         if (intersection_observer_->Observations().size() >
-            max_num_observations) {
+            max_number_of_observations_) {
           intersection_observer_limit_exceeded_ = true;
           intersection_observer_->disconnect();
         }
diff --git a/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h b/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h
index 85981ccb..1010f40 100644
--- a/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h
+++ b/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h
@@ -187,7 +187,10 @@
   // is no longer done.
   bool should_skip_update_delays_for_testing_ = false;
 
+  // Cached field trial param values.
   const int random_anchor_sampling_period_;
+  const wtf_size_t max_number_of_observations_;
+  const base::TimeDelta intersection_observer_delay_;
 
   Member<IntersectionObserver> intersection_observer_;
   HeapHashSet<WeakMember<const HTMLAnchorElement>> anchors_in_viewport_;
diff --git a/third_party/blink/renderer/core/loader/resource/svg_document_resource.cc b/third_party/blink/renderer/core/loader/resource/svg_document_resource.cc
index fd158fd..ffb5f5e0 100644
--- a/third_party/blink/renderer/core/loader/resource/svg_document_resource.cc
+++ b/third_party/blink/renderer/core/loader/resource/svg_document_resource.cc
@@ -82,7 +82,7 @@
   UpdateResult update_status = UpdateResult::kError;
   if (MimeTypeAllowed(response) && HasData()) {
     update_status =
-        content_->UpdateDocument(*Data(), response.CurrentRequestUrl());
+        content_->UpdateDocument(Data(), response.CurrentRequestUrl());
   }
   switch (update_status) {
     case UpdateResult::kCompleted:
diff --git a/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc b/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc
index 3e292c64..95a41d4 100644
--- a/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/scroll_into_view_test.cc
@@ -2,8 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/test/scoped_feature_list.h"
 #include "cc/base/features.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features_generated.h"
 #include "third_party/blink/public/mojom/frame/find_in_page.mojom-blink.h"
 #include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom-blink.h"
 #include "third_party/blink/public/web/web_script_source.h"
@@ -35,9 +37,28 @@
 
 namespace {
 
-class ScrollIntoViewTest : public SimTest {};
+class ScrollIntoViewTest : public SimTest,
+                           public ::testing::WithParamInterface<
+                               std::vector<base::test::FeatureRef>> {
+ public:
+  ScrollIntoViewTest() {
+    feature_list_.InitWithFeatures(
+        GetParam(),
+        /*disabled_features=*/std::vector<base::test::FeatureRef>());
+  }
 
-TEST_F(ScrollIntoViewTest, InstantScroll) {
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    ,
+    ScrollIntoViewTest,
+    testing::Values(std::vector<base::test::FeatureRef>{},
+                    std::vector<base::test::FeatureRef>{
+                        features::kMultiSmoothScrollIntoView}));
+
+TEST_P(ScrollIntoViewTest, InstantScroll) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
@@ -58,7 +79,7 @@
   ASSERT_EQ(Window().scrollY(), content->OffsetTop());
 }
 
-TEST_F(ScrollIntoViewTest, ScrollPaddingOnDocumentElWhenBodyDefinesViewport) {
+TEST_P(ScrollIntoViewTest, ScrollPaddingOnDocumentElWhenBodyDefinesViewport) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(300, 300));
@@ -90,7 +111,7 @@
   ASSERT_EQ(Window().scrollY(), target->OffsetTop() - 10);
 }
 
-TEST_F(ScrollIntoViewTest,
+TEST_P(ScrollIntoViewTest,
        ScrollPaddingOnDocumentElWhenDocumentElDefinesViewport) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
@@ -121,7 +142,7 @@
   ASSERT_EQ(Window().scrollY(), target->OffsetTop() - 10);
 }
 
-TEST_F(ScrollIntoViewTest, ScrollPaddingOnBodyWhenDocumentElDefinesViewport) {
+TEST_P(ScrollIntoViewTest, ScrollPaddingOnBodyWhenDocumentElDefinesViewport) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(300, 300));
@@ -167,7 +188,7 @@
 // case, invoking scrollIntoView on a child element within the scrollport
 // should not trigger scrolling.
 // See https://crbug.com/40055750
-TEST_F(ScrollIntoViewTest, EmptyScrollportSinceScrollPadding) {
+TEST_P(ScrollIntoViewTest, EmptyScrollportSinceScrollPadding) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(300, 300));
@@ -211,7 +232,7 @@
   ASSERT_EQ(scroller->scrollLeft(), 0);
 }
 
-TEST_F(ScrollIntoViewTest, SmoothScroll) {
+TEST_P(ScrollIntoViewTest, SmoothScroll) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
@@ -243,7 +264,7 @@
   ASSERT_EQ(Window().scrollY(), content->OffsetTop());
 }
 
-TEST_F(ScrollIntoViewTest, NestedContainer) {
+TEST_P(ScrollIntoViewTest, NestedContainer) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
@@ -275,12 +296,32 @@
   Compositor().BeginFrame(0.2);
   ASSERT_NEAR(Window().scrollY(),
               (::features::IsImpulseScrollAnimationEnabled() ? 800 : 299), 1);
-  ASSERT_EQ(container->scrollTop(), 0);
+  if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled()) {
+    // If MultiSmoothScrollIntoView is enabled, the frames will also scroll the
+    // inner container.
+    ASSERT_NEAR(container->scrollTop(),
+                (::features::IsImpulseScrollAnimationEnabled() ? 800 : 299), 1);
+  } else {
+    ASSERT_EQ(container->scrollTop(), 0);
+  }
 
   // Finish scrolling the outer container
   Compositor().BeginFrame(1);
   ASSERT_EQ(Window().scrollY(), container->OffsetTop());
-  ASSERT_EQ(container->scrollTop(), 0);
+  if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled()) {
+    // If MultiSmoothScrollIntoView is enabled, the frames will also have
+    // scrolled inner container.
+    ASSERT_EQ(container->scrollTop(),
+              content->OffsetTop() - container->OffsetTop());
+  } else {
+    ASSERT_EQ(container->scrollTop(), 0);
+  }
+
+  if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled()) {
+    // The rest of the test depends on scrolling the inner and outer scrollers
+    // sequentially, which we do not do if MultiSmoothScrollIntoView is enabled.
+    return;
+  }
 
   // Scrolling the inner container
   Compositor().BeginFrame();  // Set start_time = now.
@@ -294,7 +335,7 @@
             content->OffsetTop() - container->OffsetTop());
 }
 
-TEST_F(ScrollIntoViewTest, NewScrollIntoViewAbortsCurrentAnimation) {
+TEST_P(ScrollIntoViewTest, NewScrollIntoViewAbortsCurrentAnimation) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
@@ -334,7 +375,14 @@
   Compositor().BeginFrame(0.2);
   ASSERT_NEAR(Window().scrollY(),
               (::features::IsImpulseScrollAnimationEnabled() ? 800 : 299), 1);
-  ASSERT_EQ(container1->scrollTop(), 0);
+  if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled()) {
+    // If MultiSmoothScrollIntoView is enabled, the frames will also scroll
+    // container1.
+    ASSERT_NEAR(container1->scrollTop(),
+                (::features::IsImpulseScrollAnimationEnabled() ? 800 : 299), 1);
+  } else {
+    ASSERT_EQ(container1->scrollTop(), 0);
+  }
 
   content2->scrollIntoView(arg);
   Compositor().BeginFrame();  // update run_state_.
@@ -342,11 +390,31 @@
   Compositor().BeginFrame(0.2);
   ASSERT_NEAR(Window().scrollY(),
               (::features::IsImpulseScrollAnimationEnabled() ? 171 : 61), 1);
-  ASSERT_EQ(container1->scrollTop(), 0);  // container1 should not scroll.
+  if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled()) {
+    // If MultiSmoothScrollIntoView is enabled, the new scrollIntoView does not
+    // cancel the first scrollIntoView so the scroll on container1 continues.
+    ASSERT_GT(container1->scrollTop(),
+              (::features::IsImpulseScrollAnimationEnabled() ? 800 : 299));
+  } else {
+    ASSERT_EQ(container1->scrollTop(), 0);  // container1 should not scroll.
+  }
 
   Compositor().BeginFrame(1);
   ASSERT_EQ(Window().scrollY(), container2->OffsetTop());
-  ASSERT_EQ(container2->scrollTop(), 0);
+  if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled()) {
+    // If MultiSmoothScrollIntoView is enabled, the frames will also have
+    // scrolled inner container.
+    ASSERT_EQ(container2->scrollTop(),
+              content2->OffsetTop() - container2->OffsetTop());
+  } else {
+    ASSERT_EQ(container2->scrollTop(), 0);
+  }
+
+  if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled()) {
+    // The rest of the test depends on scrolling the inner and outer scrollers
+    // sequentially, which we do not do if MultiSmoothScrollIntoView is enabled.
+    return;
+  }
 
   // Scrolling content2 in container2
   Compositor().BeginFrame();  // Set start_time = now.
@@ -367,7 +435,7 @@
 
 // Ensure an in-progress smooth sequenced scroll isn't interrupted by a
 // scrollIntoView call that doesn't actually cause scrolling.
-TEST_F(ScrollIntoViewTest, NoOpScrollIntoViewContinuesCurrentAnimation) {
+TEST_P(ScrollIntoViewTest, NoOpScrollIntoViewContinuesCurrentAnimation) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
@@ -408,7 +476,12 @@
   Compositor().BeginFrame(0.2);
   ASSERT_NEAR(Window().scrollY(),
               (::features::IsImpulseScrollAnimationEnabled() ? 250 : 241), 1);
-  ASSERT_EQ(container->scrollTop(), 0);
+  if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled()) {
+    ASSERT_NEAR(container->scrollTop(),
+                (::features::IsImpulseScrollAnimationEnabled() ? 800 : 299), 1);
+  } else {
+    ASSERT_EQ(container->scrollTop(), 0);
+  }
 
   // Since visibleElement is already on screen, this call should be a no-op.
   {
@@ -422,12 +495,17 @@
   }
 
   // The window animation should continue running but the container shouldn't
-  // yet have started.
+  // yet have started unless MultiSmoothScrollIntoView support is enabled.
   Compositor().BeginFrame();
   ASSERT_NEAR(Window().scrollY(),
               (::features::IsImpulseScrollAnimationEnabled() ? 258 : 260), 1);
-  ASSERT_EQ(container->scrollTop(),
-            0);  // container should not have scrolled yet.
+  if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled()) {
+    ASSERT_GT(container->scrollTop(),
+              (::features::IsImpulseScrollAnimationEnabled() ? 800 : 299));
+  } else {
+    // container should not have scrolled yet.
+    ASSERT_EQ(container->scrollTop(), 0);
+  }
 
   // Finish the animation to make sure the animation to content finishes
   // without interruption.
@@ -438,7 +516,7 @@
   EXPECT_EQ(container->scrollTop(), 1000);
 }
 
-TEST_F(ScrollIntoViewTest, ScrollWindowAbortsCurrentAnimation) {
+TEST_P(ScrollIntoViewTest, ScrollWindowAbortsCurrentAnimation) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
@@ -470,7 +548,12 @@
   Compositor().BeginFrame(0.2);
   ASSERT_NEAR(Window().scrollY(),
               (::features::IsImpulseScrollAnimationEnabled() ? 800 : 299), 1);
-  ASSERT_EQ(container->scrollTop(), 0);
+  if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled()) {
+    ASSERT_NEAR(container->scrollTop(),
+                (::features::IsImpulseScrollAnimationEnabled() ? 800 : 299), 1);
+  } else {
+    ASSERT_EQ(container->scrollTop(), 0);
+  }
 
   ScrollToOptions* window_option = ScrollToOptions::Create();
   window_option->setLeft(0);
@@ -485,10 +568,15 @@
 
   Compositor().BeginFrame(1);
   ASSERT_EQ(Window().scrollY(), 0);
-  ASSERT_EQ(container->scrollTop(), 0);
+  if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled()) {
+    ASSERT_EQ(container->scrollTop(),
+              content->OffsetTop() - container->OffsetTop());
+  } else {
+    ASSERT_EQ(container->scrollTop(), 0);
+  }
 }
 
-TEST_F(ScrollIntoViewTest, BlockAndInlineSettings) {
+TEST_P(ScrollIntoViewTest, BlockAndInlineSettings) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
@@ -549,7 +637,7 @@
             content->OffsetTop() + content_height - window_height);
 }
 
-TEST_F(ScrollIntoViewTest, SmoothAndInstantInChain) {
+TEST_P(ScrollIntoViewTest, SmoothAndInstantInChain) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
@@ -603,7 +691,7 @@
             content->OffsetTop() - inner_container->OffsetTop());
 }
 
-TEST_F(ScrollIntoViewTest, SmoothScrollAnchor) {
+TEST_P(ScrollIntoViewTest, SmoothScrollAnchor) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
@@ -635,7 +723,7 @@
             content->OffsetTop() - container->OffsetTop());
 }
 
-TEST_F(ScrollIntoViewTest, FindDoesNotScrollOverflowHidden) {
+TEST_P(ScrollIntoViewTest, FindDoesNotScrollOverflowHidden) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
@@ -658,7 +746,7 @@
   ASSERT_EQ(container->scrollTop(), 0);
 }
 
-TEST_F(ScrollIntoViewTest, ApplyRootElementScrollBehaviorToViewport) {
+TEST_P(ScrollIntoViewTest, ApplyRootElementScrollBehaviorToViewport) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
@@ -694,7 +782,7 @@
 // prevent scrolling a non-default root scroller from the page revealing
 // ScrollIntoView (the layout viewport scroll will be animated, potentially
 // with zoom, from WebViewImpl::FinishScrollFocusedEditableIntoView.
-TEST_F(ScrollIntoViewTest, StopAtLayoutViewportForFocusedEditable) {
+TEST_P(ScrollIntoViewTest, StopAtLayoutViewportForFocusedEditable) {
   ScopedImplicitRootScrollerForTest implicit_root_scroller(true);
 
   v8::HandleScope HandleScope(
@@ -790,7 +878,7 @@
 }
 
 // This test passes if it doesn't crash/hit an ASAN check.
-TEST_F(ScrollIntoViewTest, RemoveSequencedScrollableArea) {
+TEST_P(ScrollIntoViewTest, RemoveSequencedScrollableArea) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
@@ -849,7 +937,7 @@
   Compositor().BeginFrame(1);
 }
 
-TEST_F(ScrollIntoViewTest, SmoothUserScrollNotAbortedByProgrammaticScrolls) {
+TEST_P(ScrollIntoViewTest, SmoothUserScrollNotAbortedByProgrammaticScrolls) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
@@ -887,7 +975,7 @@
   ASSERT_EQ(Window().scrollY(), content->OffsetTop());
 }
 
-TEST_F(ScrollIntoViewTest, LongDistanceSmoothScrollFinishedInThreeSeconds) {
+TEST_P(ScrollIntoViewTest, LongDistanceSmoothScrollFinishedInThreeSeconds) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
@@ -921,7 +1009,7 @@
   ASSERT_EQ(Window().scrollY(), target->OffsetTop());
 }
 
-TEST_F(ScrollIntoViewTest, OriginCrossingUseCounter) {
+TEST_P(ScrollIntoViewTest, OriginCrossingUseCounter) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
@@ -1016,7 +1104,7 @@
   }
 }
 
-TEST_F(ScrollIntoViewTest, FromDisplayNoneIframe) {
+TEST_P(ScrollIntoViewTest, FromDisplayNoneIframe) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
@@ -1104,7 +1192,7 @@
   EXPECT_EQ(Window().scrollX(), 0);
 }
 
-TEST_F(ScrollIntoViewTest, EmptyEditableElementRect) {
+TEST_P(ScrollIntoViewTest, EmptyEditableElementRect) {
   v8::HandleScope HandleScope(
       WebView().GetPage()->GetAgentGroupScheduler().Isolate());
   WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
index 1b87c84..42b2589 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -214,8 +214,9 @@
 
   ClearScrollableArea();
 
-  if (SmoothScrollSequencer* sequencer = GetSmoothScrollSequencer())
+  if (SmoothScrollSequencer* sequencer = GetSmoothScrollSequencer()) {
     sequencer->DidDisposeScrollableArea(*this);
+  }
 
   RunScrollCompleteCallbacks(ScrollableArea::ScrollCompletionMode::kFinished);
 
@@ -2424,13 +2425,17 @@
   new_scroll_offset = ScrollPositionToOffset(end_point);
 
   if (params->is_for_scroll_sequence) {
-    CHECK(GetSmoothScrollSequencer());
-    DCHECK(params->type == mojom::blink::ScrollType::kProgrammatic ||
-           params->type == mojom::blink::ScrollType::kUser);
     mojom::blink::ScrollBehavior behavior = DetermineScrollBehavior(
         params->behavior, GetLayoutBox()->StyleRef().GetScrollBehavior());
-    GetSmoothScrollSequencer()->QueueAnimation(this, new_scroll_offset,
-                                               behavior);
+    if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled()) {
+      SetScrollOffset(new_scroll_offset, params->type, behavior);
+    } else {
+      CHECK(GetSmoothScrollSequencer());
+      DCHECK(params->type == mojom::blink::ScrollType::kProgrammatic ||
+             params->type == mojom::blink::ScrollType::kUser);
+      GetSmoothScrollSequencer()->QueueAnimation(this, new_scroll_offset,
+                                                 behavior);
+    }
   } else {
     SetScrollOffset(new_scroll_offset, params->type,
                     mojom::blink::ScrollBehavior::kInstant);
diff --git a/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc b/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc
index 9704ea1..cb4cf91 100644
--- a/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc
+++ b/third_party/blink/renderer/core/scroll/programmatic_scroll_animator.cc
@@ -46,8 +46,9 @@
   ScrollOffsetChanged(offset, GetScrollType());
   is_sequenced_scroll_ = false;
   if (SmoothScrollSequencer* sequencer =
-          GetScrollableArea()->GetSmoothScrollSequencer())
+          GetScrollableArea()->GetSmoothScrollSequencer()) {
     sequencer->RunQueuedAnimations();
+  }
 }
 
 void ProgrammaticScrollAnimator::AnimateToOffset(
@@ -146,23 +147,22 @@
           GetScrollableArea()->GetCompositorAnimationTimeline());
 
     bool sent_to_compositor = false;
+    if (!scrollable_area_->ShouldScrollOnMainThread()) {
+      // If MultiSmoothScrollIntoView is not enabled, we use sequenced scrolls
+      // which we cannot send to the compositor thread. crbug.com/730705.
+      if (!is_sequenced_scroll_ ||
+          RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled()) {
+        auto animation = cc::KeyframeModel::Create(
+            animation_curve_->Clone(),
+            cc::AnimationIdProvider::NextKeyframeModelId(),
+            cc::AnimationIdProvider::NextGroupId(),
+            cc::KeyframeModel::TargetPropertyId(
+                cc::TargetProperty::SCROLL_OFFSET));
 
-    // TODO(sunyunjia): Sequenced Smooth Scroll should also be able to
-    // scroll on the compositor thread. We should send the ScrollType
-    // information to the compositor thread.
-    // crbug.com/730705
-    if (!scrollable_area_->ShouldScrollOnMainThread() &&
-        !is_sequenced_scroll_) {
-      auto animation = cc::KeyframeModel::Create(
-          animation_curve_->Clone(),
-          cc::AnimationIdProvider::NextKeyframeModelId(),
-          cc::AnimationIdProvider::NextGroupId(),
-          cc::KeyframeModel::TargetPropertyId(
-              cc::TargetProperty::SCROLL_OFFSET));
-
-      if (AddAnimation(std::move(animation))) {
-        sent_to_compositor = true;
-        run_state_ = RunState::kRunningOnCompositor;
+        if (AddAnimation(std::move(animation))) {
+          sent_to_compositor = true;
+          run_state_ = RunState::kRunningOnCompositor;
+        }
       }
     }
 
diff --git a/third_party/blink/renderer/core/scroll/scroll_into_view_util.cc b/third_party/blink/renderer/core/scroll/scroll_into_view_util.cc
index 3c6437f..a86ba417 100644
--- a/third_party/blink/renderer/core/scroll/scroll_into_view_util.cc
+++ b/third_party/blink/renderer/core/scroll/scroll_into_view_util.cc
@@ -22,6 +22,7 @@
 #include "third_party/blink/renderer/core/page/page.h"
 #include "third_party/blink/renderer/core/scroll/smooth_scroll_sequencer.h"
 #include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
 #include "ui/gfx/geometry/rect_f.h"
 
@@ -132,6 +133,9 @@
   PhysicalRect absolute_rect_to_scroll = absolute_rect;
   PhysicalBoxStrut active_scroll_margin = scroll_margin;
   bool scrolled_to_area = false;
+  bool will_sequence_scrolls =
+      !RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled() &&
+      params->is_for_scroll_sequence;
 
   // TODO(bokan): Temporary, to track cross-origin scroll-into-view prevalence.
   // https://crbug.com/1339003.
@@ -169,10 +173,10 @@
 
     if (area_to_scroll) {
       ScrollOffset scroll_before = area_to_scroll->GetScrollOffset();
-      CHECK(!params->is_for_scroll_sequence ||
+      CHECK(!will_sequence_scrolls ||
             area_to_scroll->GetSmoothScrollSequencer());
       wtf_size_t num_scroll_sequences =
-          params->is_for_scroll_sequence
+          will_sequence_scrolls
               ? area_to_scroll->GetSmoothScrollSequencer()->GetCount()
               : 0ul;
 
@@ -188,7 +192,7 @@
       // check instead if an entry was added to the sequence which occurs only
       // if the scroll offset is changed as a result of ScrollIntoView.
       bool scroll_changed =
-          params->is_for_scroll_sequence
+          will_sequence_scrolls
               ? area_to_scroll->GetSmoothScrollSequencer()->GetCount() !=
                     num_scroll_sequences
               : area_to_scroll->GetScrollOffset() != scroll_before;
@@ -296,9 +300,12 @@
 
   params->is_for_scroll_sequence |=
       params->type == mojom::blink::ScrollType::kProgrammatic;
+  bool will_sequence_scrolls =
+      !RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled() &&
+      params->is_for_scroll_sequence;
 
   SmoothScrollSequencer* old_sequencer = nullptr;
-  if (params->is_for_scroll_sequence) {
+  if (will_sequence_scrolls) {
     old_sequencer = frame->CreateNewSmoothScrollSequence();
     frame->GetSmoothScrollSequencer()->SetScrollType(params->type);
   }
@@ -319,7 +326,7 @@
       PerformBubblingScrollIntoView(*enclosing_box, scroll_into_view_rect,
                                     params, scroll_margin, from_remote_frame);
 
-  if (params->is_for_scroll_sequence) {
+  if (will_sequence_scrolls) {
     if (frame->GetSmoothScrollSequencer()->IsEmpty()) {
       // If the scroll into view was a no-op (the element was already in the
       // proper place), reinstate any previously running smooth scroll sequence
diff --git a/third_party/blink/renderer/core/scroll/scrollable_area.cc b/third_party/blink/renderer/core/scroll/scrollable_area.cc
index 0183ead3..c0def6c 100644
--- a/third_party/blink/renderer/core/scroll/scrollable_area.cc
+++ b/third_party/blink/renderer/core/scroll/scrollable_area.cc
@@ -327,13 +327,19 @@
         }
       },
       WrapWeakPersistent(this)));
-
+  bool filter_scroll = false;
   if (SmoothScrollSequencer* sequencer = GetSmoothScrollSequencer()) {
-    if (sequencer->FilterNewScrollOrAbortCurrent(scroll_type)) {
-      std::move(run_scroll_complete_callbacks)
-          .Run(ScrollCompletionMode::kFinished);
-      return false;
-    }
+    DCHECK(!RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled());
+    filter_scroll = sequencer->FilterNewScrollOrAbortCurrent(scroll_type);
+  } else if (active_smooth_scroll_type_.has_value()) {
+    DCHECK(RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled());
+    filter_scroll = ShouldFilterIncomingScroll(scroll_type);
+  }
+
+  if (filter_scroll) {
+    std::move(run_scroll_complete_callbacks)
+        .Run(ScrollCompletionMode::kFinished);
+    return false;
   }
 
   ScrollOffset previous_offset = GetScrollOffset();
@@ -390,21 +396,41 @@
       GetScrollAnimator().AdjustAnimation(animation_adjustment);
       break;
     case mojom::blink::ScrollType::kProgrammatic:
-      return ProgrammaticScrollHelper(clamped_offset, behavior,
-                                      /* is_sequenced_scroll */ false,
-                                      animation_adjustment,
-                                      std::move(run_scroll_complete_callbacks));
+      if (ProgrammaticScrollHelper(clamped_offset, behavior,
+                                   /* is_sequenced_scroll */ false,
+                                   animation_adjustment,
+                                   std::move(run_scroll_complete_callbacks))) {
+        if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled() &&
+            behavior == mojom::blink::ScrollBehavior::kSmooth) {
+          active_smooth_scroll_type_ = scroll_type;
+        }
+        return true;
+      }
+      return false;
     case mojom::blink::ScrollType::kSequenced:
       return ProgrammaticScrollHelper(clamped_offset, behavior,
                                       /* is_sequenced_scroll */ true,
                                       animation_adjustment,
                                       std::move(run_scroll_complete_callbacks));
     case mojom::blink::ScrollType::kUser:
-      UserScrollHelper(clamped_offset, behavior);
-      break;
+      if (RuntimeEnabledFeatures::MultiSmoothScrollIntoViewEnabled() &&
+          behavior == mojom::blink::ScrollBehavior::kSmooth) {
+        if (ProgrammaticScrollHelper(
+                clamped_offset, behavior,
+                /* is_sequenced_scroll */ false, animation_adjustment,
+                std::move(run_scroll_complete_callbacks))) {
+          active_smooth_scroll_type_ = scroll_type;
+          return true;
+        }
+        return false;
+      } else {
+        UserScrollHelper(clamped_offset, behavior);
+        break;
+      }
     default:
       NOTREACHED_IN_MIGRATION();
   }
+
   std::move(run_scroll_complete_callbacks).Run(ScrollCompletionMode::kFinished);
   return true;
 }
@@ -1232,6 +1258,7 @@
 void ScrollableArea::OnScrollFinished(bool scroll_did_end) {
   if (GetLayoutBox()) {
     if (scroll_did_end) {
+      active_smooth_scroll_type_.reset();
       UpdateSnappedTargetsAndEnqueueScrollSnapChange();
       if (Node* node = EventTargetNode()) {
         if (auto* anchor_element_interaction_tracker =
diff --git a/third_party/blink/renderer/core/scroll/scrollable_area.h b/third_party/blink/renderer/core/scroll/scrollable_area.h
index 14f3ce9..5f7737b 100644
--- a/third_party/blink/renderer/core/scroll/scrollable_area.h
+++ b/third_party/blink/renderer/core/scroll/scrollable_area.h
@@ -713,6 +713,32 @@
   void ScrollToScrollStartTarget(const LayoutBox*, cc::SnapAxis);
   void ScrollToScrollStartTargets(const ScrollStartTargetCandidates*);
 
+  bool ShouldFilterIncomingScroll(mojom::blink::ScrollType incoming_type) {
+    auto old_type = active_smooth_scroll_type_;
+
+    // Allow the incoming scroll to co-exist if its scroll type is
+    // kClamping, or kAnchoring.
+    if (incoming_type == mojom::blink::ScrollType::kClamping ||
+        incoming_type == mojom::blink::ScrollType::kAnchoring) {
+      return false;
+    }
+    // If the current smooth scroll is UserScroll, but the incoming scroll is
+    // not, filter the incoming scroll. See crbug.com/913009 for more details.
+    if (old_type == mojom::blink::ScrollType::kUser &&
+        incoming_type != mojom::blink::ScrollType::kUser) {
+      return true;
+    }
+    // TODO(crbug.com/325081538, crbug.com/342093060): Ideally, if the incoming
+    // scroll is a gesture scroll we'd cancel the current animation here.
+    // But to do that, we must be able to distinguish between compositor updates
+    // due to gesture scrolls from compositor updates due to impl-ticked
+    // programmatic scrolls. So we'd need to:
+    //   - split kCompositor ScrollType into kCompositorUser and
+    //     kCompositorProgrammatic and
+    //   - pass the ScrollType from the compositor to the main thread.
+    return false;
+  }
+
   // This animator is used to handle painting animations for MacOS scrollbars
   // using AppKit-specific code (Cocoa APIs). It requires input from
   // ScrollableArea about changes on scrollbars. For other platforms, painting
@@ -739,6 +765,8 @@
   unsigned mouse_over_scrollbar_ : 1;
   unsigned has_been_disposed_ : 1;
 
+  std::optional<mojom::blink::ScrollType> active_smooth_scroll_type_;
+
   scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
 };
 
diff --git a/third_party/blink/renderer/core/svg/build.gni b/third_party/blink/renderer/core/svg/build.gni
index 3e41dd0..0b3c5efc 100644
--- a/third_party/blink/renderer/core/svg/build.gni
+++ b/third_party/blink/renderer/core/svg/build.gni
@@ -17,8 +17,6 @@
   "animation/smil_time_container.h",
   "animation/svg_smil_element.cc",
   "animation/svg_smil_element.h",
-  "color_distance.cc",
-  "color_distance.h",
   "gradient_attributes.h",
   "graphics/filters/svg_fe_image.cc",
   "graphics/filters/svg_fe_image.h",
diff --git a/third_party/blink/renderer/core/svg/color_distance.cc b/third_party/blink/renderer/core/svg/color_distance.cc
deleted file mode 100644
index 02ef54d..0000000
--- a/third_party/blink/renderer/core/svg/color_distance.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "third_party/blink/renderer/core/svg/color_distance.h"
-
-#include "third_party/blink/renderer/platform/graphics/color.h"
-
-#include <math.h>
-
-namespace blink {
-
-Color ColorDistance::AddColors(const Color& first, const Color& second) {
-  return Color(first.Red() + second.Red(), first.Green() + second.Green(),
-               first.Blue() + second.Blue());
-}
-
-float ColorDistance::Distance(const Color& from_color, const Color& to_color) {
-  int red_diff = to_color.Red() - from_color.Red();
-  int green_diff = to_color.Green() - from_color.Green();
-  int blue_diff = to_color.Blue() - from_color.Blue();
-
-  // This is just a simple distance calculation, not respecting color spaces
-  return sqrtf(red_diff * red_diff + blue_diff * blue_diff +
-               green_diff * green_diff);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/color_distance.h b/third_party/blink/renderer/core/svg/color_distance.h
deleted file mode 100644
index cef574f..0000000
--- a/third_party/blink/renderer/core/svg/color_distance.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_COLOR_DISTANCE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_COLOR_DISTANCE_H_
-
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-class Color;
-
-class ColorDistance {
-  STATIC_ONLY(ColorDistance);
-
- public:
-  static Color AddColors(const Color&, const Color&);
-  static float Distance(const Color& from_color, const Color& to_color);
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_SVG_COLOR_DISTANCE_H_
diff --git a/third_party/blink/renderer/core/svg/graphics/isolated_svg_document_host.cc b/third_party/blink/renderer/core/svg/graphics/isolated_svg_document_host.cc
index 0c1d8b1d8..08712f3 100644
--- a/third_party/blink/renderer/core/svg/graphics/isolated_svg_document_host.cc
+++ b/third_party/blink/renderer/core/svg/graphics/isolated_svg_document_host.cc
@@ -139,7 +139,7 @@
 }
 
 void IsolatedSVGDocumentHost::InstallDocument(
-    const SegmentedBuffer& data,
+    scoped_refptr<const SharedBuffer> data,
     base::OnceClosure async_load_callback,
     const Settings* inherited_settings,
     ProcessingMode processing_mode) {
@@ -165,8 +165,9 @@
     settings.SetImageAnimationPolicy(
         mojom::blink::ImageAnimationPolicy::kImageAnimationPolicyNoAnimation);
   }
+  CHECK(data);
   LocalFrame* frame = GetFrame();
-  frame->ForceSynchronousDocumentInstall(AtomicString("image/svg+xml"), data);
+  frame->ForceSynchronousDocumentInstall(AtomicString("image/svg+xml"), *data);
 
   // Intrinsic sizing relies on computed style (e.g. font-size and
   // writing-mode).
diff --git a/third_party/blink/renderer/core/svg/graphics/isolated_svg_document_host.h b/third_party/blink/renderer/core/svg/graphics/isolated_svg_document_host.h
index 09630f46..a304874 100644
--- a/third_party/blink/renderer/core/svg/graphics/isolated_svg_document_host.h
+++ b/third_party/blink/renderer/core/svg/graphics/isolated_svg_document_host.h
@@ -59,7 +59,7 @@
   IsolatedSVGDocumentHost(IsolatedSVGChromeClient&, AgentGroupScheduler&);
   ~IsolatedSVGDocumentHost();
 
-  void InstallDocument(const SegmentedBuffer& data,
+  void InstallDocument(scoped_refptr<const SharedBuffer> data,
                        base::OnceClosure async_load_callback,
                        const Settings* inherited_settings,
                        ProcessingMode processing_mode);
diff --git a/third_party/blink/renderer/core/svg/graphics/svg_image.cc b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
index 141f3bb..8fd6d88 100644
--- a/third_party/blink/renderer/core/svg/graphics/svg_image.cc
+++ b/third_party/blink/renderer/core/svg/graphics/svg_image.cc
@@ -671,7 +671,7 @@
       IsolatedSVGDocumentHostInitializer::Get()->GetOrCreate();
   chrome_client_->SetImage(this);
   document_host_->InstallDocument(
-      *Data(),
+      Data(),
       WTF::BindOnce(&SVGImage::NotifyAsyncLoadCompleted,
                     weak_ptr_factory_.GetWeakPtr()),
       settings_to_use, IsolatedSVGDocumentHost::ProcessingMode::kAnimated);
diff --git a/third_party/blink/renderer/core/svg/svg_animated_color.cc b/third_party/blink/renderer/core/svg/svg_animated_color.cc
index 9a4a3ae..916668d 100644
--- a/third_party/blink/renderer/core/svg/svg_animated_color.cc
+++ b/third_party/blink/renderer/core/svg/svg_animated_color.cc
@@ -24,11 +24,57 @@
 #include "third_party/blink/renderer/core/css/properties/longhands.h"
 #include "third_party/blink/renderer/core/dom/node_computed_style.h"
 #include "third_party/blink/renderer/core/svg/animation/smil_animation_effect_parameters.h"
-#include "third_party/blink/renderer/core/svg/color_distance.h"
 #include "third_party/blink/renderer/core/svg/svg_element.h"
 
 namespace blink {
 
+namespace {
+
+struct RGBATuple {
+  float red;
+  float green;
+  float blue;
+  float alpha;
+};
+
+void Accumulate(RGBATuple& base, const RGBATuple& addend) {
+  base.red += addend.red;
+  base.green += addend.green;
+  base.blue += addend.blue;
+  base.alpha += addend.alpha;
+}
+
+RGBATuple ToRGBATuple(const StyleColor& color,
+                      Color fallback_color,
+                      mojom::blink::ColorScheme color_scheme) {
+  const Color resolved = color.Resolve(fallback_color, color_scheme);
+  RGBATuple tuple;
+  resolved.GetRGBA(tuple.red, tuple.green, tuple.blue, tuple.alpha);
+  return tuple;
+}
+
+StyleColor ToStyleColor(const RGBATuple& tuple) {
+  return StyleColor(
+      Color::FromRGBAFloat(tuple.red, tuple.green, tuple.blue, tuple.alpha));
+}
+
+Color FallbackColorForCurrentColor(const SVGElement& target_element) {
+  if (const ComputedStyle* target_style = target_element.GetComputedStyle()) {
+    return target_style->VisitedDependentColor(GetCSSPropertyColor());
+  }
+  return Color::kTransparent;
+}
+
+mojom::blink::ColorScheme ColorSchemeForSVGElement(
+    const SVGElement& target_element) {
+  if (const ComputedStyle* target_style = target_element.GetComputedStyle()) {
+    return target_style->UsedColorScheme();
+  }
+  return mojom::blink::ColorScheme::kLight;
+}
+
+}  // namespace
+
 SVGColorProperty::SVGColorProperty(const String& color_string)
     : style_color_(StyleColor::CurrentColor()) {
   Color color;
@@ -49,33 +95,18 @@
   return nullptr;
 }
 
-static inline Color FallbackColorForCurrentColor(
-    const SVGElement* target_element) {
-  DCHECK(target_element);
-  if (const ComputedStyle* target_style = target_element->GetComputedStyle())
-    return target_style->VisitedDependentColor(GetCSSPropertyColor());
-  return Color::kTransparent;
-}
-
-static inline mojom::blink::ColorScheme ColorSchemeForSVGElement(
-    const SVGElement* target_element) {
-  DCHECK(target_element);
-  if (const ComputedStyle* target_style = target_element->GetComputedStyle())
-    return target_style->UsedColorScheme();
-  return mojom::blink::ColorScheme::kLight;
-}
-
 void SVGColorProperty::Add(const SVGPropertyBase* other,
                            const SVGElement* context_element) {
   DCHECK(context_element);
 
-  Color fallback_color = FallbackColorForCurrentColor(context_element);
+  Color fallback_color = FallbackColorForCurrentColor(*context_element);
   mojom::blink::ColorScheme color_scheme =
-      ColorSchemeForSVGElement(context_element);
-  Color from_color = To<SVGColorProperty>(other)->style_color_.Resolve(
-      fallback_color, color_scheme);
-  Color to_color = style_color_.Resolve(fallback_color, color_scheme);
-  style_color_ = StyleColor(ColorDistance::AddColors(from_color, to_color));
+      ColorSchemeForSVGElement(*context_element);
+  auto base = ToRGBATuple(To<SVGColorProperty>(other)->style_color_,
+                          fallback_color, color_scheme);
+  const auto addend = ToRGBATuple(style_color_, fallback_color, color_scheme);
+  Accumulate(base, addend);
+  style_color_ = ToStyleColor(base);
 }
 
 void SVGColorProperty::CalculateAnimatedValue(
@@ -93,53 +124,53 @@
 
   // Apply currentColor rules.
   DCHECK(context_element);
-  Color fallback_color = FallbackColorForCurrentColor(context_element);
+  Color fallback_color = FallbackColorForCurrentColor(*context_element);
   mojom::blink::ColorScheme color_scheme =
-      ColorSchemeForSVGElement(context_element);
-  Color from_color = from_style_color.Resolve(fallback_color, color_scheme);
-  Color to_color = to_style_color.Resolve(fallback_color, color_scheme);
-  Color to_at_end_of_duration_color =
-      to_at_end_of_duration_style_color.Resolve(fallback_color, color_scheme);
+      ColorSchemeForSVGElement(*context_element);
+  const auto from = ToRGBATuple(from_style_color, fallback_color, color_scheme);
+  const auto to = ToRGBATuple(to_style_color, fallback_color, color_scheme);
+  const auto to_at_end_of_duration = ToRGBATuple(
+      to_at_end_of_duration_style_color, fallback_color, color_scheme);
 
-  // TODO(crbug.com/1399566): Use float color and don't clobber colorspace.
-  float animated_red = ComputeAnimatedNumber(
-      parameters, percentage, repeat_count, from_color.Red(), to_color.Red(),
-      to_at_end_of_duration_color.Red());
-  float animated_green = ComputeAnimatedNumber(
-      parameters, percentage, repeat_count, from_color.Green(),
-      to_color.Green(), to_at_end_of_duration_color.Green());
-  float animated_blue = ComputeAnimatedNumber(
-      parameters, percentage, repeat_count, from_color.Blue(), to_color.Blue(),
-      to_at_end_of_duration_color.Blue());
-  float animated_alpha = ComputeAnimatedNumber(
-      parameters, percentage, repeat_count, from_color.AlphaAsInteger(),
-      to_color.AlphaAsInteger(), to_at_end_of_duration_color.AlphaAsInteger());
+  // TODO(crbug.com/40249893): Don't clobber colorspace.
+  RGBATuple result;
+  result.red =
+      ComputeAnimatedNumber(parameters, percentage, repeat_count, from.red,
+                            to.red, to_at_end_of_duration.red);
+  result.green =
+      ComputeAnimatedNumber(parameters, percentage, repeat_count, from.green,
+                            to.green, to_at_end_of_duration.green);
+  result.blue =
+      ComputeAnimatedNumber(parameters, percentage, repeat_count, from.blue,
+                            to.blue, to_at_end_of_duration.blue);
+  result.alpha =
+      ComputeAnimatedNumber(parameters, percentage, repeat_count, from.alpha,
+                            to.alpha, to_at_end_of_duration.alpha);
 
   if (parameters.is_additive) {
-    Color animated_color = style_color_.Resolve(fallback_color, color_scheme);
-    animated_red += animated_color.Red();
-    animated_green += animated_color.Green();
-    animated_blue += animated_color.Blue();
-    animated_alpha += animated_color.AlphaAsInteger();
+    Accumulate(result, ToRGBATuple(style_color_, fallback_color, color_scheme));
   }
 
-  style_color_ = StyleColor(
-      Color::FromRGBA(roundf(animated_red), roundf(animated_green),
-                      roundf(animated_blue), roundf(animated_alpha)));
+  style_color_ = ToStyleColor(result);
 }
 
 float SVGColorProperty::CalculateDistance(
     const SVGPropertyBase* to_value,
     const SVGElement* context_element) const {
   DCHECK(context_element);
-  Color fallback_color = FallbackColorForCurrentColor(context_element);
+  Color fallback_color = FallbackColorForCurrentColor(*context_element);
   mojom::blink::ColorScheme color_scheme =
-      ColorSchemeForSVGElement(context_element);
+      ColorSchemeForSVGElement(*context_element);
 
-  Color from_color = style_color_.Resolve(fallback_color, color_scheme);
-  Color to_color = To<SVGColorProperty>(to_value)->style_color_.Resolve(
-      fallback_color, color_scheme);
-  return ColorDistance::Distance(from_color, to_color);
+  const auto from = ToRGBATuple(style_color_, fallback_color, color_scheme);
+  const auto to = ToRGBATuple(To<SVGColorProperty>(to_value)->style_color_,
+                              fallback_color, color_scheme);
+  float red_diff = to.red - from.red;
+  float green_diff = to.green - from.green;
+  float blue_diff = to.blue - from.blue;
+  // This is just a simple distance calculation, not respecting color spaces
+  return sqrtf(red_diff * red_diff + blue_diff * blue_diff +
+               green_diff * green_diff);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_resource_document_content.cc b/third_party/blink/renderer/core/svg/svg_resource_document_content.cc
index 958f1e3..c50aeda 100644
--- a/third_party/blink/renderer/core/svg/svg_resource_document_content.cc
+++ b/third_party/blink/renderer/core/svg/svg_resource_document_content.cc
@@ -130,16 +130,17 @@
 }
 
 SVGResourceDocumentContent::UpdateResult
-SVGResourceDocumentContent::UpdateDocument(const SegmentedBuffer& data,
+SVGResourceDocumentContent::UpdateDocument(scoped_refptr<SharedBuffer> data,
                                            const KURL& request_url) {
-  if (data.empty()) {
+  if (data->empty()) {
     return UpdateResult::kError;
   }
+  CHECK(!document_host_);
   auto* chrome_client = MakeGarbageCollected<ChromeClient>(this);
   document_host_ = MakeGarbageCollected<IsolatedSVGDocumentHost>(
       *chrome_client, *agent_group_scheduler_);
   document_host_->InstallDocument(
-      data,
+      std::move(data),
       WTF::BindOnce(&SVGResourceDocumentContent::AsyncLoadingFinished,
                     WrapWeakPersistent(this)),
       nullptr, IsolatedSVGDocumentHost::ProcessingMode::kStatic);
diff --git a/third_party/blink/renderer/core/svg/svg_resource_document_content.h b/third_party/blink/renderer/core/svg/svg_resource_document_content.h
index 290b4263..1a810dc4 100644
--- a/third_party/blink/renderer/core/svg/svg_resource_document_content.h
+++ b/third_party/blink/renderer/core/svg/svg_resource_document_content.h
@@ -73,10 +73,10 @@
     kAsync,
     kError,
   };
-  // Update the contained document using the data in `data`, using
+  // Update the contained document using the text data in `content`, using
   // `request_url` as the document URL. Returns `kAsync` if the document's
   // 'load' event has not been dispatched.
-  UpdateResult UpdateDocument(const SegmentedBuffer& data,
+  UpdateResult UpdateDocument(scoped_refptr<SharedBuffer> data,
                               const KURL& request_url);
   void ClearDocument();
   void Dispose();
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc
index a94af2c..58ca89f 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -7934,9 +7934,8 @@
                            : CanSetFocusAttribute()) {
       string_builder = string_builder + " focusable";
     }
-    if (!IsDetached() && AXObjectCache().IsAriaOwned(this, /*checks*/ false)) {
+    if (!IsDetached() && AXObjectCache().IsAriaOwned(this))
       string_builder = string_builder + " isAriaOwned";
-    }
     if (IsIgnored()) {
       string_builder = string_builder + " isIgnored";
 #if defined(AX_FAIL_FAST_BUILD)
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index a444528c..59a1d2e 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -3717,8 +3717,8 @@
   }
 }
 
-bool AXObjectCacheImpl::IsAriaOwned(const AXObject* object, bool checks) const {
-  return relation_cache_ ? relation_cache_->IsAriaOwned(object, checks) : false;
+bool AXObjectCacheImpl::IsAriaOwned(const AXObject* object) const {
+  return relation_cache_ ? relation_cache_->IsAriaOwned(object) : false;
 }
 
 AXObject* AXObjectCacheImpl::ValidatedAriaOwner(const AXObject* object) const {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
index da61820..0126ec5 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -430,7 +430,7 @@
 
   // Returns true if the given object's position in the tree was due to
   // aria-owns.
-  bool IsAriaOwned(const AXObject*, bool checks = true) const;
+  bool IsAriaOwned(const AXObject*) const;
 
   // Returns the parent of the given object due to aria-owns, if valid.
   AXObject* ValidatedAriaOwner(const AXObject*) const;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
index 68c02ce..bb341b9 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
@@ -198,40 +198,11 @@
   return !owner_ids_to_update_.empty();
 }
 
-bool AXRelationCache::IsAriaOwned(const AXObject* child, bool check) const {
+bool AXRelationCache::IsAriaOwned(const AXObject* child) const {
   if (!child)
     return false;
   DCHECK(!child->IsDetached()) << "Child was detached: " << child;
-  bool is_owned =
-      aria_owned_child_to_owner_mapping_.Contains(child->AXObjectID());
-  if (is_owned) {
-    return true;
-  }
-
-  if (!check) {
-    return false;
-  }
-
-  // Ensure that unowned objects have the expected parent.
-  AXObject* parent = child->ParentObjectIfPresent();
-  if (parent && parent->GetElement() && child->GetElement() &&
-      !child->GetElement()->IsPseudoElement()) {
-    AXObject* natural_parent =
-        AXObject::ComputeNonARIAParent(*object_cache_, child->GetElement());
-    if (parent != natural_parent) {
-      std::ostringstream msg;
-      msg << "Unowned child should have natural parent:" << "\n* Child: "
-          << child << "\n* Actual parent: " << parent
-          << "\n* Natural parent: " << natural_parent
-          << "\n* Owners to update:";
-      for (AXID id : owner_ids_to_update_) {
-        msg << " " << id;
-      }
-      NOTREACHED() << msg.str();
-    }
-  }
-
-  return false;
+  return aria_owned_child_to_owner_mapping_.Contains(child->AXObjectID());
 }
 
 AXObject* AXRelationCache::GetAriaOwnedParent(const AXObject* child) const {
@@ -703,36 +674,17 @@
     Vector<String> owned_id_vector;
     owner->TokenVectorFromAttribute(element, owned_id_vector,
                                     html_names::kAriaOwnsAttr);
-    HeapVector<Member<Element>> valid_owned_child_elements;
     for (const String& id_name : owned_id_vector) {
       Element* child_element = scope.getElementById(AtomicString(id_name));
       if (!child_element ||
           !IsValidOwnsRelation(const_cast<AXObject*>(owner), *child_element)) {
         continue;
       }
-      AXID future_child_axid = child_element->GetDomNodeId();
-      HashMap<AXID, AXID>::const_iterator iter =
-          aria_owned_child_to_owner_mapping_.find(future_child_axid);
-      if (iter != aria_owned_child_to_owner_mapping_.end() &&
-          owner->AXObjectID() != iter->value) {
-        // Already has a different aria-owns parent.
+      AXObject* child = GetOrCreate(child_element, owner);
+      if (!child) {
         continue;
       }
-
-      // Preemptively add the child to owner mapping to satisfy checks
-      // that this child is owned, and therefore does not need to be added by
-      // any other node who's subtree is eagerly updated during the
-      // GetOrCreate() call, as this call recursively fills out subtrees.
-      aria_owned_child_to_owner_mapping_.Set(future_child_axid,
-                                             owner->AXObjectID());
-      valid_owned_child_elements.emplace_back(child_element);
-    }
-
-    for (Element* child_element : valid_owned_child_elements) {
-      AXObject* child = GetOrCreate(child_element, owner);
-      if (child) {
-        owned_children.push_back(child);
-      }
+      owned_children.push_back(child);
     }
   }
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
index cc1c5f9..65c46ec6 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
@@ -35,7 +35,7 @@
   // Returns true if the given object's position in the tree was due to
   // aria-owns.
   bool IsAriaOwned(AXID) const;
-  bool IsAriaOwned(const AXObject*, bool check = true) const;
+  bool IsAriaOwned(const AXObject*) const;
 
   // Returns the parent of the given object due to aria-owns, if valid,
   // otherwise, removes the child from maps indicating that it is owned.
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
index 64f5de3..9e398a3 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -3398,7 +3398,7 @@
   gfx::PointF location(ClampTo<float>(x),
                        ClampTo<float>(y + GetFontBaseline(*font_data)));
   gfx::RectF bounds;
-  double font_width = font.BidiWidth(text_run, &bounds);
+  double font_width = font.Width(text_run, &bounds);
 
   bool use_max_width = (max_width && *max_width < font_width);
   double width = use_max_width ? *max_width : font_width;
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
index 54e155d..beb3df2 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
@@ -1824,9 +1824,9 @@
   blink::test::RunPendingTasks();
   // If enabled, hibernation should cause repaint of the painting layer.
   EXPECT_FALSE(box->NeedsPaintPropertyUpdate());
-  EXPECT_EQ(Canvas2DLayerBridge::IsHibernationEnabled(),
+  EXPECT_EQ(features::IsCanvas2DHibernationEnabled(),
             painting_layer->SelfNeedsRepaint());
-  EXPECT_EQ(Canvas2DLayerBridge::IsHibernationEnabled(),
+  EXPECT_EQ(features::IsCanvas2DHibernationEnabled(),
             !CanvasElement().ResourceProvider());
 
   // The page is hidden so it doesn't make sense to paint, and doing so will
@@ -1839,7 +1839,7 @@
       mojom::blink::PageVisibilityState::kVisible,
       /*is_initial_state=*/false);
   EXPECT_FALSE(box->NeedsPaintPropertyUpdate());
-  EXPECT_EQ(Canvas2DLayerBridge::IsHibernationEnabled(),
+  EXPECT_EQ(features::IsCanvas2DHibernationEnabled(),
             painting_layer->SelfNeedsRepaint());
 }
 
diff --git a/third_party/blink/renderer/modules/credentialmanagement/authentication_credentials_container.cc b/third_party/blink/renderer/modules/credentialmanagement/authentication_credentials_container.cc
index dcf928b..86f4912 100644
--- a/third_party/blink/renderer/modules/credentialmanagement/authentication_credentials_container.cc
+++ b/third_party/blink/renderer/modules/credentialmanagement/authentication_credentials_container.cc
@@ -1972,6 +1972,8 @@
     }
 
     if (blink::RuntimeEnabledFeatures::FedCmIdPRegistrationEnabled() &&
+        blink::RuntimeEnabledFeatures::FedCmMultipleIdentityProvidersEnabled(
+            context) &&
         provider->hasConfigURL() && provider->configURL() == "any") {
       mojom::blink::IdentityProviderRequestOptionsPtr identity_provider =
           blink::mojom::blink::IdentityProviderRequestOptions::From(*provider);
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_cursor_unittest.cc b/third_party/blink/renderer/modules/indexeddb/idb_cursor_unittest.cc
index 678f85df..211aa44e0 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_cursor_unittest.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_cursor_unittest.cc
@@ -215,7 +215,7 @@
             WebString("blobuuid"), "text/plain", 123));
       }
       values.emplace_back(
-          std::make_unique<IDBValue>(std::nullopt, std::move(blob_info)));
+          std::make_unique<IDBValue>(Vector<char>(), std::move(blob_info)));
     }
     cursor_->SetPrefetchData(std::move(keys), std::move(primary_keys),
                              std::move(values));
@@ -285,7 +285,7 @@
                                                          "text/plain", 123));
     }
     values.emplace_back(
-        std::make_unique<IDBValue>(std::nullopt, std::move(blob_info)));
+        std::make_unique<IDBValue>(Vector<char>(), std::move(blob_info)));
   }
   cursor_->SetPrefetchData(std::move(keys), std::move(primary_keys),
                            std::move(values));
@@ -369,7 +369,7 @@
   Vector<std::unique_ptr<IDBValue>> values;
   for (int i = 0; i < prefetch_count; ++i) {
     values.emplace_back(
-        std::make_unique<IDBValue>(std::nullopt, Vector<WebBlobInfo>()));
+        std::make_unique<IDBValue>(Vector<char>(), Vector<WebBlobInfo>()));
   }
   cursor_->SetPrefetchData(std::move(keys), std::move(primary_keys),
                            std::move(values));
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request.cc b/third_party/blink/renderer/modules/indexeddb/idb_request.cc
index ba57f17..be74e2e 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_request.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_request.cc
@@ -467,7 +467,7 @@
   std::unique_ptr<IDBValue> value =
       optional_value
           ? std::move(optional_value)
-          : std::make_unique<IDBValue>(std::nullopt, Vector<WebBlobInfo>());
+          : std::make_unique<IDBValue>(Vector<char>(), Vector<WebBlobInfo>());
   value->SetIsolate(GetIsolate());
   transaction_->EnqueueResult(std::make_unique<IDBRequestQueueItem>(
       this, std::move(key), std::move(primary_key), std::move(value),
@@ -560,7 +560,7 @@
   if (result->get_value()->value) {
     value = std::move(*result->get_value()->value);
   } else {
-    value = std::make_unique<IDBValue>(std::nullopt, Vector<WebBlobInfo>());
+    value = std::make_unique<IDBValue>(Vector<char>(), Vector<WebBlobInfo>());
   }
 
   value->SetIsolate(GetIsolate());
@@ -747,8 +747,8 @@
   }
 
   if (pending_cursor_) {
-    // Value should be null, signifying the end of the cursor's range.
-    DCHECK(value->IsNull());
+    // Value should be empty, signifying the end of the cursor's range.
+    DCHECK(!value->DataSize());
     DCHECK(!value->BlobInfo().size());
     pending_cursor_->Close();
     pending_cursor_.Clear();
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc b/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc
index 80a3330..2c375eb 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc
@@ -122,7 +122,7 @@
   file_reader_loading_ = false;
 #endif  // DCHECK_IS_ON()
 
-  IDBValueUnwrapper::Unwrap(std::move(wrapped_data_), current_value_->get());
+  IDBValueUnwrapper::Unwrap(std::move(wrapped_data_), **current_value_);
   ++current_value_;
 
   StartNextValue();
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc b/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc
index 382eefc..29ba5d3e 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc
@@ -388,9 +388,9 @@
   // of memory, which crashes on memory-constrained systems.
   const size_t kMaxValueSizeForTesting = 10 * 1024 * 1024;  // 10 MB
 
-  const Vector<char> value_data = Vector<char>(kMaxValueSizeForTesting + 1);
+  const Vector<char> value_data(kMaxValueSizeForTesting + 1);
   const Vector<WebBlobInfo> blob_info;
-  auto value = std::make_unique<IDBValue>(value_data, blob_info);
+  auto value = std::make_unique<IDBValue>(Vector<char>(value_data), blob_info);
   std::unique_ptr<IDBKey> key = IDBKey::CreateNumber(0);
   const int64_t object_store_id = 2;
 
@@ -422,10 +422,9 @@
   const size_t kMaxValueSizeForTesting = 10 * 1024 * 1024;  // 10 MB
   const size_t kKeySize = 1024 * 1024;
 
-  const Vector<char> value_data =
-      Vector<char>(kMaxValueSizeForTesting - kKeySize);
+  const Vector<char> value_data(kMaxValueSizeForTesting - kKeySize);
   const Vector<WebBlobInfo> blob_info;
-  auto value = std::make_unique<IDBValue>(value_data, blob_info);
+  auto value = std::make_unique<IDBValue>(Vector<char>(value_data), blob_info);
   const int64_t object_store_id = 2;
 
   // For this test, we want IDBKey::SizeEstimate() minus kKeySize to be the
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_value.cc b/third_party/blink/renderer/modules/indexeddb/idb_value.cc
index 5e85a6d..5974fbf 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_value.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_value.cc
@@ -20,7 +20,7 @@
 namespace blink {
 
 IDBValue::IDBValue(
-    std::optional<Vector<char>> data,
+    Vector<char>&& data,
     Vector<WebBlobInfo> blob_info,
     Vector<mojo::PendingRemote<mojom::blink::FileSystemAccessTransferToken>>
         file_system_access_tokens)
@@ -34,16 +34,11 @@
 }
 
 scoped_refptr<SerializedScriptValue> IDBValue::CreateSerializedValue() const {
-  CHECK(data_);
   Vector<char> decompressed;
-  if (IDBValueUnwrapper::Decompress(*data_, &decompressed)) {
+  if (IDBValueUnwrapper::Decompress(data_, &decompressed)) {
     const_cast<IDBValue*>(this)->SetData(std::move(decompressed));
   }
-  return SerializedScriptValue::Create(base::as_byte_span(*data_));
-}
-
-bool IDBValue::IsNull() const {
-  return !data_;
+  return SerializedScriptValue::Create(base::as_byte_span(data_));
 }
 
 void IDBValue::SetIsolate(v8::Isolate* isolate) {
@@ -51,7 +46,7 @@
   DCHECK(!isolate_) << "SetIsolate must be called at most once";
 
   isolate_ = isolate;
-  external_allocated_size_ = data_ ? static_cast<int64_t>(data_->size()) : 0l;
+  external_allocated_size_ = DataSize();
   if (external_allocated_size_)
     isolate_->AdjustAmountOfExternalAllocatedMemory(external_allocated_size_);
 }
@@ -83,7 +78,7 @@
 std::unique_ptr<IDBValue> IDBValue::ConvertReturnValue(
     const mojom::blink::IDBReturnValuePtr& input) {
   if (!input) {
-    return std::make_unique<IDBValue>(std::nullopt, Vector<WebBlobInfo>());
+    return std::make_unique<IDBValue>(Vector<char>(), Vector<WebBlobInfo>());
   }
 
   std::unique_ptr<IDBValue> output = std::move(input->value);
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_value.h b/third_party/blink/renderer/modules/indexeddb/idb_value.h
index 70dd868..b2ce7f46 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_value.h
+++ b/third_party/blink/renderer/modules/indexeddb/idb_value.h
@@ -41,7 +41,7 @@
 class MODULES_EXPORT IDBValue final {
  public:
   IDBValue(
-      std::optional<Vector<char>> data,
+      Vector<char>&& data,
       Vector<WebBlobInfo>,
       Vector<mojo::PendingRemote<mojom::blink::FileSystemAccessTransferToken>> =
           {});
@@ -51,12 +51,11 @@
   IDBValue(const IDBValue&) = delete;
   IDBValue& operator=(const IDBValue&) = delete;
 
-  size_t DataSize() const { return data_ ? data_->size() : 0; }
+  size_t DataSize() const { return data_.size(); }
 
-  bool IsNull() const;
   scoped_refptr<SerializedScriptValue> CreateSerializedValue() const;
   const Vector<WebBlobInfo>& BlobInfo() const { return blob_info_; }
-  const std::optional<Vector<char>>& Data() const { return data_; }
+  const Vector<char>& Data() const { return data_; }
   const IDBKey* PrimaryKey() const { return primary_key_.get(); }
   const IDBKeyPath& KeyPath() const { return key_path_; }
 
@@ -101,7 +100,7 @@
  private:
   friend class IDBValueUnwrapper;
 
-  std::optional<Vector<char>> data_;
+  Vector<char> data_;
 
   Vector<WebBlobInfo> blob_info_;
 
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.cc b/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.cc
index d5e93f5..e8f0703 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.cc
@@ -276,10 +276,10 @@
 bool IDBValueUnwrapper::IsWrapped(IDBValue* value) {
   DCHECK(value);
 
-  if (!value->data_ || value->data_->size() < kHeaderSize) {
+  if (value->DataSize() < kHeaderSize) {
     return false;
   }
-  base::span<const uint8_t> data_span = base::as_byte_span(*value->data_);
+  base::span<const uint8_t> data_span = base::as_byte_span(value->Data());
   return data_span[0] == kVersionTag &&
          data_span[1] == kRequiresProcessingSSVPseudoVersion &&
          data_span[2] == kReplaceWithBlob;
@@ -297,12 +297,9 @@
 
 // static
 void IDBValueUnwrapper::Unwrap(Vector<char>&& wrapper_blob_content,
-                               IDBValue* wrapped_value) {
-  DCHECK(wrapped_value);
-  DCHECK(wrapped_value->data_);
-
-  wrapped_value->SetData(std::move(wrapper_blob_content));
-  wrapped_value->TakeLastBlob();
+                               IDBValue& wrapped_value) {
+  wrapped_value.SetData(std::move(wrapper_blob_content));
+  wrapped_value.TakeLastBlob();
 }
 
 // static
@@ -341,8 +338,8 @@
   if (!IDBValueUnwrapper::IsWrapped(value))
     return false;
 
-  const uint8_t* data = reinterpret_cast<const uint8_t*>(value->data_->data());
-  end_ = data + value->data_->size();
+  const uint8_t* data = reinterpret_cast<const uint8_t*>(value->Data().data());
+  end_ = data + value->DataSize();
   current_ = data + kHeaderSize;
 
   if (!ReadVarInt(blob_size_))
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.h b/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.h
index e1456250..8a9cd771 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.h
+++ b/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.h
@@ -231,11 +231,10 @@
   // True if at least one of the IDBValues' data was wrapped in a Blob.
   static bool IsWrapped(const Vector<std::unique_ptr<IDBValue>>&);
 
-  // Unwraps an IDBValue that has wrapped Blob data.
-  //
-  // The caller should own the IDBValue (have a std::unique_ptr for it).
+  // Unwraps an IDBValue that has wrapped Blob data, placing the result in
+  // `wrapped_value`.
   static void Unwrap(Vector<char>&& wrapper_blob_content,
-                     IDBValue* wrapped_value);
+                     IDBValue& wrapped_value);
 
   // Decompresses the value in `buffer` and stores in `out_buffer`. Returns true
   // on success.
diff --git a/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc b/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc
index 99b6749..5ca2acf 100644
--- a/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc
+++ b/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc
@@ -169,7 +169,7 @@
 base::span<const uint8_t>
 StructTraits<blink::mojom::IDBValueDataView, std::unique_ptr<blink::IDBValue>>::
     bits(const std::unique_ptr<blink::IDBValue>& input) {
-  return base::as_byte_span(*input->Data());
+  return base::as_byte_span(input->Data());
 }
 
 // static
@@ -221,7 +221,7 @@
   }
 
   if (value_bits.empty()) {
-    *out = std::make_unique<blink::IDBValue>(std::nullopt,
+    *out = std::make_unique<blink::IDBValue>(std::move(value_bits),
                                              Vector<blink::WebBlobInfo>());
     return true;
   }
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc
index 0730f9d..e958140a 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/ml/webnn/ml_graph.h"
 
+#include <array>
 #include <numeric>
 #include <optional>
 #include <utility>
@@ -21,6 +22,7 @@
 #include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "mojo/public/cpp/system/message_pipe.h"
+#include "services/webnn/public/cpp/operand_descriptor.h"
 #include "services/webnn/public/mojom/webnn_buffer.mojom-blink.h"
 #include "services/webnn/public/mojom/webnn_context_provider.mojom-blink.h"
 #include "services/webnn/public/mojom/webnn_graph.mojom-blink.h"
@@ -100,10 +102,10 @@
   Vector<T> values;
 };
 
-struct OperandInfoMojo {
-  blink_mojom::DataType data_type;
-  Vector<uint32_t> dimensions;
-};
+webnn::OperandDescriptor ToDescriptor(webnn::OperandDataType data_type,
+                                      base::span<const uint32_t> shape) {
+  return *webnn::OperandDescriptor::Create(data_type, shape);
+}
 
 template <typename T>
 T* V8ToObject(V8TestingScope* scope, ScriptValue value) {
@@ -1424,7 +1426,7 @@
 
 struct SoftmaxTester {
   OperandInfo<float> input;
-  OperandInfoMojo expected;
+  webnn::OperandDescriptor expected_descriptor;
 
   void Test(MLGraphTest& helper,
             V8TestingScope& scope,
@@ -1449,8 +1451,7 @@
     auto output_operand_iter =
         graph_info->id_to_operand_map.find(output_operand_id);
     ASSERT_TRUE(output_operand_iter != graph_info->id_to_operand_map.end());
-    EXPECT_EQ(output_operand_iter->value->data_type, expected.data_type);
-    EXPECT_EQ(output_operand_iter->value->dimensions, expected.dimensions);
+    EXPECT_EQ(output_operand_iter->value->descriptor, expected_descriptor);
   }
 };
 
@@ -1464,20 +1465,23 @@
   options->setDeviceType(V8MLDeviceType::Enum::kGpu);
   auto* builder = CreateGraphBuilder(scope, options);
   ASSERT_THAT(builder, testing::NotNull());
+
   {
     // Test building softmax with float32 input.
-    SoftmaxTester{.input = {.data_type = V8MLOperandDataType::Enum::kFloat32,
-                            .dimensions = {2, 4}},
-                  .expected = {.data_type = blink_mojom::DataType::kFloat32,
-                               .dimensions = {2, 4}}}
+    SoftmaxTester{
+        .input = {.data_type = V8MLOperandDataType::Enum::kFloat32,
+                  .dimensions = {2, 4}},
+        .expected_descriptor = ToDescriptor(webnn::OperandDataType::kFloat32,
+                                            std::array<uint32_t, 2>{2, 4})}
         .Test(*this, scope, builder);
   }
   {
     // Test building softmax with float16 input.
-    SoftmaxTester{.input = {.data_type = V8MLOperandDataType::Enum::kFloat16,
-                            .dimensions = {1, 5}},
-                  .expected = {.data_type = blink_mojom::DataType::kFloat16,
-                               .dimensions = {1, 5}}}
+    SoftmaxTester{
+        .input = {.data_type = V8MLOperandDataType::Enum::kFloat16,
+                  .dimensions = {1, 5}},
+        .expected_descriptor = ToDescriptor(webnn::OperandDataType::kFloat16,
+                                            std::array<uint32_t, 2>{1, 5})}
         .Test(*this, scope, builder);
   }
 }
@@ -1485,7 +1489,7 @@
 template <typename T>
 struct ConstantTester {
   OperandInfo<T> constant;
-  OperandInfoMojo expected;
+  webnn::OperandDescriptor expected_descriptor;
   Vector<T> expected_constant_data;
 
   void Test(MLGraphTest& helper,
@@ -1513,8 +1517,7 @@
       ASSERT_TRUE(constant_operand_iter != graph_info->id_to_operand_map.end());
       EXPECT_EQ(constant_operand_iter->value->kind,
                 blink_mojom::Operand::Kind::kConstant);
-      EXPECT_EQ(constant_operand_iter->value->data_type, expected.data_type);
-      EXPECT_EQ(constant_operand_iter->value->dimensions, expected.dimensions);
+      EXPECT_EQ(constant_operand_iter->value->descriptor, expected_descriptor);
       EXPECT_TRUE(constant_operand_iter->value->name.empty());
       // Verify the constant data in the mojo.
       const wtf_size_t constant_size =
@@ -1537,14 +1540,13 @@
   options->setDeviceType(V8MLDeviceType::Enum::kGpu);
   auto* builder = CreateGraphBuilder(scope, options);
   ASSERT_THAT(builder, testing::NotNull());
-  {
-    // Test scalar constant operand.
+  {  // Test scalar constant operand.
     ConstantTester<float>{
         .constant = {.data_type = V8MLOperandDataType::Enum::kFloat32,
                      .dimensions = {},
                      .values = {1.0}},
-        .expected = {.data_type = blink_mojom::DataType::kFloat32,
-                     .dimensions = {}},
+        .expected_descriptor = ToDescriptor(webnn::OperandDataType::kFloat32,
+                                            std::array<uint32_t, 0>{}),
         .expected_constant_data = {1.0}}
         .Test(*this, scope, builder);
   }
@@ -1554,8 +1556,8 @@
         .constant = {.data_type = V8MLOperandDataType::Enum::kFloat32,
                      .dimensions = {2, 3},
                      .values = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}},
-        .expected = {.data_type = blink_mojom::DataType::kFloat32,
-                     .dimensions = {2, 3}},
+        .expected_descriptor = ToDescriptor(webnn::OperandDataType::kFloat32,
+                                            std::array<uint32_t, 2>{2, 3}),
         .expected_constant_data = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}}
         .Test(*this, scope, builder);
   }
@@ -1565,8 +1567,8 @@
         .constant = {.data_type = V8MLOperandDataType::Enum::kFloat16,
                      .dimensions = {2, 3},
                      .values = {1, 2, 3, 4, 5, 6}},
-        .expected = {.data_type = blink_mojom::DataType::kFloat16,
-                     .dimensions = {2, 3}},
+        .expected_descriptor = ToDescriptor(webnn::OperandDataType::kFloat16,
+                                            std::array<uint32_t, 2>{2, 3}),
         .expected_constant_data = {1, 2, 3, 4, 5, 6}}
         .Test(*this, scope, builder);
   }
@@ -1576,8 +1578,8 @@
         .constant = {.data_type = V8MLOperandDataType::Enum::kInt32,
                      .dimensions = {2, 3},
                      .values = {1, 2, 3, 4, 5, 6}},
-        .expected = {.data_type = blink_mojom::DataType::kInt32,
-                     .dimensions = {2, 3}},
+        .expected_descriptor = ToDescriptor(webnn::OperandDataType::kInt32,
+                                            std::array<uint32_t, 2>{2, 3}),
         .expected_constant_data = {1, 2, 3, 4, 5, 6}}
         .Test(*this, scope, builder);
   }
@@ -1587,8 +1589,8 @@
         .constant = {.data_type = V8MLOperandDataType::Enum::kInt8,
                      .dimensions = {2, 3},
                      .values = {1, 2, 3, 4, 5, 6}},
-        .expected = {.data_type = blink_mojom::DataType::kInt8,
-                     .dimensions = {2, 3}},
+        .expected_descriptor = ToDescriptor(webnn::OperandDataType::kInt8,
+                                            std::array<uint32_t, 2>{2, 3}),
         .expected_constant_data = {1, 2, 3, 4, 5, 6}}
         .Test(*this, scope, builder);
   }
@@ -1597,7 +1599,7 @@
 struct CastTester {
   OperandInfo<float> input;
   V8MLOperandDataType::Enum output_data_type;
-  OperandInfoMojo expected_operand;
+  webnn::OperandDescriptor expected_descriptor;
 
   void Test(MLGraphTest& helper,
             V8TestingScope& scope,
@@ -1627,10 +1629,7 @@
     auto output_operand_iter =
         graph_info->id_to_operand_map.find(output_operand_id);
     ASSERT_TRUE(output_operand_iter != graph_info->id_to_operand_map.end());
-    EXPECT_EQ(output_operand_iter->value->data_type,
-              expected_operand.data_type);
-    EXPECT_EQ(output_operand_iter->value->dimensions,
-              expected_operand.dimensions);
+    EXPECT_EQ(output_operand_iter->value->descriptor, expected_descriptor);
   }
 };
 
@@ -1643,196 +1642,188 @@
   // Create WebNN Context with GPU device type.
   options->setDeviceType(V8MLDeviceType::Enum::kGpu);
   auto* builder = CreateGraphBuilder(scope, options);
+  const std::array<uint32_t, 2> shape{2, 2};
+  const Vector<uint32_t> wtf_shape(shape);
   {
     CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kFloat32,
-                         .dimensions = {2, 2}},
+                         .dimensions = wtf_shape},
                .output_data_type = V8MLOperandDataType::Enum::kInt32,
-               .expected_operand = {.data_type = blink_mojom::DataType::kInt32,
-                                    .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{
-        .input = {.data_type = V8MLOperandDataType::Enum::kFloat32,
-                  .dimensions = {2, 2}},
-        .output_data_type = V8MLOperandDataType::Enum::kFloat16,
-        .expected_operand = {.data_type = blink_mojom::DataType::kFloat16,
-                             .dimensions = {2, 2}}}
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kInt32, shape)}
         .Test(*this, scope, builder);
     CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kFloat32,
-                         .dimensions = {2, 2}},
-               .output_data_type = V8MLOperandDataType::Enum::kUint32,
-               .expected_operand = {.data_type = blink_mojom::DataType::kUint32,
-                                    .dimensions = {2, 2}}}
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kFloat16,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kFloat16, shape)}
         .Test(*this, scope, builder);
     CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kFloat32,
-                         .dimensions = {2, 2}},
-               .output_data_type = V8MLOperandDataType::Enum::kInt8,
-               .expected_operand = {.data_type = blink_mojom::DataType::kInt8,
-                                    .dimensions = {2, 2}}}
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kUint32,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kUint32, shape)}
         .Test(*this, scope, builder);
     CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kFloat32,
-                         .dimensions = {2, 2}},
-               .output_data_type = V8MLOperandDataType::Enum::kUint8,
-               .expected_operand = {.data_type = blink_mojom::DataType::kUint8,
-                                    .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{
-        .input = {.data_type = V8MLOperandDataType::Enum::kFloat16,
-                  .dimensions = {2, 2}},
-        .output_data_type = V8MLOperandDataType::Enum::kFloat32,
-        .expected_operand = {.data_type = blink_mojom::DataType::kFloat32,
-                             .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kFloat16,
-                         .dimensions = {2, 2}},
-               .output_data_type = V8MLOperandDataType::Enum::kInt32,
-               .expected_operand = {.data_type = blink_mojom::DataType::kInt32,
-                                    .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kFloat16,
-                         .dimensions = {2, 2}},
-               .output_data_type = V8MLOperandDataType::Enum::kUint32,
-               .expected_operand = {.data_type = blink_mojom::DataType::kUint32,
-                                    .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kFloat16,
-                         .dimensions = {2, 2}},
+                         .dimensions = wtf_shape},
                .output_data_type = V8MLOperandDataType::Enum::kInt8,
-               .expected_operand = {.data_type = blink_mojom::DataType::kInt8,
-                                    .dimensions = {2, 2}}}
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kInt8, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kFloat32,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kUint8,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kUint8, shape)}
         .Test(*this, scope, builder);
     CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kFloat16,
-                         .dimensions = {2, 2}},
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kFloat32,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kFloat32, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kFloat16,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kInt32,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kInt32, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kFloat16,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kUint32,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kUint32, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kFloat16,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kInt8,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kInt8, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kFloat16,
+                         .dimensions = wtf_shape},
                .output_data_type = V8MLOperandDataType::Enum::kUint8,
-               .expected_operand = {.data_type = blink_mojom::DataType::kUint8,
-                                    .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{
-        .input = {.data_type = V8MLOperandDataType::Enum::kInt32,
-                  .dimensions = {2, 2}},
-        .output_data_type = V8MLOperandDataType::Enum::kFloat32,
-        .expected_operand = {.data_type = blink_mojom::DataType::kFloat32,
-                             .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{
-        .input = {.data_type = V8MLOperandDataType::Enum::kInt32,
-                  .dimensions = {2, 2}},
-        .output_data_type = V8MLOperandDataType::Enum::kFloat16,
-        .expected_operand = {.data_type = blink_mojom::DataType::kFloat16,
-                             .dimensions = {2, 2}}}
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kUint8, shape)}
         .Test(*this, scope, builder);
     CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kInt32,
-                         .dimensions = {2, 2}},
-               .output_data_type = V8MLOperandDataType::Enum::kUint32,
-               .expected_operand = {.data_type = blink_mojom::DataType::kUint32,
-                                    .dimensions = {2, 2}}}
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kFloat32,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kFloat32, shape)}
         .Test(*this, scope, builder);
     CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kInt32,
-                         .dimensions = {2, 2}},
-               .output_data_type = V8MLOperandDataType::Enum::kInt8,
-               .expected_operand = {.data_type = blink_mojom::DataType::kInt8,
-                                    .dimensions = {2, 2}}}
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kFloat16,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kFloat16, shape)}
         .Test(*this, scope, builder);
     CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kInt32,
-                         .dimensions = {2, 2}},
-               .output_data_type = V8MLOperandDataType::Enum::kUint8,
-               .expected_operand = {.data_type = blink_mojom::DataType::kUint8,
-                                    .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{
-        .input = {.data_type = V8MLOperandDataType::Enum::kUint32,
-                  .dimensions = {2, 2}},
-        .output_data_type = V8MLOperandDataType::Enum::kFloat32,
-        .expected_operand = {.data_type = blink_mojom::DataType::kFloat32,
-                             .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{
-        .input = {.data_type = V8MLOperandDataType::Enum::kUint32,
-                  .dimensions = {2, 2}},
-        .output_data_type = V8MLOperandDataType::Enum::kFloat16,
-        .expected_operand = {.data_type = blink_mojom::DataType::kFloat16,
-                             .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kUint32,
-                         .dimensions = {2, 2}},
-               .output_data_type = V8MLOperandDataType::Enum::kInt32,
-               .expected_operand = {.data_type = blink_mojom::DataType::kInt32,
-                                    .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kUint32,
-                         .dimensions = {2, 2}},
-               .output_data_type = V8MLOperandDataType::Enum::kInt8,
-               .expected_operand = {.data_type = blink_mojom::DataType::kInt8,
-                                    .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kUint32,
-                         .dimensions = {2, 2}},
-               .output_data_type = V8MLOperandDataType::Enum::kUint8,
-               .expected_operand = {.data_type = blink_mojom::DataType::kUint8,
-                                    .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{
-        .input = {.data_type = V8MLOperandDataType::Enum::kInt8,
-                  .dimensions = {2, 2}},
-        .output_data_type = V8MLOperandDataType::Enum::kFloat32,
-        .expected_operand = {.data_type = blink_mojom::DataType::kFloat32,
-                             .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{
-        .input = {.data_type = V8MLOperandDataType::Enum::kInt8,
-                  .dimensions = {2, 2}},
-        .output_data_type = V8MLOperandDataType::Enum::kFloat16,
-        .expected_operand = {.data_type = blink_mojom::DataType::kFloat16,
-                             .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kInt8,
-                         .dimensions = {2, 2}},
+                         .dimensions = wtf_shape},
                .output_data_type = V8MLOperandDataType::Enum::kUint32,
-               .expected_operand = {.data_type = blink_mojom::DataType::kUint32,
-                                    .dimensions = {2, 2}}}
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kUint32, shape)}
         .Test(*this, scope, builder);
-    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kInt8,
-                         .dimensions = {2, 2}},
-               .output_data_type = V8MLOperandDataType::Enum::kUint8,
-               .expected_operand = {.data_type = blink_mojom::DataType::kUint8,
-                                    .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kInt8,
-                         .dimensions = {2, 2}},
-               .output_data_type = V8MLOperandDataType::Enum::kInt32,
-               .expected_operand = {.data_type = blink_mojom::DataType::kInt32,
-                                    .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{
-        .input = {.data_type = V8MLOperandDataType::Enum::kUint8,
-                  .dimensions = {2, 2}},
-        .output_data_type = V8MLOperandDataType::Enum::kFloat32,
-        .expected_operand = {.data_type = blink_mojom::DataType::kFloat32,
-                             .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{
-        .input = {.data_type = V8MLOperandDataType::Enum::kUint8,
-                  .dimensions = {2, 2}},
-        .output_data_type = V8MLOperandDataType::Enum::kFloat16,
-        .expected_operand = {.data_type = blink_mojom::DataType::kFloat16,
-                             .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kUint8,
-                         .dimensions = {2, 2}},
-               .output_data_type = V8MLOperandDataType::Enum::kInt32,
-               .expected_operand = {.data_type = blink_mojom::DataType::kInt32,
-                                    .dimensions = {2, 2}}}
-        .Test(*this, scope, builder);
-    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kUint8,
-                         .dimensions = {2, 2}},
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kInt32,
+                         .dimensions = wtf_shape},
                .output_data_type = V8MLOperandDataType::Enum::kInt8,
-               .expected_operand = {.data_type = blink_mojom::DataType::kInt8,
-                                    .dimensions = {2, 2}}}
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kInt8, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kInt32,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kUint8,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kUint8, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kUint32,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kFloat32,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kFloat32, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kUint32,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kFloat16,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kFloat16, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kUint32,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kInt32,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kInt32, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kUint32,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kInt8,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kInt8, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kUint32,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kUint8,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kUint8, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kInt8,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kFloat32,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kFloat32, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kInt8,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kFloat16,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kFloat16, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kInt8,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kUint32,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kUint32, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kInt8,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kUint8,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kUint8, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kInt8,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kInt32,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kInt32, shape)}
         .Test(*this, scope, builder);
     CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kUint8,
-                         .dimensions = {2, 2}},
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kFloat32,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kFloat32, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kUint8,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kFloat16,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kFloat16, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kUint8,
+                         .dimensions = wtf_shape},
                .output_data_type = V8MLOperandDataType::Enum::kInt32,
-               .expected_operand = {.data_type = blink_mojom::DataType::kInt32,
-                                    .dimensions = {2, 2}}}
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kInt32, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kUint8,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kInt8,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kInt8, shape)}
+        .Test(*this, scope, builder);
+    CastTester{.input = {.data_type = V8MLOperandDataType::Enum::kUint8,
+                         .dimensions = wtf_shape},
+               .output_data_type = V8MLOperandDataType::Enum::kInt32,
+               .expected_descriptor =
+                   ToDescriptor(webnn::OperandDataType::kInt32, shape)}
         .Test(*this, scope, builder);
   }
 }
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.cc
index d043423a..e040922 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.cc
@@ -5,11 +5,13 @@
 #include "third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.h"
 
 #include <array>
+#include <optional>
 
 #include "base/notreached.h"
 #include "base/ranges/algorithm.h"
 #include "base/types/expected_macros.h"
 #include "services/webnn/public/cpp/graph_validation_utils.h"
+#include "services/webnn/public/cpp/operand_descriptor.h"
 #include "services/webnn/public/mojom/webnn_graph.mojom-blink-forward.h"
 #include "services/webnn/public/mojom/webnn_graph.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_arg_min_max_options.h"
@@ -46,27 +48,26 @@
 
 namespace mojo {
 
-blink_mojom::DataType BlinkDataTypeToMojo(
+webnn::OperandDataType ToOperandDataType(
     blink::V8MLOperandDataType::Enum data_type) {
   switch (data_type) {
     case blink::V8MLOperandDataType::Enum::kFloat32:
-      return blink_mojom::DataType::kFloat32;
+      return webnn::OperandDataType::kFloat32;
     case blink::V8MLOperandDataType::Enum::kFloat16:
-      return blink_mojom::DataType::kFloat16;
+      return webnn::OperandDataType::kFloat16;
     case blink::V8MLOperandDataType::Enum::kInt32:
-      return blink_mojom::DataType::kInt32;
+      return webnn::OperandDataType::kInt32;
     case blink::V8MLOperandDataType::Enum::kUint32:
-      return blink_mojom::DataType::kUint32;
+      return webnn::OperandDataType::kUint32;
     case blink::V8MLOperandDataType::Enum::kInt64:
-      return blink_mojom::DataType::kInt64;
+      return webnn::OperandDataType::kInt64;
     case blink::V8MLOperandDataType::Enum::kUint64:
-      return blink_mojom::DataType::kUint64;
+      return webnn::OperandDataType::kUint64;
     case blink::V8MLOperandDataType::Enum::kInt8:
-      return blink_mojom::DataType::kInt8;
+      return webnn::OperandDataType::kInt8;
     case blink::V8MLOperandDataType::Enum::kUint8:
-      return blink_mojom::DataType::kUint8;
+      return webnn::OperandDataType::kUint8;
   }
-  NOTREACHED_NORETURN();
 }
 
 blink_mojom::RecurrentNetworkDirection BlinkRecurrentNetworkDirectionToMojo(
@@ -108,7 +109,18 @@
   if (!ml_operand) {
     return nullptr;
   }
+  auto operand_descriptor = webnn::OperandDescriptor::Create(
+      ToOperandDataType(ml_operand->DataType()), ml_operand->Dimensions());
+  // TODO(crbug.com/325598628): Remove this failure case once we've required
+  // that that every `blink::MLOperand` is created with a
+  // `webnn::OperandDescriptor`.
+  if (!operand_descriptor.has_value()) {
+    return nullptr;
+  }
+
   auto mojo_operand = blink_mojom::Operand::New();
+  mojo_operand->descriptor = *std::move(operand_descriptor);
+
   switch (ml_operand->Kind()) {
     case webnn::mojom::blink::Operand::Kind::kInput:
       mojo_operand->kind = blink_mojom::Operand::Kind::kInput;
@@ -121,8 +133,6 @@
       mojo_operand->kind = blink_mojom::Operand::Kind::kOutput;
       break;
   }
-  mojo_operand->data_type = BlinkDataTypeToMojo(ml_operand->DataType());
-  mojo_operand->dimensions = ml_operand->Dimensions();
   return mojo_operand;
 }
 
@@ -189,10 +199,18 @@
                                 base::span<const uint32_t> dimensions,
                                 blink_mojom::GraphInfo* graph_info) {
   uint64_t operand_id = NextOperandId(*graph_info);
+
+  auto operand_descriptor = webnn::OperandDescriptor::Create(
+      mojo::ToOperandDataType(data_type.AsEnum()), dimensions);
+  // TODO(crbug.com/325598628): Refactor this method to take a
+  // `webnn::OperandDescriptor` such that this CHECK is not required and
+  // inserting a temporary operand will always succeed.
+  CHECK(operand_descriptor.has_value());
+
   auto mojo_operand = blink_mojom::Operand::New();
   mojo_operand->kind = blink_mojom::Operand::Kind::kOutput;
-  mojo_operand->data_type = mojo::BlinkDataTypeToMojo(data_type.AsEnum());
-  mojo_operand->dimensions = Vector<uint32_t>(dimensions);
+  mojo_operand->descriptor = *std::move(operand_descriptor);
+
   graph_info->id_to_operand_map.insert(operand_id, std::move(mojo_operand));
   return operand_id;
 }
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.h
index 18f102e..678fe09 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.h
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.h
@@ -38,9 +38,6 @@
       const blink::MLOperand* ml_operand);
 };
 
-MODULES_EXPORT webnn::mojom::blink::DataType BlinkOperandTypeToMojo(
-    blink::V8MLOperandDataType::Enum data_type);
-
 }  // namespace mojo
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_ML_WEBNN_ML_GRAPH_TYPE_CONVERTER_H_
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_operand.h b/third_party/blink/renderer/modules/ml/webnn/ml_operand.h
index 1c3e4f18..693d5a6 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_operand.h
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_operand.h
@@ -32,6 +32,8 @@
   // Represents an MLOperandDescriptor whose characteristics have already been
   // validated according to the steps specified in
   // https://www.w3.org/TR/webnn/#mloperanddescriptor-check-dimensions.
+  //
+  // TODO(crbug.com/325598628): Replace this with `webnn::OperandDescriptor`.
   class ValidatedDescriptor {
    public:
     // Creates a ValidatedDescriptor or returns an error message which may be
diff --git a/third_party/blink/renderer/platform/fonts/web_font_typeface_factory_test.cc b/third_party/blink/renderer/platform/fonts/web_font_typeface_factory_test.cc
index f8de603a..c291301 100644
--- a/third_party/blink/renderer/platform/fonts/web_font_typeface_factory_test.cc
+++ b/third_party/blink/renderer/platform/fonts/web_font_typeface_factory_test.cc
@@ -66,6 +66,8 @@
 }
 
 TEST(WebFontTypefaceFactoryTest, ColrV1AlwaysFallback) {
+  ScopedFontationsForSelectedFormatsForTest scoped_fontations_selected_formats(
+      false);
   sk_sp<SkData> data = SkData::MakeEmpty();
   MockFontFormatCheck mock_font_format_check(data);
   EXPECT_CALL(mock_font_format_check, IsColrCpalColorFontV1())
@@ -97,6 +99,8 @@
 }
 
 TEST(WebFontTypefaceFactoryTest, Cff2AlwaysFallback) {
+  ScopedFontationsForSelectedFormatsForTest scoped_fontations_selected_formats(
+      false);
   sk_sp<SkData> data = SkData::MakeEmpty();
   MockFontFormatCheck mock_font_format_check(data);
   EXPECT_CALL(mock_font_format_check, IsCff2OutlineFont())
@@ -128,6 +132,8 @@
 }
 
 TEST(WebFontTypefaceFactoryTest, CbdtCblcAlwaysFallback) {
+  ScopedFontationsForSelectedFormatsForTest scoped_fontations_selected_formats(
+      false);
   sk_sp<SkData> data = SkData::MakeEmpty();
   MockFontFormatCheck mock_font_format_check(data);
   EXPECT_CALL(mock_font_format_check, IsCbdtCblcColorFont())
@@ -159,6 +165,8 @@
 }
 
 TEST(WebFontTypefaceFactoryTest, ColrV0FallbackApple) {
+  ScopedFontationsForSelectedFormatsForTest scoped_fontations_selected_formats(
+      false);
   sk_sp<SkData> data = SkData::MakeEmpty();
   MockFontFormatCheck mock_font_format_check(data);
   EXPECT_CALL(mock_font_format_check, IsColrCpalColorFontV0())
@@ -176,6 +184,8 @@
 }
 
 TEST(WebFontTypefaceFactoryTest, VariableColrV0FallbackWindowsApple) {
+  ScopedFontationsForSelectedFormatsForTest scoped_fontations_selected_formats(
+      false);
   sk_sp<SkData> data = SkData::MakeEmpty();
   MockFontFormatCheck mock_font_format_check(data);
   EXPECT_CALL(mock_font_format_check, IsColrCpalColorFontV0())
@@ -256,6 +266,8 @@
 #define MAYBE_SbixFallbackWindows SbixFallbackWindows
 #endif
 TEST(WebFontTypefaceFactoryTest, MAYBE_SbixFallbackWindows) {
+  ScopedFontationsForSelectedFormatsForTest scoped_fontations_selected_formats(
+      false);
   sk_sp<SkData> data = SkData::MakeEmpty();
   MockFontFormatCheck mock_font_format_check(data);
   EXPECT_CALL(mock_font_format_check, IsSbixColorFont())
@@ -301,6 +313,8 @@
 #define MAYBE_VariationsWinFallbackIfNeeded VariationsWinFallbackIfNeeded
 #endif
 TEST(WebFontTypefaceFactoryTest, MAYBE_VariationsWinFallbackIfNeeded) {
+  ScopedFontationsForSelectedFormatsForTest scoped_fontations_selected_formats(
+      false);
   sk_sp<SkData> data = SkData::MakeEmpty();
   MockFontFormatCheck mock_font_format_check(data);
   EXPECT_CALL(mock_font_format_check, IsVariableFont())
diff --git a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
index 26478c8..7f309e2 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
@@ -64,11 +64,6 @@
 
 }  // namespace
 
-// static
-bool Canvas2DLayerBridge::IsHibernationEnabled() {
-  return base::FeatureList::IsEnabled(features::kCanvas2DHibernation);
-}
-
 Canvas2DLayerBridge::Canvas2DLayerBridge()
     : logger_(std::make_unique<Logger>()),
       snapshot_state_(kInitialSnapshotState),
@@ -272,7 +267,7 @@
     }
   }
 
-  if (IsHibernationEnabled() && ResourceProvider() &&
+  if (features::IsCanvas2DHibernationEnabled() && ResourceProvider() &&
       resource_host_->GetRasterMode() == RasterMode::kGPU && !page_is_visible &&
       !hibernation_scheduled_) {
     resource_host_->ClearLayerTexture();
diff --git a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h
index 251b1b4e..2447f90 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h
+++ b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h
@@ -103,8 +103,6 @@
   CanvasResourceProvider* GetOrCreateResourceProvider();
   void FlushRecording(FlushReason);
 
-  static bool IsHibernationEnabled();
-
   CanvasHibernationHandler& GetHibernationHandlerForTesting() {
     return hibernation_handler_;
   }
diff --git a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
index 02e2ae0b..eb782f8 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge_test.cc
@@ -420,8 +420,9 @@
 };
 
 TEST_F(Canvas2DLayerBridgeTest, HibernationLifeCycle) {
-  if (!Canvas2DLayerBridge::IsHibernationEnabled())
+  if (!features::IsCanvas2DHibernationEnabled()) {
     GTEST_SKIP();
+  }
 
   ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
   std::unique_ptr<Canvas2DLayerBridge> bridge =
@@ -472,8 +473,9 @@
 }
 
 TEST_F(Canvas2DLayerBridgeTest, HibernationReEntry) {
-  if (!Canvas2DLayerBridge::IsHibernationEnabled())
+  if (!features::IsCanvas2DHibernationEnabled()) {
     GTEST_SKIP();
+  }
 
   ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
   std::unique_ptr<Canvas2DLayerBridge> bridge =
@@ -534,8 +536,9 @@
 }
 
 TEST_F(Canvas2DLayerBridgeTest, TeardownWhileHibernating) {
-  if (!Canvas2DLayerBridge::IsHibernationEnabled())
+  if (!features::IsCanvas2DHibernationEnabled()) {
     GTEST_SKIP();
+  }
 
   ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
   std::unique_ptr<Canvas2DLayerBridge> bridge =
@@ -575,8 +578,9 @@
 }
 
 TEST_F(Canvas2DLayerBridgeTest, SnapshotWhileHibernating) {
-  if (!Canvas2DLayerBridge::IsHibernationEnabled())
+  if (!features::IsCanvas2DHibernationEnabled()) {
     GTEST_SKIP();
+  }
 
   ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
   std::unique_ptr<Canvas2DLayerBridge> bridge =
@@ -630,8 +634,9 @@
 }
 
 TEST_F(Canvas2DLayerBridgeTest, TeardownWhileHibernationIsPending) {
-  if (!Canvas2DLayerBridge::IsHibernationEnabled())
+  if (!features::IsCanvas2DHibernationEnabled()) {
     GTEST_SKIP();
+  }
 
   ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
   std::unique_ptr<Canvas2DLayerBridge> bridge =
@@ -666,8 +671,9 @@
 }
 
 TEST_F(Canvas2DLayerBridgeTest, HibernationAbortedDueToVisibilityChange) {
-  if (!Canvas2DLayerBridge::IsHibernationEnabled())
+  if (!features::IsCanvas2DHibernationEnabled()) {
     GTEST_SKIP();
+  }
 
   ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
   std::unique_ptr<Canvas2DLayerBridge> bridge =
@@ -709,8 +715,9 @@
 }
 
 TEST_F(Canvas2DLayerBridgeTest, HibernationAbortedDueToLostContext) {
-  if (!Canvas2DLayerBridge::IsHibernationEnabled())
+  if (!features::IsCanvas2DHibernationEnabled()) {
     GTEST_SKIP();
+  }
 
   ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
   std::unique_ptr<Canvas2DLayerBridge> bridge =
@@ -747,8 +754,9 @@
 }
 
 TEST_F(Canvas2DLayerBridgeTest, PrepareMailboxWhileHibernating) {
-  if (!Canvas2DLayerBridge::IsHibernationEnabled())
+  if (!features::IsCanvas2DHibernationEnabled()) {
     GTEST_SKIP();
+  }
 
   ScopedTestingPlatformSupport<GpuMemoryBufferTestPlatform> platform;
   std::unique_ptr<Canvas2DLayerBridge> bridge =
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index aff643d..a853f109 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1884,6 +1884,7 @@
     },
     {
       name: "FontationsForSelectedFormats",
+      status: "stable",
     },
     {
       name: "FontFamilyPostscriptMatchingCTMigration",
@@ -2605,6 +2606,10 @@
       name: "MultiSelectDeselectWhenOnlyOption",
       status: "test",
     },
+    {
+      name: "MultiSmoothScrollIntoView",
+      status: "test",
+    },
     // crbug.com/1446498: This feature is being used for the deprecation of
     // Mutation Events.
     {
diff --git a/third_party/blink/tools/blinkpy/common/config/builders.json b/third_party/blink/tools/blinkpy/common/config/builders.json
index 0f1cb80..6eececf 100644
--- a/third_party/blink/tools/blinkpy/common/config/builders.json
+++ b/third_party/blink/tools/blinkpy/common/config/builders.json
@@ -261,8 +261,8 @@
     },
     "mac-rel": {
         "main": "tryserver.chromium.mac",
-        "port_name": "mac-mac13",
-        "specifiers": ["Mac13", "Release"],
+        "port_name": "mac-mac14",
+        "specifiers": ["Mac14", "Release"],
         "steps": {
             "blink_web_tests": {},
             "blink_wpt_tests": {}
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index e3e170598..1065e2bc 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -2574,6 +2574,8 @@
 crbug.com/347045480 external/wpt/webrtc/RTCRtpReceiver-audio-jitterBufferTarget-stats.https.html [ Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/347055263 external/wpt/css/css-ui/transparent-accent-color-001.html [ Failure ]
+crbug.com/347055263 external/wpt/css/css-ui/transparent-accent-color-002.html [ Failure ]
 crbug.com/347071485 external/wpt/css/css-overflow/line-clamp/line-clamp-001.html [ Failure ]
 crbug.com/347071485 external/wpt/css/css-overflow/line-clamp/line-clamp-004.html [ Failure ]
 crbug.com/347071485 external/wpt/css/css-overflow/line-clamp/line-clamp-010.html [ Failure ]
@@ -3116,9 +3118,12 @@
 crbug.com/331556923 external/wpt/geolocation-API/enabled-by-permissions-policy.https.sub.html [ Timeout ]
 crbug.com/331556923 external/wpt/geolocation-API/enabled-on-self-origin-by-permissions-policy.https.sub.html [ Timeout ]
 crbug.com/626703 [ Linux ] external/wpt/webxr/ar-module/xrSession_interactionMode.https.html [ Timeout ]
+crbug.com/626703 [ Mac12 ] external/wpt/webxr/ar-module/xrSession_interactionMode.https.html [ Timeout ]
 crbug.com/626703 [ Linux ] external/wpt/webxr/dom-overlay/ar_dom_overlay.https.html [ Timeout ]
+crbug.com/626703 [ Mac12 ] external/wpt/webxr/dom-overlay/ar_dom_overlay.https.html [ Timeout ]
 crbug.com/626703 [ Linux ] external/wpt/webxr/hit-test/ar_hittest_source_cancel.https.html [ Timeout ]
 crbug.com/626703 [ Linux ] external/wpt/webxr/render_state_update.https.html [ Timeout ]
+crbug.com/626703 [ Mac12 ] external/wpt/webxr/render_state_update.https.html [ Timeout ]
 crbug.com/626703 [ Linux ] external/wpt/webxr/xrSession_requestReferenceSpace_features.https.html [ Timeout ]
 crbug.com/626703 [ Linux ] external/wpt/webxr/xr_viewport_scale.https.html [ Timeout ]
 crbug.com/626703 [ Linux Release ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices-per-origin-ids.sub.https.html [ Timeout ]
@@ -5711,7 +5716,6 @@
 crbug.com/1462683 [ Mac11-arm64 ] virtual/threaded/external/wpt/long-animation-frame/tentative/loaf-iframe-self.html [ Skip Timeout ]
 
 crbug.com/1455262 virtual/threaded/external/wpt/soft-navigation-heuristics/navigation-api-view-transition.tentative.html [ Crash Failure Pass Skip ]
-crbug.com/1521474 external/wpt/intersection-observer/callback-cross-realm-report-exception.html [ Failure ]
 crbug.com/324293120 [ Debug Linux ] external/wpt/webstorage/event_case_sensitive.html [ Failure Pass ]
 
 crbug.com/324536287 external/wpt/soft-navigation-heuristics/interaction-with-paint-before-back.tentative.html [ Failure Pass ]
@@ -7528,8 +7532,8 @@
 # Gardener 2024-05-13
 crbug.com/339835801 [ Win ] fast/forms/select-popup/popup-menu-appearance-tall.html [ Failure Pass ]
 
-# Gardener 2024-05-15
-crbug.com/340774350 [ Win ] external/wpt/uievents/mouse/mouse_boundary_events_after_reappending_last_over_target.tentative.html [ Failure Pass ]
+# Flaky on multiple builds.
+crbug.com/340651310 external/wpt/uievents/mouse/mouse_boundary_events_after_reappending_last_over_target.tentative.html [ Failure Pass ]
 
 # Gardener 2024-05-15
 b/40270061 http/tests/inspector-protocol/tracing/runtime-stats.js [ Crash Failure Pass Timeout ]
@@ -7579,9 +7583,9 @@
 crbug.com/346387874 [ Win11 ] fast/backgrounds/size/contain-and-cover.html [ Failure ]
 
 # Gardener 2024-06-12
-crbug.com/346706682 [ Mac ] http/tests/devtools/indexeddb/resources-panel.js [ Failure ]
+crbug.com/346706682 http/tests/devtools/indexeddb/resources-panel.js [ Failure Pass ]
 
 crbug.com/40899458 [ Mac14 ] fast/canvas/OffscreenCanvas-copyImage.html [ Failure Pass ]
 
-crbug.com/346794458 [ Mac ] external/wpt/feature-policy/feature-policy-frame-policy-timing.https.sub.html [ Failure Pass ]
-crbug.com/346794458 [ Mac ] external/wpt/permissions-policy/permissions-policy-frame-policy-timing.https.sub.html [ Failure Pass ]
+crbug.com/342438266 external/wpt/feature-policy/feature-policy-frame-policy-timing.https.sub.html [ Failure Pass ]
+crbug.com/342438266 external/wpt/permissions-policy/permissions-policy-frame-policy-timing.https.sub.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index 835e8e5..1e646f7 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -29,8 +29,7 @@
     "bases": ["external/wpt/fetch/private-network-access"],
     "args": [
       "--enable-features=PrivateNetworkAccessPermissionPrompt",
-      "--enable-blink-features=PrivateNetworkAccessPermissionPrompt",
-      "--disable-threaded-compositing", "--disable-threaded-animation"],
+      "--enable-blink-features=PrivateNetworkAccessPermissionPrompt"],
     "owners": ["phao@google.com", "lyf@google.com"],
     "expires": "Jul 1, 2024"
   },
@@ -38,8 +37,7 @@
     "prefix": "pna-workers-disabled",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/fetch/private-network-access"],
-    "args": ["--disable-features=PrivateNetworkAccessForWorkers",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--disable-features=PrivateNetworkAccessForWorkers"],
     "owners": ["phao@google.com", "lyf@google.com"],
     "expires": "Jul 1, 2024"
   },
@@ -49,8 +47,7 @@
     "bases": ["external/wpt/fetch/private-network-access"],
     "args": [
       "--enable-features=PrivateNetworkAccessForWorkers",
-      "--disable-features=PrivateNetworkAccessForWorkersWarningOnly",
-      "--disable-threaded-compositing", "--disable-threaded-animation"],
+      "--disable-features=PrivateNetworkAccessForWorkersWarningOnly"],
     "owners": ["phao@google.com", "lyf@google.com"],
     "expires": "Jul 1, 2024"
   },
@@ -67,8 +64,7 @@
     "prefix": "pna-navigations-enabled",
     "platforms": ["Linux", "Mac", "win"],
     "bases": ["external/wpt/fetch/private-network-access"],
-    "args": ["--enable-features=PrivateNetworkAccessForNavigations",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=PrivateNetworkAccessForNavigations"],
     "owners": ["phao@google.com", "lyf@google.com"],
     "expires": "Jul 1, 2024"
   },
@@ -76,8 +72,7 @@
     "prefix": "pna-navigations-warning",
     "platforms": ["Linux", "Mac", "win"],
     "bases": ["external/wpt/fetch/private-network-access"],
-    "args": ["--enable-features=PrivateNetworkAccessForNavigations,PrivateNetworkAccessForNavigationsWarningOnly",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=PrivateNetworkAccessForNavigations,PrivateNetworkAccessForNavigationsWarningOnly"],
     "owners": ["phao@google.com", "lyf@google.com"],
     "expires": "Jul 1, 2024"
   },
@@ -87,8 +82,7 @@
     "bases": [ "fast/canvas",
                "external/wpt/mediacapture-record/MediaRecorder-canvas-media-source.https.html",
                "external/wpt/webmessaging/postMessage_cross_domain_image_transfer_2d.sub.htm" ],
-    "args": ["--enable-accelerated-2d-canvas",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-accelerated-2d-canvas"],
     "expires": "Jul 1, 2023"
   },
 
@@ -168,8 +162,7 @@
               "http/tests/intersection-observer",
               "intersection-observer",
               "wpt_internal/display-lock"],
-    "args": ["--disable-features=IntersectionOptimization",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--disable-features=IntersectionOptimization"],
     "owners": ["wangxianzhu@chromium.org"],
     "expires": "Jul 30, 2024"
   },
@@ -187,8 +180,7 @@
     "prefix": "attribution-reporting-in-browser-migration",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["http/tests/inspector-protocol/attribution-reporting"],
-    "args": ["--enable-features=KeepAliveInBrowserMigration,AttributionReportingInBrowserMigration",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=KeepAliveInBrowserMigration,AttributionReportingInBrowserMigration"],
     "owners": ["anthonygarant@chromium.org"],
     "expires": "Jan 2, 2025"
   },
@@ -199,8 +191,7 @@
     "exclusive_tests": "ALL",
     "args": ["--attribution-reporting-debug-mode",
              "--enable-features=AttributionReportingReportVerification,AggregationServiceMultipleCloudProviders:allowlist/https%3A%2F%2Fweb-platform%2Etest%3A8444%2Chttps%3A%2F%2Fwww1%2Eweb-platform%2Etest%3A8444",
-             "--additional-private-state-token-key-commitments={\"https://web-platform.test:8444\":{\"PrivateStateTokenV3VOPRF\":{\"protocol_version\":\"PrivateStateTokenV3VOPRF\",\"id\":1,\"batchsize\":1,\"keys\":{\"0\":{\"Y\":\"AAAAAASqh8oivosFN46xxx7zIK10bh07Younm5hZ90HgglQqOFUC8l2/VSlsOlReOHJ2CrfJ6CG1adnTkKJhZ0BtbSPWBwviQtdl64MWJc7sSg9HPvWfTjDigX5ihbzihG8V8aA=\",\"expiry\":\"253402300799000000\"}}}}}",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--additional-private-state-token-key-commitments={\"https://web-platform.test:8444\":{\"PrivateStateTokenV3VOPRF\":{\"protocol_version\":\"PrivateStateTokenV3VOPRF\",\"id\":1,\"batchsize\":1,\"keys\":{\"0\":{\"Y\":\"AAAAAASqh8oivosFN46xxx7zIK10bh07Younm5hZ90HgglQqOFUC8l2/VSlsOlReOHJ2CrfJ6CG1adnTkKJhZ0BtbSPWBwviQtdl64MWJc7sSg9HPvWfTjDigX5ihbzihG8V8aA=\",\"expiry\":\"253402300799000000\"}}}}}"],
     "expires": "Jan 2, 2025"
   },
   {
@@ -208,8 +199,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/attribution-reporting/aggregatable-debug"],
     "exclusive_tests": "ALL",
-    "args": ["--enable-features=AttributionAggregatableDebugReporting",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=AttributionAggregatableDebugReporting"],
     "owners": ["linnan@chromium.org"],
     "expires": "Dec 3, 2024"
   },
@@ -236,8 +226,7 @@
     "bases": ["compositing/overflow",
               "compositing/squashing/keep-lcd-text.html",
               "scrollbars"],
-    "args": ["--enable-prefer-compositing-to-lcd-text",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-prefer-compositing-to-lcd-text"],
     "owners": ["paint-dev@chromium.org"],
     "expires": "never"
   },
@@ -274,8 +263,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["images",
               "external/wpt/css/css-images/gradient"],
-    "args": ["--enable-gpu-rasterization",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-gpu-rasterization"],
     "expires": "Jul 1, 2023"
   },
   {
@@ -283,8 +271,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["images"],
     "args": ["--force-color-profile=srgb",
-             "--force-raster-color-profile=color-spin-gamma24",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--force-raster-color-profile=color-spin-gamma24"],
     "expires": "Jul 1, 2023"
   },
   "The stable suite tests for conformance to HTML/web specifications, and",
@@ -309,8 +296,7 @@
     "exclusive_tests": ["media/stable"],
     "args": ["--stable-release-mode",
              "--disable-auto-wpt-origin-isolation",
-             "--disable-field-trial-config",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--disable-field-trial-config"],
     "expires": "never"
   },
   {
@@ -319,8 +305,7 @@
     "bases": ["external/wpt/mediacapture-streams"],
     "exclusive_tests": ["external/wpt/mediacapture-streams/MediaStream-default-feature-policy.https.html"],
     "args": ["--use-fake-device-for-media-stream",
-             "--use-fake-ui-for-media-stream",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--use-fake-ui-for-media-stream"],
     "expires": "Jul 1, 2023"
   },
   "The origin trials suite tests that OT-controlled features are exposed to",
@@ -330,8 +315,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["http/tests/origin_trials/webexposed"],
     "args": ["--disable-origin-trial-controlled-blink-features",
-             "--stable-release-mode",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--stable-release-mode"],
     "expires": "never"
   },
   "This suite tests some android features on Linux and should never expire.",
@@ -357,8 +341,7 @@
     "bases": ["external/wpt/media-source",
               "media"],
     "args": ["--use-gpu-in-tests",
-             "--enable-features=MediaFoundationClearPlayback,MediaFoundationClearRendering:strategy/direct-composition",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--enable-features=MediaFoundationClearPlayback,MediaFoundationClearRendering:strategy/direct-composition"],
     "expires": "Dec 1, 2024"
   },
   {
@@ -368,8 +351,7 @@
               "media"],
     "args": ["--use-gpu-in-tests",
              "--force-mfmediaengine-renderer",
-             "--enable-features=MediaFoundationClearRendering:strategy/frame-server",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--enable-features=MediaFoundationClearRendering:strategy/frame-server"],
     "expires": "Dec 1, 2024"
   },
   {
@@ -377,8 +359,7 @@
     "platforms": ["Linux", "Mac", "Win", "Fuchsia"],
     "bases": ["external/wpt/media-source",
               "media"],
-    "args": ["--use-gpu-in-tests",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--use-gpu-in-tests"],
     "expires": "Dec 1, 2024"
   },
   {
@@ -389,8 +370,7 @@
               "fast/workers/worker-sharedarraybuffer-transfer.html",
               "fast/workers/chromium/worker-sharedarraybuffer-transfer-two-workers.html",
               "http/tests/inspector-protocol/issues"],
-    "args": ["--enable-features=SharedArrayBuffer",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=SharedArrayBuffer"],
     "expires": "Jul 1, 2025"
   },
   {
@@ -399,8 +379,7 @@
     "bases": ["http/tests/media/media-source/stream_memory_tests"],
     "exclusive_tests": ["http/tests/media/media-source/stream_memory_tests/mediasource-appendbuffer-quota-exceeded-1mb-buffers.html"],
     "args": ["--mse-audio-buffer-size-limit-mb=1",
-             "--mse-video-buffer-size-limit-mb=1",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--mse-video-buffer-size-limit-mb=1"],
     "expires": "Jul 1, 2023"
   },
   {
@@ -429,8 +408,7 @@
               "paint/invalidation/svg/invalid-clip-path-crash.html",
               "transitions/webkit-clip-path-equality.html"],
     "exclusive_tests": "ALL",
-    "args": ["--disable-blink-features=CompositeClipPathAnimation",
-              "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--disable-blink-features=CompositeClipPathAnimation"],
     "owners": ["clchambers@microsoft.com", "gerchiko@microsoft.com"],
     "expires": "Jan 1, 2025"
   },
@@ -440,8 +418,7 @@
     "bases": ["external/wpt/css/css-position/sticky/",
               "external/wpt/css/css-viewport/zoom/scroll-top-test-with-zoom.html",
               "fast/scrolling/"],
-    "args": ["--enable-blink-features=FractionalScrollOffsets",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-blink-features=FractionalScrollOffsets"],
     "expires": "Jun 1, 2025"
   },
   {
@@ -469,8 +446,7 @@
               "http/tests/csspaint/hidpi",
               "http/tests/inspector-protocol/page/page-captureScreenshot-clip-emulation.js"],
     "exclusive_tests": ["fast/hidpi/static"],
-    "args": ["--force-device-scale-factor=2",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--force-device-scale-factor=2"],
     "owners": ["paint-dev@chromium.org"],
     "expires": "never"
   },
@@ -481,8 +457,7 @@
               "fast/events/wheel/wheelevent-in-scrolling-div.html",
               "fast/hidpi/static"],
     "exclusive_tests": ["fast/hidpi/static"],
-    "args": ["--force-device-scale-factor=1.5",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--force-device-scale-factor=1.5"],
     "owners": ["paint-dev@chromium.org"],
     "expires": "never"
   },
@@ -491,8 +466,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["dark-mode/images"],
     "args": ["--blink-settings=preferredColorScheme=0,forceDarkModeEnabled=true",
-             "--dark-mode-settings=ImageClassifierPolicy=1",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--dark-mode-settings=ImageClassifierPolicy=1"],
     "expires": "Jul 1, 2025"
   },
   {
@@ -500,8 +474,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["dark-mode/colors",
               "dark-mode/images"],
-    "args": ["--blink-settings=preferredColorScheme=0,forceDarkModeEnabled=true",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--blink-settings=preferredColorScheme=0,forceDarkModeEnabled=true"],
     "expires": "Jul 1, 2025"
   },
   {
@@ -509,8 +482,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["dark-mode/images"],
     "args": ["--blink-settings=preferredColorScheme=0,forceDarkModeEnabled=true",
-             "--dark-mode-settings=ImagePolicy=0",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--dark-mode-settings=ImagePolicy=0"],
     "expires": "Jul 1, 2025"
   },
   {
@@ -518,24 +490,21 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["dark-mode/images"],
     "args": ["--blink-settings=preferredColorScheme=0,forceDarkModeEnabled=true",
-             "--dark-mode-settings=ImagePolicy=1",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--dark-mode-settings=ImagePolicy=1"],
     "expires": "Jul 1, 2025"
   },
   {
     "prefix": "presentation",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": [],
-    "args": ["--force-presentation-receiver-for-testing",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--force-presentation-receiver-for-testing"],
     "expires": "Oct 1, 2025"
   },
   {
     "prefix": "single-renderer-process",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/longtask-timing/shared-renderer"],
-    "args": ["--renderer-process-limit=1",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--renderer-process-limit=1"],
     "expires": "Jul 1, 2024"
   },
   {
@@ -543,8 +512,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["fast/events/wheel",
               "fast/scrolling"],
-    "args": ["--enable-features=WindowsScrollingPersonality",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=WindowsScrollingPersonality"],
     "owners": ["gerchiko@microsoft.com", "yshalivskyy@microsoft.com"],
     "expires": "Jun 1, 2025"
   },
@@ -564,24 +532,21 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["fast/scrolling/scrollbars/dsf-ready"],
     "args": ["--disable-smooth-scrolling",
-             "--force-device-scale-factor=2",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--force-device-scale-factor=2"],
     "expires": "Jun 1, 2025"
   },
   {
     "prefix": "speech-with-unified-autoplay",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/speech-api"],
-    "args": ["--autoplay-policy=document-user-activation-required",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--autoplay-policy=document-user-activation-required"],
     "expires": "Jul 1, 2023"
   },
   {
     "prefix": "unified-autoplay",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/feature-policy"],
-    "args": ["--autoplay-policy=document-user-activation-required",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--autoplay-policy=document-user-activation-required"],
     "expires": "Jul 1, 2023"
   },
   {
@@ -618,8 +583,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["wpt_internal/permissions-policy"],
     "exclusive_tests": "ALL",
-    "args": ["--isolated-context-origins=https://web-platform.test",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--isolated-context-origins=https://web-platform.test"],
     "owners": [
       "cmp@chromium.org",
       "reillyg@chromium.org",
@@ -633,8 +597,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/direct-sockets"],
     "exclusive_tests": "ALL",
-    "args": ["--isolated-context-origins=https://web-platform.test",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--isolated-context-origins=https://web-platform.test"],
     "expires": "never"
   },
   {
@@ -642,8 +605,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": [],
     "args": ["--enable-display-compositor-pixel-dump",
-             "--enable-accelerated-2d-canvas",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--enable-accelerated-2d-canvas"],
     "expires": "Jul 1, 2023"
   },
 
@@ -655,8 +617,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["http/tests/wasm/caching"],
     "exclusive_tests": "ALL",
-    "args": ["--js-flags=--wasm-tiering-budget=100 --allow-natives-syntax",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--js-flags=--wasm-tiering-budget=100 --allow-natives-syntax"],
     "expires": "Jul 1, 2024"
   },
 
@@ -714,7 +675,6 @@
     ],
     "exclusive_tests": "ALL",
     "args": ["--disable-site-isolation-trials",
-             "--disable-threaded-compositing", "--disable-threaded-animation",
              "--disable-features=OriginKeyedProcessesByDefault"],
     "owners": [
       "alexmos@chromium.org",
@@ -727,8 +687,7 @@
     "prefix": "not-site-per-process-nonexclusive",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/performance-timeline/tentative"],
-    "args": ["--disable-site-isolation-trials",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--disable-site-isolation-trials"],
     "owners": [
       "alexmos@chromium.org",
       "creis@chromium.org",
@@ -763,8 +722,7 @@
     "exclusive_tests": ["external/wpt/html/browsers/origin/origin-keyed-agent-clusters"],
     "args": ["--disable-auto-wpt-origin-isolation",
              "--reset-browsing-instance-between-tests",
-             "--disable-features=OriginAgentClusterDefaultEnable,OriginKeyedProcessesByDefault",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--disable-features=OriginAgentClusterDefaultEnable,OriginKeyedProcessesByDefault"],
     "owners": [
       "alexmos@chromium.org",
       "creis@chromium.org",
@@ -776,8 +734,7 @@
     "prefix": "fsa-incognito",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/file-system-access", "external/wpt/fs"],
-    "args": ["--enable-features=IncognitoFileSystemContextForTesting",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=IncognitoFileSystemContextForTesting"],
     "expires": "never"
   },
   {
@@ -785,8 +742,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["fast/forms/color-scheme"],
     "args": ["--enable-features=ForcedColors",
-             "--force-high-contrast",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--force-high-contrast"],
     "expires": "Jul 1, 2024"
   },
   {
@@ -797,8 +753,7 @@
               "wpt_internal/css/css-pseudo/spelling-error-007-crash.html"],
     "exclusive_tests": ["external/wpt/forced-colors-mode"],
     "args": ["--force-high-contrast",
-             "--enable-blink-features=ForcedColors,ForcedColorsPreserveParentColor",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--enable-blink-features=ForcedColors,ForcedColorsPreserveParentColor"],
     "expires": "Jul 1, 2024"
   },
   "This never expires because it tests rendering of form controls when the",
@@ -816,8 +771,7 @@
               "fast/forms/validation-bubble-appearance-wrap.html",
               "fast/loader/plain-text-document-appearance.html",
               "http/tests/eye-dropper"],
-    "args": ["--blink-settings=preferredColorScheme=0",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--blink-settings=preferredColorScheme=0"],
     "expires": "never"
   },
   {
@@ -826,19 +780,10 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/measure-memory"],
     "exclusive_tests": "ALL",
-    "args": ["--enable-blink-features=MeasureMemory,ForceEagerMeasureMemory",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-blink-features=MeasureMemory,ForceEagerMeasureMemory"],
     "expires": "Jul 1, 2024"
   },
   {
-    "prefix": "payment-request-mandatory-total",
-    "platforms": ["Linux", "Mac", "Win"],
-    "bases": ["http/tests/payments/payment-request-app-store-billing-mandatory-total.html"],
-    "args": ["--disable-blink-features=PaymentRequestTotalOptional",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
-    "expires": "Jul 1, 2023"
-  },
-  {
     "prefix": "css-sign-related-functions-disabled",
     "owners": ["seokho@chromium.org", "sakhapov@chromium.org"],
     "platforms": ["Linux", "Mac", "Win"],
@@ -847,8 +792,7 @@
       "external/wpt/css/css-values/signs-abs-serialize.html",
       "external/wpt/css/css-values/signs-abs-invalid.html"
     ],
-    "args": ["--disable-blink-features=CSSSignRelatedFunctions",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--disable-blink-features=CSSSignRelatedFunctions"],
     "expires": "Aug 1, 2024"
   },
   "The overlay-scrollbar virtual suite is testing a feature that is enabled",
@@ -858,8 +802,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": [ "external/wpt/css/css-ui/pointer-events-no-scrollbars-001.html",
                "external/wpt/css/css-ui/pointer-events-no-scrollbars-002.html"],
-    "args": ["--enable-features=OverlayScrollbar",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=OverlayScrollbar"],
     "expires": "never"
   },
   "The elastic-overscroll virtual suite is testing a feature that is enabled",
@@ -879,8 +822,7 @@
     "prefix": "non-overlay-scrollbar",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": [],
-    "args": ["--disable-features=OverlayScrollbar",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--disable-features=OverlayScrollbar"],
     "expires": "never"
   },
   {
@@ -930,8 +872,7 @@
     "bases": ["fast/forms/color-scheme/scrollbar",
               "virtual/fluent-non-overlay-scrollbar/hover-over-scrollbar-thumb.html"],
     "args": ["--enable-features=FluentScrollbar",
-             "--blink-settings=preferredColorScheme=0,forceDarkModeEnabled=true",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--blink-settings=preferredColorScheme=0,forceDarkModeEnabled=true"],
     "expires": "Jul 1, 2024",
     "owners": ["gastonr@microsoft.com", "gerchiko@microsoft.com", "yshalivskyy@microsoft.com"]
   },
@@ -962,8 +903,7 @@
     "owners": ["drott@chromium.org"],
     "platforms": ["Linux", "Mac", "Win", "Fuchsia"],
     "bases": [],
-    "args": ["--enable-font-antialiasing",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-font-antialiasing"],
     "expires": "Jan 1, 2025"
   },
   {
@@ -981,16 +921,14 @@
       "virtual/text-antialias/basic/014.html"
     ],
     "args": ["--enable-font-antialiasing", "--enable-features=UseGammaContrastRegistrySettings",
-             "--text-contrast=0.97", "--text-gamma=1.97",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--text-contrast=0.97", "--text-gamma=1.97"],
     "expires": "August 1, 2024"
   },
   {
     "prefix": "hdr",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": [],
-    "args": ["--force-color-profile=scrgb-linear",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--force-color-profile=scrgb-linear"],
     "owners": ["fserb@chromium.org"],
     "expires": "Jul 1, 2024"
   },
@@ -998,8 +936,7 @@
     "prefix": "color-spin",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": [],
-    "args": ["--force-color-profile=color-spin-gamma24",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--force-color-profile=color-spin-gamma24"],
     "owners": ["fserb@chromium.org"],
     "expires": "Jul 1, 2024"
   },
@@ -1008,8 +945,7 @@
     "owners": ["aaronhk@chromium.org", "ccameron@chromium.org"],
     "platforms": ["Linux", "Mac", "Win"],
     "bases": [],
-    "args": ["--force-color-profile=display-p3-d65",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--force-color-profile=display-p3-d65"],
     "expires": "Jul 1, 2024"
   },
   {
@@ -1017,11 +953,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/fetch/http-cache"],
     "exclusive_tests": "ALL",
-    "args": [
-      "--enable-features=SplitCacheByIncludeCredentials",
-      "--disable-threaded-compositing",
-      "--disable-threaded-animation"
-    ],
+    "args": ["--enable-features=SplitCacheByIncludeCredentials"],
     "expires": "never",
     "owners": [
       "chrome-security-owp-team@google.com",
@@ -1039,8 +971,7 @@
     "bases": ["external/wpt/fetch/http-cache",
               "external/wpt/signed-exchange"],
     "exclusive_tests": ["external/wpt/fetch/http-cache"],
-    "args": ["--enable-features=SplitCacheByNetworkIsolationKey",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=SplitCacheByNetworkIsolationKey"],
     "expires": "never"
   },
   {
@@ -1049,9 +980,7 @@
     "bases": ["external/wpt/fetch/http-cache"],
     "exclusive_tests": "ALL",
     "args": [
-      "--disable-features=SplitCacheByNetworkIsolationKey",
-      "--disable-threaded-compositing",
-      "--disable-threaded-animation"
+      "--disable-features=SplitCacheByNetworkIsolationKey"
     ],
     "expires": "never",
     "owners": [
@@ -1065,8 +994,7 @@
     "prefix": "web-bluetooth-new-permissions-backend",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["wpt_internal/bluetooth", "external/wpt/bluetooth"],
-    "args": ["--enable-features=WebBluetoothNewPermissionsBackend",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=WebBluetoothNewPermissionsBackend"],
     "owners": ["web-bluetooth@google.com"],
     "expires": "Jan 1, 2025"
   },
@@ -1083,8 +1011,7 @@
     "args": [
         "--enable-features=PrivateStateTokens",
         "--enable-blink-features=PrivateStateTokens,PrivateStateTokensAlwaysAllowIssuance",
-        "--additional-private-state-token-key-commitments={\"https://web-platform.test:8444\":{\"PrivateStateTokenV3VOPRF\":{\"protocol_version\":\"PrivateStateTokenV3VOPRF\",\"id\":1,\"batchsize\":1,\"keys\":{\"0\":{\"Y\":\"AAAAAASqh8oivosFN46xxx7zIK10bh07Younm5hZ90HgglQqOFUC8l2/VSlsOlReOHJ2CrfJ6CG1adnTkKJhZ0BtbSPWBwviQtdl64MWJc7sSg9HPvWfTjDigX5ihbzihG8V8aA=\",\"expiry\":\"253402300799000000\"}}}}}",
-        "--disable-threaded-compositing", "--disable-threaded-animation"
+        "--additional-private-state-token-key-commitments={\"https://web-platform.test:8444\":{\"PrivateStateTokenV3VOPRF\":{\"protocol_version\":\"PrivateStateTokenV3VOPRF\",\"id\":1,\"batchsize\":1,\"keys\":{\"0\":{\"Y\":\"AAAAAASqh8oivosFN46xxx7zIK10bh07Younm5hZ90HgglQqOFUC8l2/VSlsOlReOHJ2CrfJ6CG1adnTkKJhZ0BtbSPWBwviQtdl64MWJc7sSg9HPvWfTjDigX5ihbzihG8V8aA=\",\"expiry\":\"253402300799000000\"}}}}}"
     ],
     "expires": "Jul 1, 2024"
   },
@@ -1096,8 +1023,7 @@
       "external/wpt/dom/parts",
       "fast/parser"
     ],
-    "args": ["--disable-features=DOMPartsAPI,DOMPartsAPIMinimal",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--disable-features=DOMPartsAPI,DOMPartsAPIMinimal"],
     "expires": "Dec 1, 2024"
   },
   {
@@ -1120,8 +1046,7 @@
       "html/details_summary/details-inline.html",
       "wpt_internal/html/rendering/the-details-element"
     ],
-    "args": ["--disable-blink-features=DetailsStyling",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--disable-blink-features=DetailsStyling"],
     "expires": "Aug 1, 2024"
   },
   {
@@ -1140,8 +1065,7 @@
     "owners": ["dbaron@chromium.org", "paint-dev@chromium.org"],
     "platforms": ["Linux"],
     "bases": [ "external/wpt/css/css-transforms" ],
-    "args": ["--enable-features=BackfaceVisibilityInterop",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=BackfaceVisibilityInterop"],
     "expires": "Nov 15, 2024"
   },
   {
@@ -1162,8 +1086,7 @@
       "http/tests/inspector-protocol/issues/third-party-cookie-phaseout-exclusion.js",
       "http/tests/inspector-protocol/network/response-received-extra-info-exempted-cookie.js"
     ],
-    "args": ["--test-third-party-cookie-phaseout",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--test-third-party-cookie-phaseout"],
     "expires": "May 1, 2025"
   },
   {
@@ -1205,16 +1128,14 @@
       "http/tests/inspector-protocol/storage/indexed-db-set-items-by-storage-key.js",
       "http/tests/storage/partitioned-storage"
     ],
-    "args": ["--disable-features=ThirdPartyStoragePartitioning",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--disable-features=ThirdPartyStoragePartitioning"],
     "expires": "Feb 4, 2025"
   },
   {
     "prefix": "post-message-first-party-to-third-party-different-bucket-same-origin-blocked",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/html/browsers/windows/post-message"],
-    "args": ["--enable-features=PostMessageFirstPartyToThirdPartyDifferentBucketSameOriginBlocked",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=PostMessageFirstPartyToThirdPartyDifferentBucketSameOriginBlocked"],
     "expires": "Jul 1, 2024",
     "owners": ["arichiv@chromium.org"]
   },
@@ -1222,8 +1143,7 @@
     "prefix": "post-message-third-party-to-first-party-different-bucket-same-origin-blocked",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/html/browsers/windows/post-message"],
-    "args": ["--enable-features=PostMessageThirdPartyToFirstPartyDifferentBucketSameOriginBlocked",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=PostMessageThirdPartyToFirstPartyDifferentBucketSameOriginBlocked"],
     "expires": "Jul 1, 2024",
     "owners": ["arichiv@chromium.org"]
   },
@@ -1231,8 +1151,7 @@
     "prefix": "post-message-third-party-to-third-party-different-bucket-same-origin-blocked",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/html/browsers/windows/post-message"],
-    "args": ["--enable-features=PostMessageThirdPartyToThirdPartyDifferentBucketSameOriginBlocked",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=PostMessageThirdPartyToThirdPartyDifferentBucketSameOriginBlocked"],
     "expires": "Jul 1, 2024",
     "owners": ["arichiv@chromium.org"]
   },
@@ -1257,8 +1176,7 @@
                "external/wpt/webmessaging/postMessage_cross_domain_image_transfer_2d.sub.htm" ],
     "args": [ "--enable-features=CanvasOopRasterization",
               "--enable-accelerated-2d-canvas",
-              "--enable-gpu-rasterization",
-              "--disable-threaded-compositing", "--disable-threaded-animation"],
+              "--enable-gpu-rasterization"],
     "owners": ["fserb@chromium.org", "vasilyt@chromium.org"],
     "expires": "Jul 1, 2024"
   },
@@ -1267,8 +1185,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["http/tests/subresource_filter/overlay_popup_ad"],
     "exclusive_tests": "ALL",
-    "args": ["--disable-features=FrequencyCappingForOverlayPopupDetection",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--disable-features=FrequencyCappingForOverlayPopupDetection"],
     "expires": "Jul 1, 2023"
   },
   {
@@ -1277,8 +1194,7 @@
     "bases": [
       "http/tests/inspector-protocol/issues/third-party-cookie-blocking-first-party-set-enabled.js"
     ],
-    "args": ["--test-third-party-cookie-phaseout", "--use-related-website-set={\"primary\":\"https://firstparty.test\",\"associatedSites\":[\"https://cookie.test\"]}",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--test-third-party-cookie-phaseout", "--use-related-website-set={\"primary\":\"https://firstparty.test\",\"associatedSites\":[\"https://cookie.test\"]}"],
     "expires": "Dec 1, 2024",
     "owners": ["chrome-first-party-sets@chromium.org"]
   },
@@ -1287,8 +1203,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/html/webappapis/user-prompts/cannot-show-simple-dialogs/confirm-different-origin-frame.sub.html",
               "external/wpt/html/webappapis/user-prompts/cannot-show-simple-dialogs/prompt-different-origin-frame.sub.html"],
-    "args": ["--enable-features=SuppressDifferentOriginSubframeJSDialogs",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=SuppressDifferentOriginSubframeJSDialogs"],
     "expires": "Jul 1, 2023"
   },
   {
@@ -1311,8 +1226,7 @@
               "external/wpt/html/semantics/interactive-elements/the-dialog-element/inert-svg-hittest.html",
               "editing/text-iterator/auto-expand-details.html",
               "editing/text-iterator/auto-expand-details-shadowdom.html"],
-    "args": ["--force-renderer-accessibility",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--force-renderer-accessibility"],
     "expires": "Jul 1, 2025"
   },
   {
@@ -1320,8 +1234,7 @@
     "platforms": ["Linux"],
     "bases": ["external/wpt/accessibility/crashtests/removed-from-flat-tree.html"],
     "args": ["--force-renderer-accessibility",
-             "--enable-blink-features=HTMLParserYieldAndDelayOftenForTesting",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--enable-blink-features=HTMLParserYieldAndDelayOftenForTesting"],
     "expires": "never"
   },
   {
@@ -1461,8 +1374,7 @@
       "external/wpt/html/semantics/popovers/popover-open-in-beforetoggle.html",
       "wpt_internal/html/semantics/popovers/popover-hint-crash.tentative.html"
     ],
-    "args": ["--disable-blink-features=HTMLPopoverHint",
-      "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--disable-blink-features=HTMLPopoverHint"],
     "expires": "Jul 1, 2024"
   },
   {
@@ -1564,16 +1476,14 @@
     ],
     "exclusive_tests": "ALL",
     "args": [
-      "--enable-blink-features=ExposeRenderTimeNonTaoDelayedImage",
-      "--disable-threaded-compositing", "--disable-threaded-animation"],
+      "--enable-blink-features=ExposeRenderTimeNonTaoDelayedImage"],
     "expires": "Jul 1, 2024"
   },
   {
     "prefix": "parakeet",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/parakeet"],
-    "args": ["--enable-features=InterestGroupStorage,AdInterestGroupAPI,Parakeet",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=InterestGroupStorage,AdInterestGroupAPI,Parakeet"],
     "expires": "Jul 1, 2023"
   },
   {
@@ -1624,6 +1534,26 @@
     "expires": "Sep 1, 2024"
   },
   {
+    "prefix": "fledge-bidding-and-auction",
+    "platforms": [
+      "Linux",
+      "Mac",
+      "Win"
+    ],
+    "owners": [
+      "behamilton@google.com",
+      "mmenke@chromium.org",
+      "pauljensen@chromium.org"
+    ],
+    "bases": [
+      "external/wpt/fledge/tentative/get-interest-group-auction-data.https.window.js"
+    ],
+    "args": [
+      "--enable-features=FledgeBiddingAndAuctionServerAPI,FledgeBiddingAndAuctionServer:FledgeBiddingAndAuctionKeyConfig/{\"https%3A%2F%2Fpublickeyservice.gcp.privacysandboxservices.com\"%3A\"https%3A%2F%2Fpublickeyservice.pa.gcp.privacysandboxservices.com%2F.well-known%2Fprotected-auction%2Fv1%2Fpublic-keys\"%2C\"https%3A%2F%2Fpublickeyservice.pa.gcp.privacysandboxservices.com\"%3A\"https%3A%2F%2Fpublickeyservice.pa.gcp.privacysandboxservices.com%2F.well-known%2Fprotected-auction%2Fv1%2Fpublic-keys\"}"
+    ],
+    "expires": "Jan 14, 2025"
+  },
+  {
     "prefix": "automatic-lazy-frame-loading",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": [
@@ -1633,7 +1563,7 @@
     "exclusive_tests": ["wpt_internal/lazyembed"],
     "args": [
       "--enable-features=AutomaticLazyFrameLoadingToEmbeds:timeout/1000,AutomaticLazyFrameLoadingToEmbedUrls:allowed_websites/http%3A%2F%2Fbad3p.test%3A3001%7C%2Fembed,AutomaticLazyFrameLoadingToAds:timeout/5000,DelayAsyncScriptExecution:delay_async_exec_target/cross_site_with_allow_list/delay_async_exec_allow_list/http%3A%2F%2Fbad3p.test",
-      "--disable-field-trial-config", "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--disable-field-trial-config"
     ],
     "expires": "Jul 1, 2024"
   },
@@ -1641,64 +1571,56 @@
     "prefix": "automatic-lazy-frame-loading-ads",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": [],
-    "args": ["--enable-features=AutomaticLazyFrameLoadingToAds:timeout/1000",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=AutomaticLazyFrameLoadingToAds:timeout/1000"],
     "expires": "Jul 1, 2024"
   },
   {
     "prefix": "async-script-scheduling-disabled",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["wpt_internal/async-script-scheduling"],
-    "args": ["--disable-features=DelayAsyncScriptExecution",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--disable-features=DelayAsyncScriptExecution"],
     "expires": "Jul 1, 2025"
   },
   {
     "prefix": "async-script-scheduling-apply-to-cross-site-only",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["wpt_internal/async-script-scheduling"],
-    "args": ["--enable-features=DelayAsyncScriptExecution:delay_async_exec_target/cross_site_only",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=DelayAsyncScriptExecution:delay_async_exec_target/cross_site_only"],
     "expires": "Jul 1, 2025"
   },
   {
     "prefix": "async-script-scheduling-apply-to-allowlist",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["wpt_internal/async-script-scheduling"],
-    "args": ["--enable-features=DelayAsyncScriptExecution:delay_async_exec_target/cross_site_with_allow_list/delay_async_exec_allow_list/http%3A%2F%2Fbad3p.test%7C%2Fwpt_internal%2Fasync-script-scheduling%2Fresources%2Fscript.sub.js",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=DelayAsyncScriptExecution:delay_async_exec_target/cross_site_with_allow_list/delay_async_exec_allow_list/http%3A%2F%2Fbad3p.test%7C%2Fwpt_internal%2Fasync-script-scheduling%2Fresources%2Fscript.sub.js"],
     "expires": "Jul 1, 2025"
   },
   {
     "prefix": "async-script-scheduling-finished-parsing",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["wpt_internal/async-script-scheduling"],
-    "args": ["--enable-features=DelayAsyncScriptExecution:delay_async_exec_delay_type/finished_parsing",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=DelayAsyncScriptExecution:delay_async_exec_delay_type/finished_parsing"],
     "expires": "Jul 1, 2025"
   },
   {
     "prefix": "async-script-scheduling-finished-parsing-with-dom-content-loaded-wait-for-async-script",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["wpt_internal/async-script-scheduling"],
-    "args": ["--enable-features=DelayAsyncScriptExecution:delay_async_exec_delay_type/finished_parsing,DOMContentLoadedWaitForAsyncScript",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=DelayAsyncScriptExecution:delay_async_exec_delay_type/finished_parsing,DOMContentLoadedWaitForAsyncScript"],
     "expires": "Jul 1, 2025"
   },
   {
     "prefix": "async-script-scheduling-first-paint-or-finished-parsing",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["wpt_internal/async-script-scheduling"],
-    "args": ["--enable-features=DelayAsyncScriptExecution:delay_async_exec_delay_type/first_paint_or_finished_parsing",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=DelayAsyncScriptExecution:delay_async_exec_delay_type/first_paint_or_finished_parsing"],
     "expires": "Jul 1, 2025"
   },
   {
     "prefix": "low-priority-script-loading",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["http/tests/devtools/network/resource-priority.js"],
-    "args": ["--enable-features=LowPriorityScriptLoading",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=LowPriorityScriptLoading"],
     "expires": "Jul 1, 2025"
   },
   {
@@ -1708,8 +1630,7 @@
       "external/wpt/largest-contentful-paint/update-on-style-change.tentative.html"
     ],
     "args": [
-      "--enable-features=LCPMultipleUpdatesPerElement",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--enable-features=LCPMultipleUpdatesPerElement"
     ],
     "expires": "Jul 1, 2024"
   },
@@ -1721,8 +1642,7 @@
       "external/wpt/largest-contentful-paint/mouseover-heuristics-background.tentative.html"
     ],
     "args": [
-      "--enable-features=LCPMouseoverHeuristics",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--enable-features=LCPMouseoverHeuristics"
     ],
     "expires": "Jul 1, 2024"
   },
@@ -1731,8 +1651,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "exclusive_tests": "ALL",
     "bases": ["http/tests/low-priority-async-script-execution"],
-    "args": ["--enable-features=LCPScriptObserver,LowPriorityAsyncScriptExecution:low_pri_async_exec_timeout/100ms/low_pri_async_exec_exclude_lcp_influencers/true",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=LCPScriptObserver,LowPriorityAsyncScriptExecution:low_pri_async_exec_timeout/100ms/low_pri_async_exec_exclude_lcp_influencers/true"],
     "owners": [
       "alexnj@chromium.org",
       "chikamune@chromium.org"
@@ -1748,8 +1667,7 @@
     "exclusive_tests": [
       "external/wpt/browsing-topics"
     ],
-    "args": ["--enable-features=BrowsingTopics,PrivacySandboxAdsAPIsOverride",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=BrowsingTopics,PrivacySandboxAdsAPIsOverride"],
     "expires": "Dec 3, 2024"
   },
   {
@@ -1763,8 +1681,7 @@
     ],
     "args": [
       "--enable-privacy-sandbox-ads-apis",
-      "--enable-features=FencedFramesDefaultMode,AggregationServiceMultipleCloudProviders:allowlist/https%3A%2F%2Fweb-platform.test%3A8444,FencedFramesEnforceFocus,PrivateAggregationAuctionReportBuyerDebugModeConfig,PrivateAggregationApiFilteringIds",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--enable-features=FencedFramesDefaultMode,AggregationServiceMultipleCloudProviders:allowlist/https%3A%2F%2Fweb-platform.test%3A8444,FencedFramesEnforceFocus,PrivateAggregationAuctionReportBuyerDebugModeConfig,PrivateAggregationApiFilteringIds"
     ],
     "expires": "Jul 1, 2024"
   },
@@ -1780,8 +1697,7 @@
     "args": [
       "--enable-privacy-sandbox-ads-apis",
       "--private-aggregation-developer-mode",
-      "--enable-features=FencedFramesDefaultMode,AggregationServiceMultipleCloudProviders:allowlist/https%3A%2F%2Fweb-platform%2Etest%3A8444%2Chttps%3A%2F%2Fwww1%2Eweb-platform%2Etest%3A8444,PrivateAggregationApiBundledEnhancements,PrivateAggregationApiMultipleCloudProviders,PrivateAggregationAuctionReportBuyerDebugModeConfig,PrivateAggregationApiFilteringIds",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--enable-features=FencedFramesDefaultMode,AggregationServiceMultipleCloudProviders:allowlist/https%3A%2F%2Fweb-platform%2Etest%3A8444%2Chttps%3A%2F%2Fwww1%2Eweb-platform%2Etest%3A8444,PrivateAggregationApiBundledEnhancements,PrivateAggregationApiMultipleCloudProviders,PrivateAggregationAuctionReportBuyerDebugModeConfig,PrivateAggregationApiFilteringIds"
     ],
     "expires": "Jul 1, 2024"
   },
@@ -1796,8 +1712,7 @@
       "external/wpt/shared-storage",
       "http/tests/inspector-protocol/shared-storage"
     ],
-    "args": ["--enable-features=SharedStorageAPI,FencedFrames:implementation_type/mparch,PrivacySandboxAdsAPIsOverride,FencedFramesAPIChanges,FencedFramesDefaultMode,SharedStorageAPIM118,SharedStorageAPIM125,SharedStorageAPIEnableWALForDatabase,FencedFramesEnforceFocus,FencedFramesReportEventHeaderChanges",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=SharedStorageAPI,FencedFrames:implementation_type/mparch,PrivacySandboxAdsAPIsOverride,FencedFramesAPIChanges,FencedFramesDefaultMode,SharedStorageAPIM118,SharedStorageAPIM125,SharedStorageAPIEnableWALForDatabase,FencedFramesEnforceFocus,FencedFramesReportEventHeaderChanges"],
     "expires": "Jul 31, 2024"
   },
   {
@@ -1809,8 +1724,7 @@
     "exclusive_tests": [
       "external/wpt/shared-storage-selecturl-limit/"
     ],
-    "args": ["--enable-features=SharedStorageAPI,FencedFrames:implementation_type/mparch,FencedFramesAPIChanges,FencedFramesDefaultMode,FencedFramesEnforceFocus,PrivacySandboxAdsAPIsOverride,SharedStorageSelectURLLimit:SharedStorageSelectURLBitBudgetPerPageLoad/9,SharedStorageAPIM118,SharedStorageAPIM125,SharedStorageAPIEnableWALForDatabase",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=SharedStorageAPI,FencedFrames:implementation_type/mparch,FencedFramesAPIChanges,FencedFramesDefaultMode,FencedFramesEnforceFocus,PrivacySandboxAdsAPIsOverride,SharedStorageSelectURLLimit:SharedStorageSelectURLBitBudgetPerPageLoad/9,SharedStorageAPIM118,SharedStorageAPIM125,SharedStorageAPIEnableWALForDatabase"],
     "expires": "Jul 31, 2024"
   },
   {
@@ -1844,16 +1758,14 @@
       "external/wpt/fetch/private-network-access/fenced-frame-no-preflight-required.tentative.https.window.js"
     ],
     "args": ["--enable-features=PrivacySandboxAdsAPIsOverride,Fledge,AdInterestGroupAPI,FencedFramesEnforceFocus,FencedFramesLocalUnpartitionedDataAccess,ExemptUrlFromNetworkRevocationForTesting,FencedFramesCrossOriginEventReportingAllTraffic,FencedFramesReportEventHeaderChanges",
-             "--enable-blink-features=FencedFramesDefaultMode",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--enable-blink-features=FencedFramesDefaultMode"],
     "expires": "May 1, 2025"
   },
   {
     "prefix": "cors-non-wildcard-request-headers",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/fetch/api/cors/cors-preflight.any.js"],
-    "args": ["--enable-features=CorsNonWildcardRequestHeadersSupport",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=CorsNonWildcardRequestHeadersSupport"],
     "expires": "Jul 1, 2023"
   },
   "The following tests never pass in the default Blink test runner due to",
@@ -1869,8 +1781,7 @@
     ],
     "exclusive_tests": "ALL",
     "args": ["--enable-features=NoForcedFrameUpdatesForWebTests",
-             "--disable-features=KeepAliveInBrowserMigration",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--disable-features=KeepAliveInBrowserMigration"],
     "expires": "Dec 1, 2024"
   },
 
@@ -1880,8 +1791,7 @@
     "bases": ["fast/events/mouse-cursor-image-set-svg.html"],
     "args": [
       "--enable-features=SystemCursorSizeSupported",
-      "--disable-headless-mode",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--disable-headless-mode"
     ],
     "expires": "Dec 1, 2024"
   },
@@ -1894,8 +1804,7 @@
     "args": [
       "--enable-features=OriginAgentClusterDefaultWarning",
       "--disable-features=OriginAgentClusterDefaultEnable,OriginKeyedProcessesByDefault",
-      "--disable-auto-wpt-origin-isolation",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--disable-auto-wpt-origin-isolation"
     ],
     "expires": "Jul 1, 2024"
   },
@@ -1905,8 +1814,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": [ "external/wpt/webauthn/remote-desktop-client-override.tentative.https.html" ],
     "args": [
-      "--webauthn-remote-desktop-support",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--webauthn-remote-desktop-support"
     ],
     "expires": "Jul 1, 2025"
   },
@@ -1915,8 +1823,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["wpt_internal/in-order-script-scheduling/force-in-order"],
     "args": [
-      "--enable-features=ForceInOrderScript",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--enable-features=ForceInOrderScript"
     ],
     "expires": "Jul 1, 2023"
   },
@@ -1925,8 +1832,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["wpt_internal/in-order-script-scheduling/selective-in-order"],
     "args": [
-      "--enable-features=SelectiveInOrderScript,SelectiveInOrderScriptTarget:allow_list/http%3A%2F%2Fbad3p.test%7Csync-script-1.js",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--enable-features=SelectiveInOrderScript,SelectiveInOrderScriptTarget:allow_list/http%3A%2F%2Fbad3p.test%7Csync-script-1.js"
     ],
     "expires": "Jul 1, 2023"
   },
@@ -1938,8 +1844,7 @@
       "fast/dom/HTMLScriptElement",
       "fast/preloader"
     ],
-    "args": ["--enable-features=ThreadedPreloadScanner,PrecompileInlineScripts",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=ThreadedPreloadScanner,PrecompileInlineScripts"],
     "expires": "Dec 5, 2024"
   },
   {
@@ -1949,16 +1854,14 @@
       "external/wpt/html/infrastructure/urls/terminology-0/",
       "external/wpt/cookie-store/cookieStore_opaque_origin.https.html"
     ],
-    "args": ["--enable-features=IsolateSandboxedIframes",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=IsolateSandboxedIframes"],
     "expires": "Jul 1, 2024"
   },
   {
     "prefix": "coop-restrict-properties",
     "platforms": ["Linux", "Mac", "Win"],
     "bases": [ "external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties" ],
-    "args": ["--enable-features=CoopRestrictProperties",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=CoopRestrictProperties"],
     "expires": "Jul 1, 2024"
   },
 
@@ -1977,8 +1880,7 @@
     "args": [
       "--enable-blink-features=SpeculationRulesFetchFromHeader,SpeculationRulesDocumentRules,NoVarySearchPrefetch,SpeculationRulesNoVarySearchHint,SpeculationRulesEagerness,SpeculationRulesDocumentRulesSelectorMatches",
       "--enable-features=PrefetchUseContentRefactor:block_until_head_eager_prefetch/true/block_until_head_timeout_eager_prefetch/0,PrefetchRedirects,PrefetchCookieIndices,CookieIndicesHeader",
-      "--bypass-prefetch-proxy-for-host=not-web-platform.test",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--bypass-prefetch-proxy-for-host=not-web-platform.test"
     ],
     "expires": "Jul 1, 2024"
   },
@@ -1993,8 +1895,7 @@
     "exclusive_tests": "ALL",
     "args": [
       "--enable-blink-features=NoVarySearchPrefetch,SpeculationRulesNoVarySearchHint",
-      "--enable-features=PrefetchUseContentRefactor:block_until_head_eager_prefetch/true",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--enable-features=PrefetchUseContentRefactor:block_until_head_eager_prefetch/true"
     ],
     "expires": "Jul 1, 2024"
   },
@@ -2010,8 +1911,7 @@
     "args": [
       "--enable-blink-features=SpeculationRulesFetchFromHeader,SpeculationRulesDocumentRules,NoVarySearchPrefetch,SpeculationRulesNoVarySearchHint,SpeculationRulesEagerness,SpeculationRulesDocumentRulesSelectorMatches",
       "--enable-features=PrefetchUseContentRefactor:block_until_head_eager_prefetch/true/block_until_head_timeout_eager_prefetch/0,PrefetchRedirects,PrefetchReusable,PrefetchCookieIndices,CookieIndicesHeader",
-      "--bypass-prefetch-proxy-for-host=not-web-platform.test",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--bypass-prefetch-proxy-for-host=not-web-platform.test"
     ],
     "expires": "Jul 1, 2024"
   },
@@ -2025,8 +1925,7 @@
       "http/tests/inspector-protocol/preload/preloading-attempt-sources-updated.js"
     ],
     "args": [
-      "--enable-blink-features=SpeculationRulesDocumentRules,SpeculationRulesDocumentRulesSelectorMatches",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--enable-blink-features=SpeculationRulesDocumentRules,SpeculationRulesDocumentRulesSelectorMatches"
     ],
     "expires": "Jul 1, 2024"
   },
@@ -2053,8 +1952,7 @@
       "http/tests/inspector-protocol/issues/cookie-domain-non-ascii.js",
       "external/wpt/cookies/domain/domain-attribute-idn-host.sub.https.html"
     ],
-    "args": ["--enable-features=CookieDomainRejectNonASCII",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=CookieDomainRejectNonASCII"],
     "owners": ["johannhof@chromium.org"],
     "expires": "Jul 1, 2024"
   },
@@ -2077,8 +1975,7 @@
       "external/wpt/close-watcher"
     ],
     "args": [
-      "--reset-browsing-instance-between-tests",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--reset-browsing-instance-between-tests"
     ],
     "expires": "never"
   },
@@ -2087,8 +1984,7 @@
     "platforms": ["Linux"],
     "args": [
       "--enable-features=OpaqueResponseBlockingV01,OpaqueResponseBlockingV02",
-      "--disable-features=OpaqueResponseBlockingErrorsForAllFetches,DeprecateUnload",
-      "--disable-threaded-compositing", "--disable-threaded-animation"],
+      "--disable-features=OpaqueResponseBlockingErrorsForAllFetches,DeprecateUnload"],
     "bases": [
       "external/wpt/fetch/orb",
       "external/wpt/fetch/corb",
@@ -2100,8 +1996,7 @@
   {
     "prefix": "orb-errors-for-all-fetches",
     "platforms": ["Linux"],
-    "args": ["--enable-features=OpaqueResponseBlockingV01,OpaqueResponseBlockingV02,OpaqueResponseBlockingErrorsForAllFetches",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=OpaqueResponseBlockingV01,OpaqueResponseBlockingV02,OpaqueResponseBlockingErrorsForAllFetches"],
     "bases": [
       "external/wpt/fetch/orb",
       "external/wpt/fetch/corb"
@@ -2113,8 +2008,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["wpt_internal/js/shared_memory"],
     "exclusive_tests": "ALL",
-    "args": ["--enable-features=JavaScriptExperimentalSharedMemory",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=JavaScriptExperimentalSharedMemory"],
     "owners": ["syg@chromium.org"],
     "expires": "Jul 1, 2025"
   },
@@ -2133,8 +2027,7 @@
     "bases": ["external/wpt/credential-management/fedcm-login-status/"],
     "exclusive_tests": "ALL",
     "args": ["--enable-features=FedCmIdpSigninStatusEnabled",
-             "--enable-features=FencedFramesDefaultMode",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--enable-features=FencedFramesDefaultMode"],
     "owners": ["cbiesinger@chromium.org", "npm@chromium.org"],
     "expires": "Mar 1, 2025"
   },
@@ -2143,8 +2036,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/credential-management/fedcm-same-site-none/"],
     "exclusive_tests": "ALL",
-    "args": ["--enable-features=FedCmSameSiteNone",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=FedCmSameSiteNone"],
     "owners": ["cbiesinger@chromium.org", "npm@chromium.org"],
     "expires": "Mar 1, 2025"
   },
@@ -2163,8 +2055,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/credential-management/fedcm-multi-idp/"],
     "exclusive_tests": "ALL",
-    "args": ["--enable-features=FedCmMultipleIdentityProviders",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=FedCmMultipleIdentityProviders"],
     "expires": "Jul 1, 2024"
   },
   {
@@ -2172,7 +2063,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/credential-management/fedcm-register/"],
     "exclusive_tests": "ALL",
-    "args": ["--enable-features=FedCmIdPregistration"],
+    "args": ["--enable-features=FedCmIdPregistration,FedCmMultipleIdentityProviders"],
     "owners": ["cbiesinger@chromium.org", "goto@chromium.org"],
     "expires": "May 1, 2025"
   },
@@ -2181,8 +2072,7 @@
     "owners": ["masonf@chromium.org", "dizhangg@chromium.org"],
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["external/wpt/custom-elements/scoped-registry"],
-    "args": ["--disable-blink-features=ScopedCustomElementRegistry",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--disable-blink-features=ScopedCustomElementRegistry"],
     "expires": "Jul 1, 2024"
   },
 
@@ -2197,8 +2087,7 @@
     "bases": [
       "printing/webgl-oversized-printing.html"
     ],
-    "args": ["--enable-webgl-developer-extensions",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-webgl-developer-extensions"],
     "expires": "never"
   },
   {
@@ -2219,8 +2108,7 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": ["fast/events/pointerevents/device-id"],
     "args": [
-      "--disable-blink-features=PointerEventDeviceId",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--disable-blink-features=PointerEventDeviceId"
     ],
     "expires": "Jul 1, 2024"
   },
@@ -2239,8 +2127,7 @@
     ],
     "args": [
       "--enable-features=KeepAliveInBrowserMigration",
-      "--disable-features=DeprecateUnload",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--disable-features=DeprecateUnload"
     ],
     "expires": "Apr 1, 2024"
   },
@@ -2248,8 +2135,7 @@
     "prefix": "longtask-from-loaf",
     "platforms": ["Linux"],
     "bases": ["external/wpt/longtask-timing"],
-    "args": ["--enable-blink-features=LongTaskFromLongAnimationFrame",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-blink-features=LongTaskFromLongAnimationFrame"],
     "expires": "Aug 1, 2024"
   },
   {
@@ -2257,8 +2143,7 @@
     "platforms": ["Linux"],
     "bases": ["netinfo/"],
     "args": [
-      "--enable-blink-features=NetInfoConstantType",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--enable-blink-features=NetInfoConstantType"
     ],
     "expires": "Dec 1, 2023"
   },
@@ -2319,8 +2204,7 @@
     "bases": [
       "external/wpt/soft-navigation-heuristics"
     ],
-    "args": ["--enable-blink-features=SoftNavigationHeuristicsExposeFPAndFCP",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-blink-features=SoftNavigationHeuristicsExposeFPAndFCP"],
     "expires": "Jul 1, 2024"
   },
   {
@@ -2332,8 +2216,7 @@
       "external/wpt/html/semantics/scripting-1"
     ],
     "args": ["--enable-features=ForceProduceCompileHints",
-             "--disable-features=DeprecateUnload",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--disable-features=DeprecateUnload"],
     "expires": "never"
   },
   {
@@ -2343,8 +2226,7 @@
       "external/wpt/service-workers/service-worker/tentative/static-router",
       "http/tests/inspector-protocol/service-worker/tentative/static-router"
     ],
-    "args": ["--enable-features=ServiceWorkerStaticRouterTimingInfo",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=ServiceWorkerStaticRouterTimingInfo"],
     "expires": "Jun 5, 2025",
     "owners": ["suzukikeita@chromium.org", "yyanagisawa@chromium.org", "sisidovski@chromium.org"]
   },
@@ -2360,8 +2242,7 @@
     ],
     "exclusive_tests": "ALL",
     "args": [
-      "--enable-features=LCPCriticalPathPredictor:lcpp_adjust_image_load_priority/true,LCPTimingPredictorPrerender2",
-      "--disable-threaded-compositing", "--disable-threaded-animation"
+      "--enable-features=LCPCriticalPathPredictor:lcpp_adjust_image_load_priority/true,LCPTimingPredictorPrerender2"
     ],
     "expires": "Jul 10, 2024",
     "owners": [
@@ -2466,8 +2347,7 @@
       "http/tests/inspector-protocol/issues/css-webkit-appearance-non-standard-issue.js"
     ],
     "args": ["--enable-blink-features=NonStandardAppearanceValuesHighUsage",
-             "--enable-blink-features=NonStandardAppearanceValueSliderVertical",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--enable-blink-features=NonStandardAppearanceValueSliderVertical"],
     "owners": ["dizhangg@chromium.org"],
     "expires": "Jul 1, 2024"
   },
@@ -2505,8 +2385,7 @@
       "external/wpt/cookie-deprecation-label"
     ],
     "exclusive_tests": "ALL",
-    "args": ["--enable-features=CookieDeprecationFacilitatedTesting:label/label_test",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--enable-features=CookieDeprecationFacilitatedTesting:label/label_test"],
     "expires": "June 30, 2024"
   },
   {
@@ -2985,8 +2864,7 @@
       "fast/forms/range/range-appearance-border-padding.html"
     ],
     "args": ["--disable-features=FormControlsVerticalWritingModeDirectionSupport",
-             "--disable-features=NonStandardAppearanceValueSliderVertical",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--disable-features=NonStandardAppearanceValueSliderVertical"],
     "owners": ["dizhangg@chromium.org"],
     "expires": "Jun 1, 2025"
   },
@@ -2997,8 +2875,7 @@
       "css-parser/vertical-range-slider-appearance.html"
     ],
     "args": ["--disable-features=FormControlsVerticalWritingModeDirectionSupport",
-             "--enable-features=NonStandardAppearanceValueSliderVertical",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+             "--enable-features=NonStandardAppearanceValueSliderVertical"],
     "owners": ["dizhangg@chromium.org"],
     "expires": "Jun 1, 2025"
   },
@@ -3090,8 +2967,7 @@
       "external/wpt/html/semantics/popovers/popover-css-properties.tentative.html",
       "external/wpt/html/semantics/popovers/popover-target-action-hover.tentative.html"
     ],
-    "args": ["--disable-blink-features=HTMLPopoverActionHover",
-             "--disable-threaded-compositing", "--disable-threaded-animation"],
+    "args": ["--disable-blink-features=HTMLPopoverActionHover"],
     "expires": "Feb 1, 2025"
   },
   {
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 45c9c01..7262393 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -230484,6 +230484,32 @@
        {}
       ]
      ],
+     "transparent-accent-color-001.html": [
+      "219e24c1689b11dca0f22670118439d10e6b8813",
+      [
+       null,
+       [
+        [
+         "/css/css-ui/reference/transparent-accent-color-001-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "transparent-accent-color-002.html": [
+      "46b9835d0c18313885e08e2d469111cb82fa841f",
+      [
+       null,
+       [
+        [
+         "/css/css-ui/reference/transparent-accent-color-002-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "webkit-appearance-auto-001.html": [
       "fb0261b020f6fc2b1e3bfccb3da7d899f0337f79",
       [
@@ -330621,7 +330647,7 @@
       []
      ],
      "first-letter-hi-001-ref.html": [
-      "d0decf8bf41d4516895f77ecf3462231d063f09e",
+      "0eaae755eb91fbb3983ff2caf9bbe4ac4f7bc9e1",
       []
      ],
      "first-letter-hi-002-ref.html": [
@@ -341872,6 +341898,14 @@
       "text-overflow-ellipsis-indent-001-ref.html": [
        "660a7c4d52e7e2a763bfffc7582469896a5835b8",
        []
+      ],
+      "transparent-accent-color-001-ref.html": [
+       "c9d6eb720f1f8f17285014b0b7fa99f86ec6e4e7",
+       []
+      ],
+      "transparent-accent-color-002-ref.html": [
+       "819a5852460eeb295a65ac9acf8ce8683c93170f",
+       []
       ]
      },
      "resize-change-margin-ref.html": [
@@ -347430,6 +347464,10 @@
       "matchMedia.js": [
        "f8947e0472f489ca1a98a9e231b17e7d8ce6585e",
        []
+      ],
+      "simultaneousScrollIntoViews.js": [
+       "f3d02d2598d2624fc602e1a49b6afcbbb24017ed",
+       []
       ]
      },
      "screen-detached-frame-expected.txt": [
@@ -347460,8 +347498,8 @@
       "c8a783980f8a36216f282f5873b9e161286ab3ac",
       []
      ],
-     "smooth-scroll-nonstop-expected.txt": [
-      "7cf4f26a2da860b1713cc943d8637368d0bda72e",
+     "smooth-scrollIntoView-with-smooth-fragment-scroll-iframe.html": [
+      "26dbdd2053ae62efcb7710eecc8dc270119ffe00",
       []
      ],
      "subpixel-sizes-and-offsets.tentative-expected.txt": [
@@ -400240,7 +400278,7 @@
        []
       ],
       "fixtures_bidi.py": [
-       "a9cefd004b14f622fcec8cca8cb2315d138698b9",
+       "dd99e800cc08ee36b9de59d1442722e8b51c341c",
        []
       ],
       "fixtures_http.py": [
@@ -480581,6 +480619,20 @@
        {}
       ]
      ],
+     "scrollIntoView-multiple-nested.html": [
+      "630cd21b6137c2150bb6a3363c4654b885f5e20a",
+      [
+       null,
+       {}
+      ]
+     ],
+     "scrollIntoView-multiple.html": [
+      "e6ddd1818f2ab861017c25b112725b448c2b1c09",
+      [
+       null,
+       {}
+      ]
+     ],
      "scrollIntoView-scrollMargin.html": [
       "930702aa8792506df50120feaca86d3f76bc1a02",
       [
@@ -480631,7 +480683,7 @@
       ]
      ],
      "scrollIntoView-smooth.html": [
-      "ddfa31076c2bff7711ed493dbaec0943fd03ff87",
+      "324e51d7388a04fdc3b53e26542284e4aa6a6792",
       [
        null,
        {}
@@ -480742,6 +480794,22 @@
        {}
       ]
      ],
+     "smooth-scrollIntoView-with-smooth-fragment-scroll.html": [
+      "72ecdf15e5511532944aa24d05c84f37ce04a6ce",
+      [
+       null,
+       {}
+      ]
+     ],
+     "smooth-scrollIntoView-with-unrelated-gesture-scroll.html": [
+      "f42fcb298570ccc6d56d63657982cabeb874b559",
+      [
+       null,
+       {
+        "testdriver": true
+       }
+      ]
+     ],
      "subpixel-sizes-and-offsets.tentative.html": [
       "d198b9dde60c8cac16241c412d3e55f772166010",
       [
@@ -486449,7 +486517,7 @@
        ]
       ],
       "scrollend-event-fired-for-scrollIntoView.html": [
-       "8782b1dfee623741dd2830d538684ecffe767f18",
+       "40aa77f4764b6c4301b8aba7221e1e42e768505d",
        [
         null,
         {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/details-open-ref.html b/third_party/blink/web_tests/external/wpt/css/css-lists/details-open-ref.html
new file mode 100644
index 0000000..88903cb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/details-open-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Reference File: list-item counter with details open </title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/grouping-content.html#the-li-element">
+<details open>
+  <summary>Expand me</summary>
+  <div>5. Should be numbered 5</div>
+</details>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/details-open.html b/third_party/blink/web_tests/external/wpt/css/css-lists/details-open.html
new file mode 100644
index 0000000..8354d01
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/details-open.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Test: list-item counter with details open </title>
+<link rel="author" href="mailto:sakhapov@chromium.org">
+<link rel="match" href="details-open-ref.html">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/grouping-content.html#the-li-element">
+<details>
+  <summary>Expand me</summary>
+  <ol style="margin: 0; padding: 0; list-style-position: inside;">
+    <li value="5">Should be numbered 5</li>
+  </ol>
+</details>
+<script>
+  document.documentElement.offsetTop;
+  document.querySelector("details").setAttribute("open", "");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-letter-hi-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-letter-hi-001-ref.html
index d0decf8b..0eaae75 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-letter-hi-001-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/first-letter-hi-001-ref.html
@@ -17,5 +17,5 @@
 <p><span class=fl>&#x0915;&#x094D;&#x0930;</span>&#x092E;
 <p><span class=fl>&#x0915;&#x094D;&#x0937;</span>&#x0923;
 <p><span class=fl>&#x0937;&#x094D;&#x0915;&#x094D;&#x0930;</span>&#x0938;
-<p><span class=fl>&#x0919;&#x094D;</span>&#x0919;&#x092E;
-<p><span class=fl>&#x0919;&#x094D;</span>&#x0915;&#x094D;&#x0930;&#x0938;
+<p><span class=fl>&#x0919;&#x094D;&#x0919;</span>&#x092E;
+<p><span class=fl>&#x0919;&#x094D;&#x0915;&#x094D;&#x0930;</span>&#x0938;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/reference/transparent-accent-color-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-ui/reference/transparent-accent-color-001-ref.html
new file mode 100644
index 0000000..c9d6eb72
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/reference/transparent-accent-color-001-ref.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<title>CSS Basic User Interface Test: transparent accent color</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
+<link rel="help" href="https://drafts.csswg.org/css-ui-4/#widget-accent">
+<style>
+
+div {
+    border: solid orange;
+    padding: 1ch;
+    margin: 1ch;
+    float: left;
+}
+
+#t1 input { color-scheme: light;}
+#t1 input { accent-color: white; }
+
+#t2 input { color-scheme: light;}
+#t2 input { accent-color: #7f7fff; }
+
+#t3 { background: orange;}
+#t3 input { color-scheme: light;}
+#t3 input { accent-color: #7f7fff; }
+
+</style>
+
+<p>Test passes if in each box bellow, you see a pair of identically colored check-boxes.
+
+<div id=t1>
+  <input class=test type=checkbox checked>
+  <input class=ref type=checkbox checked>
+</div>
+
+<div id=t2>
+  <input class=test type=checkbox checked>
+  <input class=ref type=checkbox checked>
+</div>
+
+<div id=t3>
+  <input class=test type=checkbox checked>
+  <input class=ref type=checkbox checked>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/reference/transparent-accent-color-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-ui/reference/transparent-accent-color-002-ref.html
new file mode 100644
index 0000000..819a585
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/reference/transparent-accent-color-002-ref.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<title>CSS Basic User Interface Test: transparent accent color</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
+<link rel="help" href="https://drafts.csswg.org/css-ui-4/#widget-accent">
+<style>
+
+div {
+    border: solid orange;
+    padding: 1ch;
+    margin: 1ch;
+    float: left;
+}
+
+#t1 input { color-scheme: dark;}
+#t1 input { accent-color: black; }
+
+#t2 input { color-scheme: dark;}
+#t2 input { accent-color: #00007f; }
+
+#t3 { background: orange;}
+#t3 input { color-scheme: dark;}
+#t3 input { accent-color: #00007f; }
+
+</style>
+
+<p>Test passes if in each box bellow, you see a pair of identically colored check-boxes.
+
+<div id=t1>
+  <input class=test type=checkbox checked>
+  <input class=ref type=checkbox checked>
+</div>
+
+<div id=t2>
+  <input class=test type=checkbox checked>
+  <input class=ref type=checkbox checked>
+</div>
+
+<div id=t3>
+  <input class=test type=checkbox checked>
+  <input class=ref type=checkbox checked>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/transparent-accent-color-001.html b/third_party/blink/web_tests/external/wpt/css/css-ui/transparent-accent-color-001.html
new file mode 100644
index 0000000..219e24c1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/transparent-accent-color-001.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<title>CSS Basic User Interface Test: transparent accent color</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
+<link rel="help" href="https://drafts.csswg.org/css-ui-4/#widget-accent">
+<link rel="match" href="reference/transparent-accent-color-001-ref.html">
+<meta name="assert" content="If the color supplied is partially or fully transparent, it is precomposed over white when in light mode.">
+<style>
+
+div {
+    border: solid orange;
+    padding: 1ch;
+    margin: 1ch;
+    float: left;
+}
+
+#t1 input { color-scheme: light;}
+#t1 .test { accent-color: #ff000000;}
+#t1 .ref { accent-color: white; }
+
+#t2 input { color-scheme: light;}
+#t2 .test { accent-color: #0000ff80;}
+#t2 .ref { accent-color: #7f7fff; }
+
+#t3 { background: orange;}
+#t3 input { color-scheme: light;}
+#t3 .test { accent-color: #0000ff80;}
+#t3 .ref { accent-color: #7f7fff; }
+
+</style>
+
+<p>Test passes if in each box bellow, you see a pair of identically colored check-boxes.
+
+<div id=t1>
+  <input class=test type=checkbox checked>
+  <input class=ref type=checkbox checked>
+</div>
+
+<div id=t2>
+  <input class=test type=checkbox checked>
+  <input class=ref type=checkbox checked>
+</div>
+
+<div id=t3>
+  <input class=test type=checkbox checked>
+  <input class=ref type=checkbox checked>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/transparent-accent-color-002.html b/third_party/blink/web_tests/external/wpt/css/css-ui/transparent-accent-color-002.html
new file mode 100644
index 0000000..46b9835d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/transparent-accent-color-002.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<title>CSS Basic User Interface Test: transparent accent color</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
+<link rel="help" href="https://drafts.csswg.org/css-ui-4/#widget-accent">
+<link rel="match" href="reference/transparent-accent-color-002-ref.html">
+<meta name="assert" content="If the color supplied is partially or fully transparent, it is precomposed over black when in dark mode.">
+<style>
+
+div {
+    border: solid orange;
+    padding: 1ch;
+    margin: 1ch;
+    float: left;
+}
+
+#t1 input { color-scheme: dark;}
+#t1 .test { accent-color: #ff000000;}
+#t1 .ref { accent-color: black; }
+
+#t2 input { color-scheme: dark;}
+#t2 .test { accent-color: #0000ff80;}
+#t2 .ref { accent-color: #00007f; }
+
+#t3 { background: orange;}
+#t3 input { color-scheme: dark;}
+#t3 .test { accent-color: #0000ff80;}
+#t3 .ref { accent-color: #00007f; }
+
+</style>
+
+<p>Test passes if in each box bellow, you see a pair of identically colored check-boxes.
+
+<div id=t1>
+  <input class=test type=checkbox checked>
+  <input class=ref type=checkbox checked>
+</div>
+
+<div id=t2>
+  <input class=test type=checkbox checked>
+  <input class=ref type=checkbox checked>
+</div>
+
+<div id=t3>
+  <input class=test type=checkbox checked>
+  <input class=ref type=checkbox checked>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/resources/simultaneousScrollIntoViews.js b/third_party/blink/web_tests/external/wpt/css/cssom-view/resources/simultaneousScrollIntoViews.js
new file mode 100644
index 0000000..f3d02d25
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/cssom-view/resources/simultaneousScrollIntoViews.js
@@ -0,0 +1,51 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+async function reset(t, scrollers) {
+  for (const scroller of scrollers) {
+    await waitForScrollReset(t, scroller);
+  }
+}
+
+/**
+ * This tests executing scrollIntoView on multiple scroll containers at the same
+ * time. It assumes and verifies vertical scrolling.
+ */
+async function simultaneousScrollIntoViewsTest(test,
+                                               behaviors,
+                                               targets,
+                                               scrollers,
+                                               target_offsets) {
+  assert_equals(targets.length, behaviors.length,
+    "equal numbers of targets and behaviors provided");
+  assert_equals(scrollers.length, target_offsets.length,
+    "equal numbers of scrollers and target_offsets provided");
+  await reset(test, scrollers);
+  await waitForCompositorCommit();
+
+  // All scrollers should be at an offset of 0.
+  for (const scroller of scrollers) {
+    assert_equals(scroller.scrollTop, 0, `${scroller.id}'s scrollTop is reset`);
+  }
+
+  const scrollend_promises = Array.from(scrollers, (scroller) => {
+    return waitForScrollEnd(scroller);
+  });
+
+  // Scroll all targets into view.
+  for (let idx = 0; idx < targets.length; idx++) {
+    targets[idx].scrollIntoView({
+      block: "start",
+      behavior: behaviors[idx]
+    });
+  }
+  await Promise.all(scrollend_promises);
+
+  // Verify the expected positions os all scrollers.
+  for (let idx = 0; idx < scrollers.length; idx++) {
+    assert_approx_equals(scrollers[idx].scrollTop, target_offsets[idx], 1,
+      `scrollIntoView finished executing on ${scrollers[idx].id}`
+    );
+  }
+}
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/scrollIntoView-multiple-nested.html b/third_party/blink/web_tests/external/wpt/css/cssom-view/scrollIntoView-multiple-nested.html
new file mode 100644
index 0000000..630cd21
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/cssom-view/scrollIntoView-multiple-nested.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSSOM View - Simultaneous scrollIntoViews</title>
+    <link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollintoview">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/dom/events/scrolling/scroll_support.js"></script>
+    <script src="/css/css-scroll-snap/support/common.js"></script>
+    <script src="resources/simultaneousScrollIntoViews.js"></script>
+  </head>
+  <body>
+    <style>
+      .scroller {
+        overflow-y: scroll;
+        background-color: teal;
+        border: solid 1px black;
+        position: relative;
+        resize: both;
+        display: inline-block;
+      }
+      .scroller.outer {
+        height: 400px;
+        width: 400px;
+      }
+      .scroller.inner {
+        height: 200px;
+        width: 200px;
+        position: absolute;
+        top: 150%;
+      }
+      .space {
+        height: 200vh;
+        width: 200vw;
+      }
+      .box {
+        height: 50px;
+        width: 50px;
+        background-color: purple;
+      }
+      .target {
+        position: absolute;
+        top: 150%;
+      }
+    </style>
+    <div id="outerscroller1" class="outer scroller">
+      <div class="space"></div>
+      <div id="innerscroller1" class="inner scroller">
+        <div class="space"></div>
+        <div class="box target" id="target1"></div>
+      </div>
+    </div>
+    <div id="outerscroller2" class="outer scroller">
+      <div class="space"></div>
+      <div id="innerscroller2" class="inner scroller">
+        <div class="space"></div>
+        <div class="box target" id="target2"></div>
+      </div>
+    </div>
+    <script>
+      const outerscroller1 = document.getElementById("outerscroller1");
+      const outerscroller2 = document.getElementById("outerscroller2");
+      const innerscroller1 = document.getElementById("innerscroller1");
+      const innerscroller2 = document.getElementById("innerscroller2");
+      const target1 = document.getElementById("target1");
+      const target2 = document.getElementById("target2");
+
+      const scrollers = [ outerscroller1,
+                          outerscroller2,
+                          innerscroller1,
+                          innerscroller2 ];
+      // Expect the outer scrollers to scroll to the inner scrollers
+      // and the inner scrollers to scroll to their respective targets.
+      const target_offsets = [ innerscroller1.offsetTop,
+                               innerscroller2.offsetTop,
+                               target1.offsetTop,
+                               target2.offsetTop ];
+      promise_test(async (t) => {
+        await simultaneousScrollIntoViewsTest(t,
+          ["smooth", "smooth"], [target1, target2], scrollers, target_offsets);
+      }, "Simultaneous smooth scrollIntoViews run to completion");
+
+      promise_test(async (t) => {
+        await simultaneousScrollIntoViewsTest(t,
+          ["smooth", "instant"], [target1, target2], scrollers, target_offsets);
+      }, "Simultaneous smooth,instant scrollIntoViews run to completion");
+
+      promise_test(async (t) => {
+        await simultaneousScrollIntoViewsTest(t,
+          ["instant", "smooth"], [target1, target2], scrollers, target_offsets);
+      }, "Simultaneous instant,smooth scrollIntoViews run to completion");
+
+      promise_test(async (t) => {
+        await simultaneousScrollIntoViewsTest(t,
+          ["instant", "instant"], [target1, target2], scrollers, target_offsets);
+      }, "Simultaneous instant scrollIntoViews run to completion");
+    </script>
+  </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/scrollIntoView-multiple.html b/third_party/blink/web_tests/external/wpt/css/cssom-view/scrollIntoView-multiple.html
new file mode 100644
index 0000000..e6ddd181
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/cssom-view/scrollIntoView-multiple.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSSOM View - Simultaneous scrollIntoViews</title>
+    <link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollintoview">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/dom/events/scrolling/scroll_support.js"></script>
+    <script src="/css/css-scroll-snap/support/common.js"></script>
+    <script src="resources/simultaneousScrollIntoViews.js"></script>
+  </head>
+  <body>
+    <style>
+      .scroller {
+        overflow-y: scroll;
+        height: 200px;
+        width: 200px;
+        background-color: teal;
+        border: solid 1px black;
+        position: relative;
+        display: inline-block;
+      }
+      .space {
+        height: 200vh;
+        width: 200vw;
+      }
+      .box {
+        height: 50px;
+        width: 50px;
+        background-color: purple;
+      }
+      .target {
+        position: absolute;
+        top: 150%;
+      }
+    </style>
+    <div id="scroller1" class="scroller">
+      <div class="space"></div>
+      <div class="box target" id="target1"></div>
+    </div>
+    <div id="scroller2" class="scroller">
+      <div class="space"></div>
+      <div class="box target" id="target2"></div>
+    </div>
+    <script>
+      const scroller1 = document.getElementById("scroller1");
+      const scroller2 = document.getElementById("scroller2");
+      const target1 = document.getElementById("target1");
+      const target2 = document.getElementById("target2");
+
+      const targets = [target1, target2];
+      const scrollers = [scroller1, scroller2];
+      const target_offsets = [target1.offsetTop, target2.offsetTop];
+
+      promise_test(async (t) => {
+        await simultaneousScrollIntoViewsTest(t,
+                                    ["smooth", "smooth"],
+                                    targets,
+                                    scrollers,
+                                    target_offsets);
+      }, "Simultaneous smooth scrollIntoViews run to completion");
+
+      promise_test(async (t) => {
+        await simultaneousScrollIntoViewsTest(t,
+                                    ["smooth", "instant"],
+                                    targets,
+                                    scrollers,
+                                    target_offsets);
+      }, "Simultaneous smooth,instant scrollIntoViews run to completion");
+
+      promise_test(async (t) => {
+        await simultaneousScrollIntoViewsTest(t,
+                                    ["instant", "smooth"],
+                                    targets,
+                                    scrollers,
+                                    target_offsets);
+      }, "Simultaneous instant,smooth scrollIntoViews run to completion");
+
+      promise_test(async (t) => {
+        await simultaneousScrollIntoViewsTest(t,
+                                    ["instant", "instant"],
+                                    targets,
+                                    scrollers,
+                                    target_offsets);
+      }, "Simultaneous instant scrollIntoViews run to completion");
+    </script>
+  </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/scrollIntoView-smooth.html b/third_party/blink/web_tests/external/wpt/css/cssom-view/scrollIntoView-smooth.html
index ddfa3107..324e51d7 100644
--- a/third_party/blink/web_tests/external/wpt/css/cssom-view/scrollIntoView-smooth.html
+++ b/third_party/blink/web_tests/external/wpt/css/cssom-view/scrollIntoView-smooth.html
@@ -1,6 +1,8 @@
 <!DOCTYPE HTML>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="/css/css-scroll-snap/support/common.js"></script>
+<script src="/dom/events/scrolling/scroll_support.js"></script>
 <title>Check End Position of smooth scrollIntoView</title>
 <div id="container" style="height: 2500px; width: 2500px;">
   <div id="content" style="height: 500px; width: 500px;margin-left: 1000px; margin-right: 1000px; margin-top: 1000px;margin-bottom: 1000px;background-color: red">
@@ -15,93 +17,63 @@
 var content = document.getElementById("content");
 add_completion_callback(() => document.getElementById("container").remove());
 
-function waitForScrollEnd() {
-  var wait_for_scroll_start = performance.now();
-  var last_changed_timestamp = wait_for_scroll_start;
-  var last_changed_frame = 0;
-  var last_x = window.scrollX;
-  var last_y = window.scrollY;
-  return new Promise((resolve, reject) => {
-    function tick(frames, timestamp) {
-      // We requestAnimationFrame until at least 200ms have elapsed and at least
-      // 5 animation frames have run since the last change to the scroll
-      // offset, timing out after 8 seconds.
-      if (window.scrollX != last_x || window.scrollY != last_y) {
-        last_changed_timestamp = timestamp;
-        last_changed_frame = frames;
-        last_x = window.scrollX;
-        last_y = window.scrollY;
-      }
-      if (timestamp - last_changed_timestamp > 200 &&
-          frames - last_changed_frame > 4) {
-        resolve();
-      } else if (timestamp - wait_for_scroll_start > 8000) {
-        reject();
-      } else {
-        requestAnimationFrame(tick.bind(null, frames + 1));
-      }
-    }
-    tick(last_changed_frame, wait_for_scroll_start);
-  });
-}
-
 // When testing manually, we need an additional frame at beginning
 // to trigger the effect.
 requestAnimationFrame(() => {
-promise_test(t => {
-  window.scrollTo(0, 0);
+promise_test(async (t) => {
+  await waitForScrollReset(t, document.scrollingElement);
   var expected_x = content.offsetLeft + content_width - window_width;
   var expected_y = content.offsetTop + content_height - window_height;
   assert_not_equals(window.scrollX, expected_x, "scrollX");
   assert_not_equals(window.scrollY, expected_y, "scrollY");
+  const scrollend_promise = waitForScrollEnd(document);
   content.scrollIntoView({behavior: "smooth", block: "nearest", inline:
 "nearest"});
-  return waitForScrollEnd().then(() => {
-    assert_approx_equals(window.scrollX, expected_x, 1, "scrollX");
-    assert_approx_equals(window.scrollY, expected_y, 1, "scrollY");
-  });
+  await scrollend_promise;
+  assert_approx_equals(window.scrollX, expected_x, 1, "scrollX");
+  assert_approx_equals(window.scrollY, expected_y, 1, "scrollY");
 }, "Smooth scrollIntoView should scroll the element to the 'nearest' position");
 
-promise_test(t => {
-  window.scrollTo(0, 0);
+promise_test(async (t) => {
+  await waitForScrollReset(t, document.scrollingElement);
   var expected_x = content.offsetLeft;
   var expected_y = content.offsetTop;
   assert_not_equals(window.scrollX, expected_x, "scrollX");
   assert_not_equals(window.scrollY, expected_y, "scrollY");
+  const scrollend_promise = waitForScrollEnd(document);
   content.scrollIntoView({behavior: "smooth", block: "start", inline:
 "start"});
-  return waitForScrollEnd().then(() => {
-    assert_approx_equals(window.scrollX, expected_x, 1, "scrollX");
-    assert_approx_equals(window.scrollY, expected_y, 1, "scrollY");
-  });
+  await scrollend_promise;
+  assert_approx_equals(window.scrollX, expected_x, 1, "scrollX");
+  assert_approx_equals(window.scrollY, expected_y, 1, "scrollY");
 }, "Smooth scrollIntoView should scroll the element to the 'start' position");
 
-promise_test(t => {
-  window.scrollTo(0, 0);
+promise_test(async (t) => {
+  await waitForScrollReset(t, document.scrollingElement);
   var expected_x = content.offsetLeft + (content_width - window_width) / 2;
   var expected_y = content.offsetTop + (content_height - window_height) / 2;
   assert_not_equals(window.scrollX, expected_x, "scrollX");
   assert_not_equals(window.scrollY, expected_y, "scrollY");
+  const scrollend_promise = waitForScrollEnd(document);
   content.scrollIntoView({behavior: "smooth", block: "center", inline:
 "center"});
-  return waitForScrollEnd().then(() => {
-    assert_approx_equals(window.scrollX, expected_x, 1, "scrollX");
-    assert_approx_equals(window.scrollY, expected_y, 1, "scrollY");
-  });
+  await scrollend_promise;
+  assert_approx_equals(window.scrollX, expected_x, 1, "scrollX");
+  assert_approx_equals(window.scrollY, expected_y, 1, "scrollY");
 }, "Smooth scrollIntoView should scroll the element to the 'center' position");
 
-promise_test(t => {
-  window.scrollTo(0, 0);
+promise_test(async (t) => {
+  await waitForScrollReset(t, document.scrollingElement);
   var expected_x = content.offsetLeft + content_width - window_width;
   var expected_y = content.offsetTop + content_height - window_height;
   assert_not_equals(window.scrollX, expected_x, "scrollX");
   assert_not_equals(window.scrollY, expected_y, "scrollY");
+  const scrollend_promise = waitForScrollEnd(document);
   content.scrollIntoView({behavior: "smooth", block: "end", inline:
 "end"});
-  return waitForScrollEnd().then(() => {
-    assert_approx_equals(window.scrollX, expected_x, 1, "scrollX");
-    assert_approx_equals(window.scrollY, expected_y, 1, "scrollY");
-  });
+  await scrollend_promise;
+  assert_approx_equals(window.scrollX, expected_x, 1, "scrollX");
+  assert_approx_equals(window.scrollY, expected_y, 1, "scrollY");
 }, "Smooth scrollIntoView should scroll the element to the 'end' position");
 
 });
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/smooth-scroll-nonstop-expected.txt b/third_party/blink/web_tests/external/wpt/css/cssom-view/smooth-scroll-nonstop-expected.txt
deleted file mode 100644
index 7cf4f26..0000000
--- a/third_party/blink/web_tests/external/wpt/css/cssom-view/smooth-scroll-nonstop-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-[FAIL] noop scrollIntoView doesn't interrupt ongoing smooth scroll.
-  assert_equals: scroller reached the target offset expected 400 but got 0
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/smooth-scrollIntoView-with-smooth-fragment-scroll-iframe.html b/third_party/blink/web_tests/external/wpt/css/cssom-view/smooth-scrollIntoView-with-smooth-fragment-scroll-iframe.html
new file mode 100644
index 0000000..26dbdd2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/cssom-view/smooth-scrollIntoView-with-smooth-fragment-scroll-iframe.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <style>
+      * {
+        scroll-behavior: smooth;
+      }
+      .scroller {
+        overflow-y: scroll;
+        height: 200px;
+        width: 200px;
+        background-color: teal;
+        border: solid 1px black;
+        position: relative;
+        display: inline-block;
+      }
+      .space {
+        height: 200vh;
+        width: 200vw;
+      }
+      .box {
+        height: 50px;
+        width: 50px;
+        background-color: purple;
+      }
+      .target {
+        position: absolute;
+        top: 150%;
+      }
+    </style>
+    <div id="fragment_scroll_container" class="scroller">
+      <div class="space"></div>
+      <div class="box target" id="fragment_scroll_target">target</div>
+    </div>
+    <div id="scrollintoview_container" class="scroller">
+      <div class="space"></div>
+      <div class="box target" id="scrollintoview_target"></div>
+    </div>
+    <a id="fragment_link" href="#fragment_scroll_target">Scroll To Fragment</a>
+    </style>
+    <script>
+      const fragment_scroll_container =
+        document.getElementById("fragment_scroll_container");
+      const scrollintoview_container =
+        document.getElementById("scrollintoview_container");
+      const scrollintoview_target =
+        document.getElementById("scrollintoview_target");
+      const parent = window.parent;
+
+      // Post a message to the parent frame when the scroll ends to the test can
+      // proceed.
+      scrollintoview_container.addEventListener("scrollend", () => {
+          parent.postMessage("ready");
+        }, { once: true });
+
+      // Start a scroll on the scrollintoview container as soon as we start
+      // scrolling the fragment's container.
+      fragment_scroll_container.addEventListener("scroll", () => {
+        scrollintoview_target.scrollIntoView({ behavior: "smooth" });
+      }, { once: true });
+    </script>
+  </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/smooth-scrollIntoView-with-smooth-fragment-scroll.html b/third_party/blink/web_tests/external/wpt/css/cssom-view/smooth-scrollIntoView-with-smooth-fragment-scroll.html
new file mode 100644
index 0000000..72ecdf1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/cssom-view/smooth-scrollIntoView-with-smooth-fragment-scroll.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSSOM View - Smooth scrollIntoView + smooth scroll to fragment</title>
+    <link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollintoview">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/dom/events/scrolling/scroll_support.js"></script>
+  </head>
+  <body>
+    <style>
+      iframe {
+        width: 100vw;
+        height: 100vh;
+      }
+    </style>
+    <script>
+      let frame = null;
+      async function test_smooth_scrollintoview_with_smooth_fragment() {
+        return new Promise((resolve) => {
+          window.addEventListener("message", (evt) => {
+            assert_equals(evt.data, "ready");
+
+            // Check that the fragment scroll completed.
+            const fragment_scroll_container =
+              frame.contentDocument.getElementById("fragment_scroll_container");
+            const fragment_scroll_target =
+              frame.contentDocument.getElementById("fragment_scroll_target");
+            assert_approx_equals(fragment_scroll_container.scrollTop,
+              fragment_scroll_target.offsetTop, 1,
+              "scroll to fragment was completed");
+
+            // Check that the scrollIntoView completed.
+            const scrollintoview_container =
+              frame.contentDocument.getElementById("scrollintoview_container");
+            const scrollintoview_target =
+              frame.contentDocument.getElementById("scrollintoview_target");
+            assert_approx_equals(scrollintoview_container.scrollTop,
+              scrollintoview_target.offsetTop, 1,
+              "scrollIntoView was completed");
+
+            resolve();
+          });
+        });
+      }
+
+      promise_test(async (t) =>  {
+        frame = document.createElement("iframe");
+        let test_complete_promise =
+          test_smooth_scrollintoview_with_smooth_fragment();
+        frame.src =
+          "smooth-scrollIntoView-with-smooth-fragment-scroll-iframe.html" +
+          "#fragment_scroll_target";
+        document.documentElement.appendChild(frame);
+        await test_complete_promise;
+        frame.src = "";
+        frame.remove();
+      }, "Smooth scroll to hash fragment (on pageload) alongside smooth " +
+         "scrollIntoView runs to completion.");
+
+      promise_test(async (t) =>  {
+        frame = document.createElement("iframe");
+        const iframe_load_promise = new Promise((resolve) => {
+          frame.addEventListener("load", resolve);
+        });
+        const test_complete_promise =
+          test_smooth_scrollintoview_with_smooth_fragment();
+        frame.src =
+          "smooth-scrollIntoView-with-smooth-fragment-scroll-iframe.html";
+        document.documentElement.appendChild(frame);
+        await iframe_load_promise;
+        const link = frame.contentDocument.getElementById("fragment_link");
+        link.click();
+        await test_complete_promise;
+        frame.src = "";
+        frame.remove();
+      }, "Smooth scroll to hash fragment (on click) alongside smooth " +
+         "scrollIntoView runs to completion.");
+    </script>
+  </body>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/smooth-scrollIntoView-with-unrelated-gesture-scroll.html b/third_party/blink/web_tests/external/wpt/css/cssom-view/smooth-scrollIntoView-with-unrelated-gesture-scroll.html
new file mode 100644
index 0000000..f42fcb2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/cssom-view/smooth-scrollIntoView-with-unrelated-gesture-scroll.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>CSSOM View - Unrelated scroll gesture while scrollIntoView is ongoing</title>
+    <link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollintoview">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/resources/testdriver.js"></script>
+    <script src="/resources/testdriver-actions.js"></script>
+    <script src="/resources/testdriver-vendor.js"></script>
+    <script src="/css/css-scroll-snap/support/common.js"></script>
+    <script src="/dom/events/scrolling/scroll_support.js"></script>
+  </head>
+  <body>
+    <style>
+      .scroller {
+        overflow-y: scroll;
+        height: 200px;
+        width: 200px;
+        background-color: teal;
+        border: solid 1px black;
+        position: relative;
+        display: inline-block;
+      }
+      .space {
+        height: 200vh;
+        width: 200vw;
+      }
+      .box {
+        height: 50px;
+        width: 50px;
+        background-color: purple;
+      }
+      .target {
+        position: absolute;
+        top: 150%;
+      }
+    </style>
+    <div id="programmatic_scroller" class="scroller">
+      <div class="space"></div>
+      <div class="box target" id="target"></div>
+    </div>
+    <div id="gesture_scroller" class="scroller">
+      <div class="space"></div>
+    </div>
+    <script>
+      const programmatic_scroller =
+        document.getElementById("programmatic_scroller");
+      const gesture_scroller = document.getElementById("gesture_scroller");
+      const target = document.getElementById("target");
+
+      promise_test(async (t) => {
+        await waitForCompositorCommit();
+
+        const scrollend_promises = [
+          waitForScrollEnd(programmatic_scroller),
+          waitForScrollEnd(gesture_scroller)
+        ]
+        // As soon as we observe a scroll event, begin a gesture scroll on the
+        // second scroll container.
+        programmatic_scroller.addEventListener("scroll", async () => {
+          await new test_driver.Actions().scroll(0, 0, 0, 100,
+                                             { origin: gesture_scroller })
+                                         .send();
+        }, { once: true });
+
+        target.scrollIntoView({ behavior: "smooth" });
+
+        await Promise.all(scrollend_promises);
+
+        assert_equals(gesture_scroller.scrollTop, 100,
+          "gesture scroll completed");
+        assert_approx_equals(programmatic_scroller.scrollTop, target.offsetTop,
+          1, "scrollIntoView completed");
+      }, "scrollIntoView is not interrupted by unrelated gesture scroll");
+    </script>
+  </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/digital-credentials/identity-get.tentative.https.html b/third_party/blink/web_tests/external/wpt/digital-credentials/identity-get.tentative.https.html
index ba5212e..850533c 100644
--- a/third_party/blink/web_tests/external/wpt/digital-credentials/identity-get.tentative.https.html
+++ b/third_party/blink/web_tests/external/wpt/digital-credentials/identity-get.tentative.https.html
@@ -26,26 +26,6 @@
     return message.data;
 }
 
-// Builds a valid navigator.identity.get() request where IdentityRequestProvider#request is an object.
-function buildValidNavigatorIdentityRequestWithRequestObject() {
-  return {
-      digital: {
-        providers: [{
-          protocol: "urn:openid.net:oid4vp",
-          request: {
-            // Based on https://github.com/openid/OpenID4VP/issues/125
-            client_id: "client.example.org",
-            client_id_scheme: "web-origin",
-            nonce: "n-0S6_WzA2Mj",
-            presentation_definition: {
-              // Presentation Exchange request, omitted for brevity
-            }
-          },
-        }],
-      },
-  };
-}
-
 // Requires browser to have mode where OS-presented digital-identity-prompt is
 // bypassed in favour of returning "fake_test_token" directly.
 promise_test(async t=>{
@@ -56,13 +36,6 @@
 
 promise_test(async t => {
   let request = buildValidNavigatorIdentityRequest();
-  let credential = await requestIdentityWithActivation(test_driver, request);
-  assert_equals("urn:openid.net:oid4vp", credential.protocol);
-  assert_equals("fake_test_token", credential.data);
-}, "navigator.identity.get() API works in toplevel frame.");
-
-promise_test(async t => {
-  let request = buildValidNavigatorIdentityRequest();
   request.digital.providers = undefined;
   await promise_rejects_js(t, TypeError, requestIdentityWithActivation(test_driver, request));
 }, "navigator.identity.get() API fails if DigitalCredentialRequestOptions::providers is not specified.");
@@ -73,46 +46,6 @@
   await promise_rejects_js(t, TypeError, requestIdentityWithActivation(test_driver, request));
 }, "navigator.identity.get() API fails if there are no providers.");
 
-promise_test(async t => {
-  let request = buildValidNavigatorIdentityRequest();
-  let providerCopy = structuredClone(request.digital.providers[0]);
-  request.digital.providers.push(providerCopy);
-  await promise_rejects_js(t, TypeError, requestIdentityWithActivation(test_driver, request));
-}, "navigator.identity.get() API fails if there is more than one provider.");
-
-promise_test(async t => {
-  const request = buildValidNavigatorIdentityRequestWithRequestObject();
-  let credential = await requestIdentityWithActivation(test_driver, request);
-  assert_equals("urn:openid.net:oid4vp", credential.protocol);
-  assert_equals("fake_test_token", credential.data);
-}, "navigator.identity.get() API succeeds when IdentityRequestProvider#request is an object instead of stringified JSON object");
-
-promise_test(async t => {
-  const request = buildValidNavigatorIdentityRequestWithRequestObject();
-  const largeList = [];
-  for (let i = 0; i < 1000000; ++i) {
-    largeList.push("Value " + i);
-  }
-  request.digital.providers[0].request.random = largeList;
-  await promise_rejects_js(t, TypeError, requestIdentityWithActivation(test_driver, request));
-}, "navigator.identity.get() API fails when IdentityRequestProvider#request object is too big");
-
-promise_test(async t=> {
-  let abortController = new AbortController();
-  let request = buildValidNavigatorIdentityRequest();
-  request.signal = abortController.signal;
-  let requestPromise = requestIdentityWithActivation(test_driver, request);
-  abortController.abort();
-  await promise_rejects_dom(t, "AbortError", requestPromise);
-}, "navigator.identity.get() promise is rejected when the page aborts the request.");
-
-promise_test(async t=> {
-  const message = await createIframeAndWaitForMessage(
-      t, basePath + "support/iframe.html");
-  assert_equals(message.result, "Pass");
-  assert_equals(message.data, "fake_test_token");
-}, "navigator.identity.get() succeeds in same-origin iframe");
-
 promise_test(async t=> {
   const message = await createIframeAndWaitForMessage(
       t, remoteBaseURL + "support/iframe.html");
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/scrolling/scrollend-event-fired-for-scrollIntoView.html b/third_party/blink/web_tests/external/wpt/dom/events/scrolling/scrollend-event-fired-for-scrollIntoView.html
index 8782b1df..40aa77f 100644
--- a/third_party/blink/web_tests/external/wpt/dom/events/scrolling/scrollend-event-fired-for-scrollIntoView.html
+++ b/third_party/blink/web_tests/external/wpt/dom/events/scrolling/scrollend-event-fired-for-scrollIntoView.html
@@ -108,10 +108,12 @@
     document.body.appendChild(out_div);
     await waitForCompositorCommit();
 
-    element_scrollend_arrived = false;
-    document_scrollend_arrived = false;
     inner_div.scrollIntoView({ inline: "end", block: "end", behavior: "auto" });
-    await waitFor(() => { return element_scrollend_arrived || document_scrollend_arrived; }, "Nested scrollIntoView did not receive scrollend event.");
+    const scrollend_events = [
+      waitForScrollendEventNoTimeout(out_div),
+      waitForScrollendEventNoTimeout(target_div)
+    ];
+    await Promise.all(scrollend_events);
     assert_equals(root_element.scrollLeft, 0, "Nested scrollIntoView root_element scrollLeft");
     assert_equals(root_element.scrollTop, 0, "Nested scrollIntoView root_element scrollTop");
     assert_equals(out_div.scrollLeft, 100, "Nested scrollIntoView out_div scrollLeft");
diff --git a/third_party/blink/web_tests/external/wpt/dom/parts/basic-dom-part-declarative-brace-syntax.tentative.html b/third_party/blink/web_tests/external/wpt/dom/parts/basic-dom-part-declarative-brace-syntax.tentative.html
index 3a43703..d60ace2 100644
--- a/third_party/blink/web_tests/external/wpt/dom/parts/basic-dom-part-declarative-brace-syntax.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/dom/parts/basic-dom-part-declarative-brace-syntax.tentative.html
@@ -58,11 +58,11 @@
 
 const template = document.getElementById('declarative');
 ['Main Document','Template','Clone','PartClone'].forEach(testCase => {
-  function assertIsComment(node,commentText) {
+  function assertIsComment(node, commentText) {
     assert_true(node instanceof Comment);
-    assert_equals(node.textContent,commentText);
+    // TODO(crbug.com/40271855): While developing alternative syntax, the comment might be empty or it might be "S"/"E".
+    assert_true(node.textContent === '' || node.textContent === commentText);
   }
-
   test((t) => {
     let doc,target,wrapper,cleanup;
     let expectDOMParts = true;
@@ -116,13 +116,13 @@
         assert_equals(root.getParts()[i].node,target.querySelector(`#nodepart${i}`));
       }
       const childPart1 = root.getParts()[0];
-      assertIsComment(childPart1.previousSibling,'');
-      assertIsComment(childPart1.nextSibling,'');
+      assertIsComment(childPart1.previousSibling,'S');
+      assertIsComment(childPart1.nextSibling,'E');
       const expectedChild1Parts = [{type:'ChildNodePart',metadata:[]}];
       assertEqualParts(childPart1.getParts(),expectedChild1Parts,0,'First level childpart should just have one child part');
       const childPart2 = childPart1.getParts()[0];
-      assertIsComment(childPart2.previousSibling,'');
-      assertIsComment(childPart2.nextSibling,'');
+      assertIsComment(childPart2.previousSibling,'S');
+      assertIsComment(childPart2.nextSibling,'E');
       const expectedChild2Parts = [{type:'NodePart',metadata:[]},{type:'AttributePart',metadata:[]}];
       assertEqualParts(childPart2.getParts(),expectedChild2Parts,0,'Second level childpart should have NodePart and AttributePart');
       assert_true(childPart2.getParts()[0].node instanceof HTMLSpanElement);
diff --git a/third_party/blink/web_tests/external/wpt/dom/parts/resources/domparts-utils.js b/third_party/blink/web_tests/external/wpt/dom/parts/resources/domparts-utils.js
index f8982de..d1da9fb 100644
--- a/third_party/blink/web_tests/external/wpt/dom/parts/resources/domparts-utils.js
+++ b/third_party/blink/web_tests/external/wpt/dom/parts/resources/domparts-utils.js
@@ -1,5 +1,6 @@
 function assertEqualParts(parts,partDescriptions,expectedParts,description) {
   assert_equals(parts.length,partDescriptions.length,`${description}: lengths differ`);
+  let nodePartIndx = 0, childNodePartIndx = 0;
   for(let i=0;i<parts.length;++i) {
     assert_true(parts[i] instanceof Part,`${description}: not a Part`);
     assert_true(parts[i] instanceof window[partDescriptions[i].type],`${description}: index ${i} expected ${partDescriptions[i].type}`);
@@ -8,7 +9,20 @@
     if (expectedParts) {
       // TODO(crbug.com/40271855): While developing alternative syntax, we aren't comparing equality of the Part objects:
       // assert_equals(parts[i],expectedParts[i],`${description}: index ${i} object equality`);
-      assert_equals(parts[i].root.getPartNode(i),parts[i].node || parts[i].previousSibling,'getPartNode() should return the same node as getParts().node/previousSibling');
+      if ('getNodePartNodes' in parts[i].root) {
+        switch (partDescriptions[i].type) {
+          case 'NodePart':
+            assert_equals(parts[i].root.getNodePartNodes()[nodePartIndx],parts[i].node,`getNodePartNodes() indx ${nodePartIndx} should match node from NodePart`);
+            nodePartIndx++;
+            break;
+          case 'ChildNodePart':
+            assert_equals(parts[i].root.getChildNodePartNodes()[childNodePartIndx],parts[i].previousSibling,`getChildNodePartNodes() indx ${childNodePartIndx} should match previousSibling from ChildNodePart`);
+            childNodePartIndx++;
+            assert_equals(parts[i].root.getChildNodePartNodes()[childNodePartIndx],parts[i].nextSibling,`getChildNodePartNodes() indx ${childNodePartIndx} should match nextSibling from ChildNodePart`);
+            childNodePartIndx++;
+            break;
+        }
+      }
     }
   }
 }
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/get-interest-group-auction-data.https.window.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/get-interest-group-auction-data.https.window.js
new file mode 100644
index 0000000..29f58ebe
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/get-interest-group-auction-data.https.window.js
@@ -0,0 +1,23 @@
+// META: script=/resources/testdriver.js
+// META: script=/common/utils.js
+// META: script=resources/fledge-util.sub.js
+// META: script=/common/subset-tests.js
+// META: timeout=long
+// META: variant=?1-4
+
+// These tests focus on the navigator.getInterestGroupAdAuctionData() method.
+
+subsetTest(promise_test, async test => {
+  const result = await navigator.getInterestGroupAdAuctionData({ seller: window.location.origin });
+  assert_true(result.requestId !== null);
+  assert_true(result.request.length === 0);
+}, 'getInterestGroupAdAuctionData() with no interest groups returns a zero length result.');
+
+subsetTest(promise_test, async test => {
+  const uuid = generateUuid(test);
+  await joinInterestGroup(test, uuid);
+
+  const result = await navigator.getInterestGroupAdAuctionData({ seller: window.location.origin });
+  assert_true(result.requestId !== null);
+  assert_true(result.request.length > 0);
+}, 'getInterestGroupAdAuctionData() with one interest group returns a non-zero length result.');
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/get-interest-group-auction-data.https.window_1-4-expected.txt b/third_party/blink/web_tests/external/wpt/fledge/tentative/get-interest-group-auction-data.https.window_1-4-expected.txt
new file mode 100644
index 0000000..1c03137
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/get-interest-group-auction-data.https.window_1-4-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] getInterestGroupAdAuctionData() with no interest groups returns a zero length result.
+  promise_test: Unhandled rejection with value: object "TypeError: navigator.getInterestGroupAdAuctionData is not a function"
+[FAIL] getInterestGroupAdAuctionData() with one interest group returns a non-zero length result.
+  promise_test: Unhandled rejection with value: object "TypeError: navigator.getInterestGroupAdAuctionData is not a function"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-context/2d.canvas.context.extraargs.cache.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-context/2d.canvas.context.extraargs.cache.html
index f4db408..236f17e 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-context/2d.canvas.context.extraargs.cache.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-context/2d.canvas.context.extraargs.cache.html
@@ -19,9 +19,9 @@
 var t = async_test("The 2D context doesn't throw with extra getContext arguments (cached)");
 _addTest(function(canvas, ctx) {
 
-  _assertDifferent(canvas.getContext('2d', false, {}, [], 1, "2"), null, "canvas.getContext('2d', false, {}, [], 1, \"2\")", "null");
+  _assertDifferent(canvas.getContext('2d', false, {}, [], 1, '2'), null, "canvas.getContext('2d', false, {}, [], 1, '2')", "null");
   _assertDifferent(canvas.getContext('2d', 123), null, "canvas.getContext('2d', 123)", "null");
-  _assertDifferent(canvas.getContext('2d', "test"), null, "canvas.getContext('2d', \"test\")", "null");
+  _assertDifferent(canvas.getContext('2d', 'test'), null, "canvas.getContext('2d', 'test')", "null");
   _assertDifferent(canvas.getContext('2d', undefined), null, "canvas.getContext('2d', undefined)", "null");
   _assertDifferent(canvas.getContext('2d', null), null, "canvas.getContext('2d', null)", "null");
   _assertDifferent(canvas.getContext('2d', Symbol.hasInstance), null, "canvas.getContext('2d', Symbol.hasInstance)", "null");
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-context/2d.canvas.context.extraargs.create.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-context/2d.canvas.context.extraargs.create.html
index 6ae7f78..b0b00dd 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-context/2d.canvas.context.extraargs.create.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-context/2d.canvas.context.extraargs.create.html
@@ -19,12 +19,12 @@
 var t = async_test("The 2D context doesn't throw with extra getContext arguments (new context)");
 _addTest(function(canvas, ctx) {
 
-  _assertDifferent(document.createElement("canvas").getContext('2d', false, {}, [], 1, "2"), null, "document.createElement(\"canvas\").getContext('2d', false, {}, [], 1, \"2\")", "null");
-  _assertDifferent(document.createElement("canvas").getContext('2d', 123), null, "document.createElement(\"canvas\").getContext('2d', 123)", "null");
-  _assertDifferent(document.createElement("canvas").getContext('2d', "test"), null, "document.createElement(\"canvas\").getContext('2d', \"test\")", "null");
-  _assertDifferent(document.createElement("canvas").getContext('2d', undefined), null, "document.createElement(\"canvas\").getContext('2d', undefined)", "null");
-  _assertDifferent(document.createElement("canvas").getContext('2d', null), null, "document.createElement(\"canvas\").getContext('2d', null)", "null");
-  _assertDifferent(document.createElement("canvas").getContext('2d', Symbol.hasInstance), null, "document.createElement(\"canvas\").getContext('2d', Symbol.hasInstance)", "null");
+  _assertDifferent(document.createElement('canvas').getContext('2d', false, {}, [], 1, "2"), null, "document.createElement('canvas').getContext('2d', false, {}, [], 1, \"2\")", "null");
+  _assertDifferent(document.createElement('canvas').getContext('2d', 123), null, "document.createElement('canvas').getContext('2d', 123)", "null");
+  _assertDifferent(document.createElement('canvas').getContext('2d', "test"), null, "document.createElement('canvas').getContext('2d', \"test\")", "null");
+  _assertDifferent(document.createElement('canvas').getContext('2d', undefined), null, "document.createElement('canvas').getContext('2d', undefined)", "null");
+  _assertDifferent(document.createElement('canvas').getContext('2d', null), null, "document.createElement('canvas').getContext('2d', null)", "null");
+  _assertDifferent(document.createElement('canvas').getContext('2d', Symbol.hasInstance), null, "document.createElement('canvas').getContext('2d', Symbol.hasInstance)", "null");
 
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-context/2d.canvas.context.prototype.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-context/2d.canvas.context.prototype.html
index 5d5edc686..18a37a18 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-context/2d.canvas.context.prototype.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-context/2d.canvas.context.prototype.html
@@ -21,7 +21,6 @@
 
   _assertSame(Object.getPrototypeOf(CanvasRenderingContext2D.prototype), Object.prototype, "Object.getPrototypeOf(CanvasRenderingContext2D.prototype)", "Object.prototype");
   _assertSame(Object.getPrototypeOf(ctx), CanvasRenderingContext2D.prototype, "Object.getPrototypeOf(ctx)", "CanvasRenderingContext2D.prototype");
-  t.done();
 
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.name.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.color.html
similarity index 63%
copy from third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.name.html
copy to third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.color.html
index fdf1d1d3..795804a 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.name.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.color.html
@@ -1,14 +1,14 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: type.name</title>
+<title>Canvas test: 2d.canvas.host.initial.color</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>type.name</h1>
-<p class="desc">HTMLCanvasElement type and toString</p>
+<h1>2d.canvas.host.initial.color</h1>
+<p class="desc">Initial state is transparent black</p>
 
 
 <p class="output">Actual output:</p>
@@ -16,11 +16,10 @@
 
 <ul id="d"></ul>
 <script>
-var t = async_test("HTMLCanvasElement type and toString");
+var t = async_test("Initial state is transparent black");
 _addTest(function(canvas, ctx) {
 
-_assertSame(Object.prototype.toString.call(canvas), '[object HTMLCanvasElement]', "Object.prototype.toString.call(canvas)", "'[object HTMLCanvasElement]'");
-
+  _assertPixel(canvas, 20,20, 0,0,0,0);
 
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.clip.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.clip.html
similarity index 66%
rename from third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.clip.html
rename to third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.clip.html
index ebf52bf..86da296 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.clip.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.clip.html
@@ -1,32 +1,32 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: initial.reset.clip</title>
+<title>Canvas test: 2d.canvas.host.initial.reset.clip</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>initial.reset.clip</h1>
+<h1>2d.canvas.host.initial.reset.clip</h1>
 <p class="desc">Resetting the canvas state resets the current clip region</p>
 
 
 <p class="output">Actual output:</p>
 <canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+
 <ul id="d"></ul>
 <script>
 var t = async_test("Resetting the canvas state resets the current clip region");
 _addTest(function(canvas, ctx) {
 
-canvas.width = 100;
-ctx.rect(0, 0, 1, 1);
-ctx.clip();
-canvas.width = 100;
-ctx.fillStyle = '#0f0';
-ctx.fillRect(0, 0, 100, 50);
-_assertPixel(canvas, 20,20, 0,255,0,255);
-
+  canvas.width = 100;
+  ctx.rect(0, 0, 1, 1);
+  ctx.clip();
+  canvas.width = 100;
+  ctx.fillStyle = '#0f0';
+  ctx.fillRect(0, 0, 100, 50);
+  _assertPixel(canvas, 20,20, 0,255,0,255);
 
 });
 </script>
+
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.different.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.different.html
similarity index 66%
rename from third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.different.html
rename to third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.different.html
index d55dd25..b95527083 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.different.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.different.html
@@ -1,30 +1,30 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: initial.reset.different</title>
+<title>Canvas test: 2d.canvas.host.initial.reset.different</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>initial.reset.different</h1>
+<h1>2d.canvas.host.initial.reset.different</h1>
 <p class="desc">Changing size resets canvas to transparent black</p>
 
 
 <p class="output">Actual output:</p>
 <canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-<p class="output expectedtext">Expected output:<p><img src="initial.reset.different.png" class="output expected" id="expected" alt="">
+
 <ul id="d"></ul>
 <script>
 var t = async_test("Changing size resets canvas to transparent black");
 _addTest(function(canvas, ctx) {
 
-ctx.fillStyle = '#f00';
-ctx.fillRect(0, 0, 50, 50);
-_assertPixel(canvas, 20,20, 255,0,0,255);
-canvas.width = 50;
-_assertPixel(canvas, 20,20, 0,0,0,0);
-
+  ctx.fillStyle = '#f00';
+  ctx.fillRect(0, 0, 50, 50);
+  _assertPixel(canvas, 20,20, 255,0,0,255);
+  canvas.width = 50;
+  _assertPixel(canvas, 20,20, 0,0,0,0);
 
 });
 </script>
+
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.gradient.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.gradient.html
similarity index 60%
rename from third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.gradient.html
rename to third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.gradient.html
index 31b56ec8..de0f19c 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.gradient.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.gradient.html
@@ -1,35 +1,35 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: initial.reset.gradient</title>
+<title>Canvas test: 2d.canvas.host.initial.reset.gradient</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>initial.reset.gradient</h1>
+<h1>2d.canvas.host.initial.reset.gradient</h1>
 <p class="desc">Resetting the canvas state does not invalidate any existing gradients</p>
 
 
 <p class="output">Actual output:</p>
 <canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+
 <ul id="d"></ul>
 <script>
 var t = async_test("Resetting the canvas state does not invalidate any existing gradients");
 _addTest(function(canvas, ctx) {
 
-canvas.width = 50;
-var g = ctx.createLinearGradient(0, 0, 100, 0);
-g.addColorStop(0, '#0f0');
-g.addColorStop(1, '#0f0');
-canvas.width = 100;
-ctx.fillStyle = '#f00';
-ctx.fillRect(0, 0, 100, 50);
-ctx.fillStyle = g;
-ctx.fillRect(0, 0, 100, 50);
-_assertPixel(canvas, 50,25, 0,255,0,255);
-
+  canvas.width = 50;
+  var g = ctx.createLinearGradient(0, 0, 100, 0);
+  g.addColorStop(0, '#0f0');
+  g.addColorStop(1, '#0f0');
+  canvas.width = 100;
+  ctx.fillStyle = '#f00';
+  ctx.fillRect(0, 0, 100, 50);
+  ctx.fillStyle = g;
+  ctx.fillRect(0, 0, 100, 50);
+  _assertPixel(canvas, 50,25, 0,255,0,255);
 
 });
 </script>
+
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.path.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.path.html
similarity index 68%
rename from third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.path.html
rename to third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.path.html
index 3525377d..6eda186d 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.path.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.path.html
@@ -1,31 +1,31 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: initial.reset.path</title>
+<title>Canvas test: 2d.canvas.host.initial.reset.path</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>initial.reset.path</h1>
+<h1>2d.canvas.host.initial.reset.path</h1>
 <p class="desc">Resetting the canvas state resets the current path</p>
 
 
 <p class="output">Actual output:</p>
 <canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-<p class="output expectedtext">Expected output:<p><img src="initial.reset.path.png" class="output expected" id="expected" alt="">
+
 <ul id="d"></ul>
 <script>
 var t = async_test("Resetting the canvas state resets the current path");
 _addTest(function(canvas, ctx) {
 
-canvas.width = 100;
-ctx.rect(0, 0, 100, 50);
-canvas.width = 100;
-ctx.fillStyle = '#f00';
-ctx.fill();
-_assertPixel(canvas, 20,20, 0,0,0,0);
-
+  canvas.width = 100;
+  ctx.rect(0, 0, 100, 50);
+  canvas.width = 100;
+  ctx.fillStyle = '#f00';
+  ctx.fill();
+  _assertPixel(canvas, 20,20, 0,0,0,0);
 
 });
 </script>
+
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.pattern.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.pattern.html
similarity index 60%
rename from third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.pattern.html
rename to third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.pattern.html
index 28f8306..3cb45257 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.pattern.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.pattern.html
@@ -1,35 +1,35 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: initial.reset.pattern</title>
+<title>Canvas test: 2d.canvas.host.initial.reset.pattern</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>initial.reset.pattern</h1>
+<h1>2d.canvas.host.initial.reset.pattern</h1>
 <p class="desc">Resetting the canvas state does not invalidate any existing patterns</p>
 
 
 <p class="output">Actual output:</p>
 <canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+
 <ul id="d"></ul>
 <script>
 var t = async_test("Resetting the canvas state does not invalidate any existing patterns");
 _addTest(function(canvas, ctx) {
 
-canvas.width = 30;
-ctx.fillStyle = '#0f0';
-ctx.fillRect(0, 0, 30, 50);
-var p = ctx.createPattern(canvas, 'repeat-x');
-canvas.width = 100;
-ctx.fillStyle = '#f00';
-ctx.fillRect(0, 0, 100, 50);
-ctx.fillStyle = p;
-ctx.fillRect(0, 0, 100, 50);
-_assertPixel(canvas, 50,25, 0,255,0,255);
-
+  canvas.width = 30;
+  ctx.fillStyle = '#0f0';
+  ctx.fillRect(0, 0, 30, 50);
+  var p = ctx.createPattern(canvas, 'repeat-x');
+  canvas.width = 100;
+  ctx.fillStyle = '#f00';
+  ctx.fillRect(0, 0, 100, 50);
+  ctx.fillStyle = p;
+  ctx.fillRect(0, 0, 100, 50);
+  _assertPixel(canvas, 50,25, 0,255,0,255);
 
 });
 </script>
+
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.same.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.same.html
similarity index 67%
rename from third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.same.html
rename to third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.same.html
index 1a0872b..6e2d912a 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.same.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.same.html
@@ -1,31 +1,31 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: initial.reset.same</title>
+<title>Canvas test: 2d.canvas.host.initial.reset.same</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>initial.reset.same</h1>
+<h1>2d.canvas.host.initial.reset.same</h1>
 <p class="desc">Setting size (not changing the value) resets canvas to transparent black</p>
 
 
 <p class="output">Actual output:</p>
 <canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-<p class="output expectedtext">Expected output:<p><img src="initial.reset.same.png" class="output expected" id="expected" alt="">
+
 <ul id="d"></ul>
 <script>
 var t = async_test("Setting size (not changing the value) resets canvas to transparent black");
 _addTest(function(canvas, ctx) {
 
-canvas.width = 100;
-ctx.fillStyle = '#f00';
-ctx.fillRect(0, 0, 50, 50);
-_assertPixel(canvas, 20,20, 255,0,0,255);
-canvas.width = 100;
-_assertPixel(canvas, 20,20, 0,0,0,0);
-
+  canvas.width = 100;
+  ctx.fillStyle = '#f00';
+  ctx.fillRect(0, 0, 50, 50);
+  _assertPixel(canvas, 20,20, 255,0,0,255);
+  canvas.width = 100;
+  _assertPixel(canvas, 20,20, 0,0,0,0);
 
 });
 </script>
+
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.transform.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.transform.html
similarity index 67%
rename from third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.transform.html
rename to third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.transform.html
index 36284ba49..d285785 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.transform.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.initial.reset.transform.html
@@ -1,31 +1,31 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: initial.reset.transform</title>
+<title>Canvas test: 2d.canvas.host.initial.reset.transform</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>initial.reset.transform</h1>
+<h1>2d.canvas.host.initial.reset.transform</h1>
 <p class="desc">Resetting the canvas state resets the current transformation matrix</p>
 
 
 <p class="output">Actual output:</p>
 <canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+
 <ul id="d"></ul>
 <script>
 var t = async_test("Resetting the canvas state resets the current transformation matrix");
 _addTest(function(canvas, ctx) {
 
-canvas.width = 100;
-ctx.scale(0.1, 0.1);
-canvas.width = 100;
-ctx.fillStyle = '#0f0';
-ctx.fillRect(0, 0, 100, 50);
-_assertPixel(canvas, 20,20, 0,255,0,255);
-
+  canvas.width = 100;
+  ctx.scale(0.1, 0.1);
+  canvas.width = 100;
+  ctx.fillStyle = '#0f0';
+  ctx.fillRect(0, 0, 100, 50);
+  _assertPixel(canvas, 20,20, 0,255,0,255);
 
 });
 </script>
+
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.readonly.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.readonly.html
index cbbf32f..44d9229 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.readonly.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.readonly.html
@@ -8,7 +8,7 @@
 <body class="show_output">
 
 <h1>2d.canvas.host.readonly</h1>
-<p class="desc">CanvasRenderingContext2D.canvas is readonly</p>
+<p class="desc">Canvas objects are readonly</p>
 
 
 <p class="output">Actual output:</p>
@@ -16,13 +16,13 @@
 
 <ul id="d"></ul>
 <script>
-var t = async_test("CanvasRenderingContext2D.canvas is readonly");
+var t = async_test("Canvas objects are readonly");
 _addTest(function(canvas, ctx) {
 
-  var c = document.createElement('canvas');
+  var canvas2 = document.createElement('canvas');
   var d = ctx.canvas;
-  _assertDifferent(c, d, "c", "d");
-  ctx.canvas = c;
+  _assertDifferent(canvas2, d, "canvas2", "d");
+  ctx.canvas = canvas2;
   _assertSame(ctx.canvas, d, "ctx.canvas", "d");
 
 });
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.reference.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.reference.html
index 6a4bdb65..f7166f9 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.reference.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.reference.html
@@ -8,7 +8,7 @@
 <body class="show_output">
 
 <h1>2d.canvas.host.reference</h1>
-<p class="desc">CanvasRenderingContext2D.canvas refers back to its canvas</p>
+<p class="desc">canvas refers back to its canvas</p>
 
 
 <p class="output">Actual output:</p>
@@ -16,7 +16,7 @@
 
 <ul id="d"></ul>
 <script>
-var t = async_test("CanvasRenderingContext2D.canvas refers back to its canvas");
+var t = async_test("canvas refers back to its canvas");
 _addTest(function(canvas, ctx) {
 
   _assertSame(ctx.canvas, canvas, "ctx.canvas", "canvas");
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.scaled-manual.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.scaled-manual.html
index acf3f9c7..930432a 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.scaled-manual.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.scaled-manual.html
@@ -12,7 +12,7 @@
 
 
 <p class="output">Actual output:</p>
-<canvas id="c" class="output" width="50" height="25" style="width: 100px; height: 50px"><p class="fallback">FAIL (fallback content)</p></canvas>
+<canvas id="c" class="output" width="50" height="25"style="width: 100px; height: 50px"><p class="fallback">FAIL (fallback content)</p></canvas>
 <p class="output expectedtext">Expected output:<p><img src="2d.canvas.host.scaled.png" class="output expected" id="expected" alt="">
 <ul id="d"></ul>
 <script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.name.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.default.html
similarity index 61%
copy from third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.name.html
copy to third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.default.html
index fdf1d1d3..c34b085a 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.name.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.default.html
@@ -1,14 +1,14 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: type.name</title>
+<title>Canvas test: 2d.canvas.host.size.attributes.default</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>type.name</h1>
-<p class="desc">HTMLCanvasElement type and toString</p>
+<h1>2d.canvas.host.size.attributes.default</h1>
+<p class="desc">Default width/height when attributes are missing</p>
 
 
 <p class="output">Actual output:</p>
@@ -16,11 +16,11 @@
 
 <ul id="d"></ul>
 <script>
-var t = async_test("HTMLCanvasElement type and toString");
+var t = async_test("Default width/height when attributes are missing");
 _addTest(function(canvas, ctx) {
 
-_assertSame(Object.prototype.toString.call(canvas), '[object HTMLCanvasElement]', "Object.prototype.toString.call(canvas)", "'[object HTMLCanvasElement]'");
-
+  _assertSame(canvas.width, 100, "canvas.width", "100");
+  _assertSame(canvas.height, 50, "canvas.height", "50");
 
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.idl.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.idl.html
new file mode 100644
index 0000000..38332cc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.idl.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.idl</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.idl</h1>
+<p class="desc">Getting/setting width/height IDL attributes</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Getting/setting width/height IDL attributes");
+_addTest(function(canvas, ctx) {
+
+  canvas.width = '100';
+  canvas.height = '100';
+  _assertSame(canvas.width, 100, "canvas.width", "100");
+  _assertSame(canvas.height, 100, "canvas.height", "100");
+  canvas.width = 301.999;
+  canvas.height = 301.001;
+  _assertSame(canvas.width, 301, "canvas.width", "301");
+  _assertSame(canvas.height, 301, "canvas.height", "301");
+  canvas.width = "+1.5e2";
+  canvas.height = "0x96";
+  _assertSame(canvas.width, 150, "canvas.width", "150");
+  _assertSame(canvas.height, 150, "canvas.height", "150");
+
+});
+</script>
+
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.idl.set.zero.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.idl.set.zero.html
similarity index 72%
rename from third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.idl.set.zero.html
rename to third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.idl.set.zero.html
index c09d5cb..e142ec6 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.idl.set.zero.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.idl.set.zero.html
@@ -1,13 +1,13 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: size.attributes.idl.set.zero</title>
+<title>Canvas test: 2d.canvas.host.size.attributes.idl.set.zero</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>size.attributes.idl.set.zero</h1>
+<h1>2d.canvas.host.size.attributes.idl.set.zero</h1>
 <p class="desc">Setting width/height IDL attributes to 0</p>
 
 
@@ -19,11 +19,10 @@
 var t = async_test("Setting width/height IDL attributes to 0");
 _addTest(function(canvas, ctx) {
 
-canvas.width = 0;
-canvas.height = 0;
-_assertSame(canvas.width, 0, "canvas.width", "0");
-_assertSame(canvas.height, 0, "canvas.height", "0");
-
+  canvas.width = 0;
+  canvas.height = 0;
+  _assertSame(canvas.width, 0, "canvas.width", "0");
+  _assertSame(canvas.height, 0, "canvas.height", "0");
 
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.reflect.setcontent.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.reflect.setcontent.html
new file mode 100644
index 0000000..2e2abae
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.reflect.setcontent.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.reflect.setcontent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.reflect.setcontent</h1>
+<p class="desc">Setting content attributes updates IDL and content attributes</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting content attributes updates IDL and content attributes");
+_addTest(function(canvas, ctx) {
+
+  canvas.setAttribute('width', '120');
+  canvas.setAttribute('height', '60');
+  _assertSame(canvas.getAttribute('width'), '120', "canvas.getAttribute('width')", "'120'");
+  _assertSame(canvas.getAttribute('height'), '60', "canvas.getAttribute('height')", "'60'");
+  _assertSame(canvas.width, 120, "canvas.width", "120");
+  _assertSame(canvas.height, 60, "canvas.height", "60");
+
+});
+</script>
+
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.reflect.setidl.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.reflect.setidl.html
new file mode 100644
index 0000000..d017070
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.reflect.setidl.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.attributes.reflect.setidl</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.attributes.reflect.setidl</h1>
+<p class="desc">Setting IDL attributes updates IDL and content attributes</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting IDL attributes updates IDL and content attributes");
+_addTest(function(canvas, ctx) {
+
+  canvas.width = 120;
+  canvas.height = 60;
+  _assertSame(canvas.width, 120, "canvas.width", "120");
+  _assertSame(canvas.height, 60, "canvas.height", "60");
+  _assertSame(canvas.getAttribute('width'), '120', "canvas.getAttribute('width')", "'120'");
+  _assertSame(canvas.getAttribute('height'), '60', "canvas.getAttribute('height')", "'60'");
+
+});
+</script>
+
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidlzero.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.reflect.setidlzero.html
similarity index 62%
rename from third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidlzero.html
rename to third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.reflect.setidlzero.html
index 65df3f9..d7747e1f1 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidlzero.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.reflect.setidlzero.html
@@ -1,13 +1,13 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: size.attributes.reflect.setidlzero</title>
+<title>Canvas test: 2d.canvas.host.size.attributes.reflect.setidlzero</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>size.attributes.reflect.setidlzero</h1>
+<h1>2d.canvas.host.size.attributes.reflect.setidlzero</h1>
 <p class="desc">Setting IDL attributes to 0 updates IDL and content attributes</p>
 
 
@@ -19,13 +19,12 @@
 var t = async_test("Setting IDL attributes to 0 updates IDL and content attributes");
 _addTest(function(canvas, ctx) {
 
-canvas.width = 0;
-canvas.height = 0;
-_assertSame(canvas.getAttribute('width'), '0', "canvas.getAttribute('width')", "'0'");
-_assertSame(canvas.getAttribute('height'), '0', "canvas.getAttribute('height')", "'0'");
-_assertSame(canvas.width, 0, "canvas.width", "0");
-_assertSame(canvas.height, 0, "canvas.height", "0");
-
+  canvas.width = 0;
+  canvas.height = 0;
+  _assertSame(canvas.getAttribute('width'), '0', "canvas.getAttribute('width')", "'0'");
+  _assertSame(canvas.getAttribute('height'), '0', "canvas.getAttribute('height')", "'0'");
+  _assertSame(canvas.width, 0, "canvas.width", "0");
+  _assertSame(canvas.height, 0, "canvas.height", "0");
 
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.removed.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.removed.html
similarity index 61%
rename from third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.removed.html
rename to third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.removed.html
index c96cba7b..15cf17c 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.removed.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.attributes.removed.html
@@ -1,28 +1,27 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: size.attributes.removed</title>
+<title>Canvas test: 2d.canvas.host.size.attributes.removed</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>size.attributes.removed</h1>
+<h1>2d.canvas.host.size.attributes.removed</h1>
 <p class="desc">Removing content attributes reverts to default size</p>
 
 
 <p class="output">Actual output:</p>
-<canvas id="c" class="output" width="120" height="60"><p class="fallback">FAIL (fallback content)</p></canvas>
-<p class="output expectedtext">Expected output:<p><img src="size.attributes.removed.png" class="output expected" id="expected" alt="">
+<canvas id="c" class="output" width="120" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
 <ul id="d"></ul>
 <script>
 var t = async_test("Removing content attributes reverts to default size");
 _addTest(function(canvas, ctx) {
 
-_assertSame(canvas.width, 120, "canvas.width", "120");
-canvas.removeAttribute('width');
-_assertSame(canvas.width, 300, "canvas.width", "300");
-
+  _assertSame(canvas.width, 120, "canvas.width", "120");
+  canvas.removeAttribute('width');
+  _assertSame(canvas.width, 300, "canvas.width", "300");
 
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.invalid.attributes.idl.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.invalid.attributes.idl.html
new file mode 100644
index 0000000..8711657f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.invalid.attributes.idl.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.invalid.attributes.idl</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.invalid.attributes.idl</h1>
+<p class="desc">Getting/setting width/height IDL attributes</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Getting/setting width/height IDL attributes");
+_addTest(function(canvas, ctx) {
+
+  canvas.width = 200 - Math.pow(2, 32);
+  canvas.height = 200 - Math.pow(2, 32);
+  _assertSame(canvas.width, 200, "canvas.width", "200");
+  _assertSame(canvas.height, 200, "canvas.height", "200");
+  canvas.width = '400x';
+  canvas.height = 'foo';
+  _assertSame(canvas.width, 0, "canvas.width", "0");
+  _assertSame(canvas.height, 0, "canvas.height", "0");
+
+});
+</script>
+
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.large.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.large.html
new file mode 100644
index 0000000..039949cf
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.size.large.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.host.size.large</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.host.size.large</h1>
+<p class="desc"></p>
+
+<p class="notes">Not sure how reasonable this is, but the spec doesn't say there's an upper limit on the size.
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+  var n = 2147483647; // 2^31 - 1, which should be supported by any sensible definition of "long"
+  canvas.width = n;
+  canvas.height = n;
+  _assertSame(canvas.width, n, "canvas.width", "n");
+  _assertSame(canvas.height, n, "canvas.height", "n");
+
+});
+</script>
+
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.delete.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.type.delete.html
similarity index 71%
rename from third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.delete.html
rename to third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.type.delete.html
index 7fd54b3..90f5c4c 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.delete.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.type.delete.html
@@ -1,16 +1,16 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: type.delete</title>
+<title>Canvas test: 2d.canvas.host.type.delete</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>type.delete</h1>
+<h1>2d.canvas.host.type.delete</h1>
 <p class="desc">window.HTMLCanvasElement interface object is [[Configurable]]</p>
 
-<p class="notes">Defined in "Web IDL" (draft)
+
 <p class="output">Actual output:</p>
 <canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
 
@@ -19,9 +19,8 @@
 var t = async_test("window.HTMLCanvasElement interface object is [[Configurable]]");
 _addTest(function(canvas, ctx) {
 
-_assertSame(delete window.HTMLCanvasElement, true, "delete window.HTMLCanvasElement", "true");
-_assertSame(window.HTMLCanvasElement, undefined, "window.HTMLCanvasElement", "undefined");
-
+  _assertSame(delete window.HTMLCanvasElement, true, "delete window.HTMLCanvasElement", "true");
+  _assertSame(window.HTMLCanvasElement, undefined, "window.HTMLCanvasElement", "undefined");
 
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.name.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.type.name.html
similarity index 73%
rename from third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.name.html
rename to third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.type.name.html
index fdf1d1d3..c0f93876 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.name.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/canvas-host/2d.canvas.host.type.name.html
@@ -1,13 +1,13 @@
 <!DOCTYPE html>
 <!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: type.name</title>
+<title>Canvas test: 2d.canvas.host.type.name</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 <link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
 <body class="show_output">
 
-<h1>type.name</h1>
+<h1>2d.canvas.host.type.name</h1>
 <p class="desc">HTMLCanvasElement type and toString</p>
 
 
@@ -19,8 +19,7 @@
 var t = async_test("HTMLCanvasElement type and toString");
 _addTest(function(canvas, ctx) {
 
-_assertSame(Object.prototype.toString.call(canvas), '[object HTMLCanvasElement]', "Object.prototype.toString.call(canvas)", "'[object HTMLCanvasElement]'");
-
+  _assertSame(Object.prototype.toString.call(canvas), '[object HTMLCanvasElement]', "Object.prototype.toString.call(canvas)", "'[object HTMLCanvasElement]'");
 
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.exists.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.exists.html
index 41b5cfe..21f35515 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.exists.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.exists.html
@@ -20,8 +20,7 @@
   var canvas = new OffscreenCanvas(100, 50);
   var ctx = canvas.getContext('2d');
 
-  var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-  _assertDifferent(offscreenCanvas2.getContext('2d'), null, "offscreenCanvas2.getContext('2d')", "null");
+  _assertDifferent(canvas.getContext('2d'), null, "canvas.getContext('2d')", "null");
   t.done();
 
 });
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.exists.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.exists.worker.js
index 77a4353..f56aff7 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.exists.worker.js
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.exists.worker.js
@@ -16,8 +16,7 @@
   var canvas = new OffscreenCanvas(100, 50);
   var ctx = canvas.getContext('2d');
 
-  var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-  _assertDifferent(offscreenCanvas2.getContext('2d'), null, "offscreenCanvas2.getContext('2d')", "null");
+  _assertDifferent(canvas.getContext('2d'), null, "canvas.getContext('2d')", "null");
   t.done();
 });
 done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.cache.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.cache.html
index 2bcf344..42f29e4 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.cache.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.cache.html
@@ -20,9 +20,9 @@
   var canvas = new OffscreenCanvas(100, 50);
   var ctx = canvas.getContext('2d');
 
-  _assertDifferent(canvas.getContext('2d', false, {}, [], 1, "2"), null, "canvas.getContext('2d', false, {}, [], 1, \"2\")", "null");
+  _assertDifferent(canvas.getContext('2d', false, {}, [], 1, '2'), null, "canvas.getContext('2d', false, {}, [], 1, '2')", "null");
   _assertDifferent(canvas.getContext('2d', 123), null, "canvas.getContext('2d', 123)", "null");
-  _assertDifferent(canvas.getContext('2d', "test"), null, "canvas.getContext('2d', \"test\")", "null");
+  _assertDifferent(canvas.getContext('2d', 'test'), null, "canvas.getContext('2d', 'test')", "null");
   _assertDifferent(canvas.getContext('2d', undefined), null, "canvas.getContext('2d', undefined)", "null");
   _assertDifferent(canvas.getContext('2d', null), null, "canvas.getContext('2d', null)", "null");
   _assertDifferent(canvas.getContext('2d', Symbol.hasInstance), null, "canvas.getContext('2d', Symbol.hasInstance)", "null");
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.cache.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.cache.worker.js
index 14284a0a..f508d52 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.cache.worker.js
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.cache.worker.js
@@ -16,9 +16,9 @@
   var canvas = new OffscreenCanvas(100, 50);
   var ctx = canvas.getContext('2d');
 
-  _assertDifferent(canvas.getContext('2d', false, {}, [], 1, "2"), null, "canvas.getContext('2d', false, {}, [], 1, \"2\")", "null");
+  _assertDifferent(canvas.getContext('2d', false, {}, [], 1, '2'), null, "canvas.getContext('2d', false, {}, [], 1, '2')", "null");
   _assertDifferent(canvas.getContext('2d', 123), null, "canvas.getContext('2d', 123)", "null");
-  _assertDifferent(canvas.getContext('2d', "test"), null, "canvas.getContext('2d', \"test\")", "null");
+  _assertDifferent(canvas.getContext('2d', 'test'), null, "canvas.getContext('2d', 'test')", "null");
   _assertDifferent(canvas.getContext('2d', undefined), null, "canvas.getContext('2d', undefined)", "null");
   _assertDifferent(canvas.getContext('2d', null), null, "canvas.getContext('2d', null)", "null");
   _assertDifferent(canvas.getContext('2d', Symbol.hasInstance), null, "canvas.getContext('2d', Symbol.hasInstance)", "null");
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.create.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.create.html
index 0291223..199f5b8 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.create.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.create.html
@@ -20,12 +20,12 @@
   var canvas = new OffscreenCanvas(100, 50);
   var ctx = canvas.getContext('2d');
 
-  _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', false, {}, [], 1, "2"), null, "(new OffscreenCanvas(100, 50)).getContext('2d', false, {}, [], 1, \"2\")", "null");
-  _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', 123), null, "(new OffscreenCanvas(100, 50)).getContext('2d', 123)", "null");
-  _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', "test"), null, "(new OffscreenCanvas(100, 50)).getContext('2d', \"test\")", "null");
-  _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', undefined), null, "(new OffscreenCanvas(100, 50)).getContext('2d', undefined)", "null");
-  _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', null), null, "(new OffscreenCanvas(100, 50)).getContext('2d', null)", "null");
-  _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', Symbol.hasInstance), null, "(new OffscreenCanvas(100, 50)).getContext('2d', Symbol.hasInstance)", "null");
+  _assertDifferent(new OffscreenCanvas(100, 50).getContext('2d', false, {}, [], 1, "2"), null, "new OffscreenCanvas(100, 50).getContext('2d', false, {}, [], 1, \"2\")", "null");
+  _assertDifferent(new OffscreenCanvas(100, 50).getContext('2d', 123), null, "new OffscreenCanvas(100, 50).getContext('2d', 123)", "null");
+  _assertDifferent(new OffscreenCanvas(100, 50).getContext('2d', "test"), null, "new OffscreenCanvas(100, 50).getContext('2d', \"test\")", "null");
+  _assertDifferent(new OffscreenCanvas(100, 50).getContext('2d', undefined), null, "new OffscreenCanvas(100, 50).getContext('2d', undefined)", "null");
+  _assertDifferent(new OffscreenCanvas(100, 50).getContext('2d', null), null, "new OffscreenCanvas(100, 50).getContext('2d', null)", "null");
+  _assertDifferent(new OffscreenCanvas(100, 50).getContext('2d', Symbol.hasInstance), null, "new OffscreenCanvas(100, 50).getContext('2d', Symbol.hasInstance)", "null");
   t.done();
 
 });
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.create.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.create.worker.js
index b4208edb..d1bfbcc 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.create.worker.js
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.extraargs.create.worker.js
@@ -16,12 +16,12 @@
   var canvas = new OffscreenCanvas(100, 50);
   var ctx = canvas.getContext('2d');
 
-  _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', false, {}, [], 1, "2"), null, "(new OffscreenCanvas(100, 50)).getContext('2d', false, {}, [], 1, \"2\")", "null");
-  _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', 123), null, "(new OffscreenCanvas(100, 50)).getContext('2d', 123)", "null");
-  _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', "test"), null, "(new OffscreenCanvas(100, 50)).getContext('2d', \"test\")", "null");
-  _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', undefined), null, "(new OffscreenCanvas(100, 50)).getContext('2d', undefined)", "null");
-  _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', null), null, "(new OffscreenCanvas(100, 50)).getContext('2d', null)", "null");
-  _assertDifferent((new OffscreenCanvas(100, 50)).getContext('2d', Symbol.hasInstance), null, "(new OffscreenCanvas(100, 50)).getContext('2d', Symbol.hasInstance)", "null");
+  _assertDifferent(new OffscreenCanvas(100, 50).getContext('2d', false, {}, [], 1, "2"), null, "new OffscreenCanvas(100, 50).getContext('2d', false, {}, [], 1, \"2\")", "null");
+  _assertDifferent(new OffscreenCanvas(100, 50).getContext('2d', 123), null, "new OffscreenCanvas(100, 50).getContext('2d', 123)", "null");
+  _assertDifferent(new OffscreenCanvas(100, 50).getContext('2d', "test"), null, "new OffscreenCanvas(100, 50).getContext('2d', \"test\")", "null");
+  _assertDifferent(new OffscreenCanvas(100, 50).getContext('2d', undefined), null, "new OffscreenCanvas(100, 50).getContext('2d', undefined)", "null");
+  _assertDifferent(new OffscreenCanvas(100, 50).getContext('2d', null), null, "new OffscreenCanvas(100, 50).getContext('2d', null)", "null");
+  _assertDifferent(new OffscreenCanvas(100, 50).getContext('2d', Symbol.hasInstance), null, "new OffscreenCanvas(100, 50).getContext('2d', Symbol.hasInstance)", "null");
   t.done();
 });
 done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.invalid.args.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.invalid.args.html
new file mode 100644
index 0000000..ce71d4c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.invalid.args.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.invalid.args</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.invalid.args</h1>
+<p class="desc">Calling getContext with invalid arguments.</p>
+
+
+<script>
+var t = async_test("Calling getContext with invalid arguments.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  assert_throws_js(TypeError, function() { canvas.getContext(''); });
+  assert_throws_js(TypeError, function() { canvas.getContext('This is not an implemented context in any real browser'); });
+  assert_throws_js(TypeError, function() { canvas.getContext('2d#'); });
+  assert_throws_js(TypeError, function() { canvas.getContext('2d\0'); });
+  assert_throws_js(TypeError, function() { canvas.getContext('2\uFF44'); });
+  assert_throws_js(TypeError, function() { canvas.getContext('2D'); });
+  assert_throws_js(TypeError, function() { canvas.getContext(); });
+  assert_throws_js(TypeError, function() { canvas.getContext('null'); });
+  assert_throws_js(TypeError, function() { canvas.getContext('undefined'); });
+  t.done();
+
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.invalid.args.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.invalid.args.worker.js
new file mode 100644
index 0000000..faea2171
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.invalid.args.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.invalid.args
+// Description:Calling getContext with invalid arguments.
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Calling getContext with invalid arguments.");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  assert_throws_js(TypeError, function() { canvas.getContext(''); });
+  assert_throws_js(TypeError, function() { canvas.getContext('This is not an implemented context in any real browser'); });
+  assert_throws_js(TypeError, function() { canvas.getContext('2d#'); });
+  assert_throws_js(TypeError, function() { canvas.getContext('2d\0'); });
+  assert_throws_js(TypeError, function() { canvas.getContext('2\uFF44'); });
+  assert_throws_js(TypeError, function() { canvas.getContext('2D'); });
+  assert_throws_js(TypeError, function() { canvas.getContext(); });
+  assert_throws_js(TypeError, function() { canvas.getContext('null'); });
+  assert_throws_js(TypeError, function() { canvas.getContext('undefined'); });
+  t.done();
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.prototype.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.prototype.html
new file mode 100644
index 0000000..17e5f089
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.prototype.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.prototype</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.prototype</h1>
+<p class="desc">checks OffscreenCanvasRenderingContext2D prototype</p>
+
+
+<script>
+var t = async_test("checks OffscreenCanvasRenderingContext2D prototype");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  _assertSame(Object.getPrototypeOf(OffscreenCanvasRenderingContext2D.prototype), Object.prototype, "Object.getPrototypeOf(OffscreenCanvasRenderingContext2D.prototype)", "Object.prototype");
+  _assertSame(Object.getPrototypeOf(ctx), OffscreenCanvasRenderingContext2D.prototype, "Object.getPrototypeOf(ctx)", "OffscreenCanvasRenderingContext2D.prototype");
+  t.done();
+
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.prototype.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.prototype.worker.js
new file mode 100644
index 0000000..dd41239
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.prototype.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.prototype
+// Description:checks OffscreenCanvasRenderingContext2D prototype
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("checks OffscreenCanvasRenderingContext2D prototype");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  _assertSame(Object.getPrototypeOf(OffscreenCanvasRenderingContext2D.prototype), Object.prototype, "Object.getPrototypeOf(OffscreenCanvasRenderingContext2D.prototype)", "Object.prototype");
+  _assertSame(Object.getPrototypeOf(ctx), OffscreenCanvasRenderingContext2D.prototype, "Object.getPrototypeOf(ctx)", "OffscreenCanvasRenderingContext2D.prototype");
+  t.done();
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.exists.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.exists.html
new file mode 100644
index 0000000..96b35d8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.exists.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.type.exists</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.type.exists</h1>
+<p class="desc">The 2D context interface is a property of 'window'</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<script>
+var t = async_test("The 2D context interface is a property of 'window'");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  _assert(window.OffscreenCanvasRenderingContext2D, "window.OffscreenCanvasRenderingContext2D");
+  t.done();
+
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.exists.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.exists.worker.js
new file mode 100644
index 0000000..239c3e9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.exists.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.type.exists
+// Description:The 2D context interface is a property of 'self'
+// Note:<p class="notes">Defined in "Web IDL" (draft)
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("The 2D context interface is a property of 'self'");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  _assert(self.OffscreenCanvasRenderingContext2D, "self.OffscreenCanvasRenderingContext2D");
+  t.done();
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.extend.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.extend.html
new file mode 100644
index 0000000..a3f720c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.extend.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.type.extend</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.type.extend</h1>
+<p class="desc">Interface methods can be added</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<script>
+var t = async_test("Interface methods can be added");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  window.OffscreenCanvasRenderingContext2D.prototype.fillRectGreen = function (x, y, w, h)
+  {
+      this.fillStyle = '#0f0';
+      this.fillRect(x, y, w, h);
+  };
+  ctx.fillStyle = '#f00';
+  ctx.fillRectGreen(0, 0, 100, 50);
+  _assertPixel(canvas, 50,25, 0,255,0,255);
+  t.done();
+
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.extend.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.extend.worker.js
new file mode 100644
index 0000000..9832c5ca
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.extend.worker.js
@@ -0,0 +1,29 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.type.extend
+// Description:Interface methods can be added
+// Note:<p class="notes">Defined in "Web IDL" (draft)
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Interface methods can be added");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  self.OffscreenCanvasRenderingContext2D.prototype.fillRectGreen = function (x, y, w, h)
+  {
+      this.fillStyle = '#0f0';
+      this.fillRect(x, y, w, h);
+  };
+  ctx.fillStyle = '#f00';
+  ctx.fillRectGreen(0, 0, 100, 50);
+  _assertPixel(canvas, 50,25, 0,255,0,255);
+  t.done();
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.prototype.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.prototype.html
new file mode 100644
index 0000000..d08193c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.prototype.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.type.prototype</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.type.prototype</h1>
+<p class="desc">window.CanvasRenderingContext2D.prototype are not [[Writable]] and not [[Configurable]], and its methods are [[Configurable]].</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<script>
+var t = async_test("window.CanvasRenderingContext2D.prototype are not [[Writable]] and not [[Configurable]], and its methods are [[Configurable]].");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  _assert(window.OffscreenCanvasRenderingContext2D.prototype, "window.OffscreenCanvasRenderingContext2D.prototype");
+  _assert(window.OffscreenCanvasRenderingContext2D.prototype.fill, "window.OffscreenCanvasRenderingContext2D.prototype.fill");
+  window.OffscreenCanvasRenderingContext2D.prototype = null;
+  _assert(window.OffscreenCanvasRenderingContext2D.prototype, "window.OffscreenCanvasRenderingContext2D.prototype");
+  delete window.OffscreenCanvasRenderingContext2D.prototype;
+  _assert(window.OffscreenCanvasRenderingContext2D.prototype, "window.OffscreenCanvasRenderingContext2D.prototype");
+  window.OffscreenCanvasRenderingContext2D.prototype.fill = 1;
+  _assertSame(window.OffscreenCanvasRenderingContext2D.prototype.fill, 1, "window.OffscreenCanvasRenderingContext2D.prototype.fill", "1");
+  delete window.OffscreenCanvasRenderingContext2D.prototype.fill;
+  _assertSame(window.OffscreenCanvasRenderingContext2D.prototype.fill, undefined, "window.OffscreenCanvasRenderingContext2D.prototype.fill", "undefined");
+  t.done();
+
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.prototype.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.prototype.worker.js
new file mode 100644
index 0000000..459975d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.prototype.worker.js
@@ -0,0 +1,31 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.type.prototype
+// Description:window.CanvasRenderingContext2D.prototype are not [[Writable]] and not [[Configurable]], and its methods are [[Configurable]].
+// Note:<p class="notes">Defined in "Web IDL" (draft)
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("window.CanvasRenderingContext2D.prototype are not [[Writable]] and not [[Configurable]], and its methods are [[Configurable]].");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  _assert(self.OffscreenCanvasRenderingContext2D.prototype, "self.OffscreenCanvasRenderingContext2D.prototype");
+  _assert(self.OffscreenCanvasRenderingContext2D.prototype.fill, "self.OffscreenCanvasRenderingContext2D.prototype.fill");
+  self.OffscreenCanvasRenderingContext2D.prototype = null;
+  _assert(self.OffscreenCanvasRenderingContext2D.prototype, "self.OffscreenCanvasRenderingContext2D.prototype");
+  delete self.OffscreenCanvasRenderingContext2D.prototype;
+  _assert(self.OffscreenCanvasRenderingContext2D.prototype, "self.OffscreenCanvasRenderingContext2D.prototype");
+  self.OffscreenCanvasRenderingContext2D.prototype.fill = 1;
+  _assertSame(self.OffscreenCanvasRenderingContext2D.prototype.fill, 1, "self.OffscreenCanvasRenderingContext2D.prototype.fill", "1");
+  delete self.OffscreenCanvasRenderingContext2D.prototype.fill;
+  _assertSame(self.OffscreenCanvasRenderingContext2D.prototype.fill, undefined, "self.OffscreenCanvasRenderingContext2D.prototype.fill", "undefined");
+  t.done();
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.replace.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.replace.html
new file mode 100644
index 0000000..69b2241
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.replace.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.context.type.replace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.context.type.replace</h1>
+<p class="desc">Interface methods can be overridden</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<script>
+var t = async_test("Interface methods can be overridden");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  var fillRect = window.OffscreenCanvasRenderingContext2D.prototype.fillRect;
+  window.OffscreenCanvasRenderingContext2D.prototype.fillRect = function (x, y, w, h)
+  {
+      this.fillStyle = '#0f0';
+      fillRect.call(this, x, y, w, h);
+  };
+  ctx.fillStyle = '#f00';
+  ctx.fillRect(0, 0, 100, 50);
+  _assertPixel(canvas, 50,25, 0,255,0,255);
+  t.done();
+
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.replace.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.replace.worker.js
new file mode 100644
index 0000000..e6793d1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.type.replace.worker.js
@@ -0,0 +1,30 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.context.type.replace
+// Description:Interface methods can be overridden
+// Note:<p class="notes">Defined in "Web IDL" (draft)
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Interface methods can be overridden");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  var fillRect = self.OffscreenCanvasRenderingContext2D.prototype.fillRect;
+  self.OffscreenCanvasRenderingContext2D.prototype.fillRect = function (x, y, w, h)
+  {
+      this.fillStyle = '#0f0';
+      fillRect.call(this, x, y, w, h);
+  };
+  ctx.fillStyle = '#f00';
+  ctx.fillRect(0, 0, 100, 50);
+  _assertPixel(canvas, 50,25, 0,255,0,255);
+  t.done();
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unique.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unique.html
index 66e4a049..828817b 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unique.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unique.html
@@ -20,8 +20,7 @@
   var canvas = new OffscreenCanvas(100, 50);
   var ctx = canvas.getContext('2d');
 
-  var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-  _assertSame(offscreenCanvas2.getContext('2d'), offscreenCanvas2.getContext('2d'), "offscreenCanvas2.getContext('2d')", "offscreenCanvas2.getContext('2d')");
+  _assertSame(canvas.getContext('2d'), canvas.getContext('2d'), "canvas.getContext('2d')", "canvas.getContext('2d')");
   t.done();
 
 });
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unique.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unique.worker.js
index 275e45f..90687bf 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unique.worker.js
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unique.worker.js
@@ -16,8 +16,7 @@
   var canvas = new OffscreenCanvas(100, 50);
   var ctx = canvas.getContext('2d');
 
-  var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-  _assertSame(offscreenCanvas2.getContext('2d'), offscreenCanvas2.getContext('2d'), "offscreenCanvas2.getContext('2d')", "offscreenCanvas2.getContext('2d')");
+  _assertSame(canvas.getContext('2d'), canvas.getContext('2d'), "canvas.getContext('2d')", "canvas.getContext('2d')");
   t.done();
 });
 done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badname.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badname.html
deleted file mode 100644
index 4313f40..0000000
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badname.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>OffscreenCanvas test: 2d.canvas.context.unrecognised.badname</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/html/canvas/resources/canvas-tests.js"></script>
-
-<h1>2d.canvas.context.unrecognised.badname</h1>
-<p class="desc">getContext with unrecognised context name returns null</p>
-
-
-<script>
-var t = async_test("getContext with unrecognised context name returns null");
-var t_pass = t.done.bind(t);
-var t_fail = t.step_func(function(reason) {
-    throw reason;
-});
-t.step(function() {
-
-  var canvas = new OffscreenCanvas(100, 50);
-  var ctx = canvas.getContext('2d');
-
-  var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-  assert_throws_js(TypeError, function() { offscreenCanvas2.getContext('This is not an implemented context in any real browser'); });
-  t.done();
-
-});
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badname.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badname.worker.js
deleted file mode 100644
index dd16f2f..0000000
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badname.worker.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
-// OffscreenCanvas test in a worker:2d.canvas.context.unrecognised.badname
-// Description:getContext with unrecognised context name returns null
-// Note:
-
-importScripts("/resources/testharness.js");
-importScripts("/html/canvas/resources/canvas-tests.js");
-
-var t = async_test("getContext with unrecognised context name returns null");
-var t_pass = t.done.bind(t);
-var t_fail = t.step_func(function(reason) {
-    throw reason;
-});
-t.step(function() {
-
-  var canvas = new OffscreenCanvas(100, 50);
-  var ctx = canvas.getContext('2d');
-
-  var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-  assert_throws_js(TypeError, function() { offscreenCanvas2.getContext('This is not an implemented context in any real browser'); });
-  t.done();
-});
-done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badsuffix.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badsuffix.html
deleted file mode 100644
index c00afa6..0000000
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badsuffix.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>OffscreenCanvas test: 2d.canvas.context.unrecognised.badsuffix</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/html/canvas/resources/canvas-tests.js"></script>
-
-<h1>2d.canvas.context.unrecognised.badsuffix</h1>
-<p class="desc">Context name "2d" plus a suffix is unrecognised</p>
-
-
-<script>
-var t = async_test("Context name \"2d\" plus a suffix is unrecognised");
-var t_pass = t.done.bind(t);
-var t_fail = t.step_func(function(reason) {
-    throw reason;
-});
-t.step(function() {
-
-  var canvas = new OffscreenCanvas(100, 50);
-  var ctx = canvas.getContext('2d');
-
-  var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-  assert_throws_js(TypeError, function() { offscreenCanvas2.getContext("2d#"); });
-  t.done();
-
-});
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badsuffix.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badsuffix.worker.js
deleted file mode 100644
index 5e684c9..0000000
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.badsuffix.worker.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
-// OffscreenCanvas test in a worker:2d.canvas.context.unrecognised.badsuffix
-// Description:Context name "2d" plus a suffix is unrecognised
-// Note:
-
-importScripts("/resources/testharness.js");
-importScripts("/html/canvas/resources/canvas-tests.js");
-
-var t = async_test("Context name \"2d\" plus a suffix is unrecognised");
-var t_pass = t.done.bind(t);
-var t_fail = t.step_func(function(reason) {
-    throw reason;
-});
-t.step(function() {
-
-  var canvas = new OffscreenCanvas(100, 50);
-  var ctx = canvas.getContext('2d');
-
-  var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-  assert_throws_js(TypeError, function() { offscreenCanvas2.getContext("2d#"); });
-  t.done();
-});
-done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.nullsuffix.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.nullsuffix.html
deleted file mode 100644
index 0ce3d4195..0000000
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.nullsuffix.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>OffscreenCanvas test: 2d.canvas.context.unrecognised.nullsuffix</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/html/canvas/resources/canvas-tests.js"></script>
-
-<h1>2d.canvas.context.unrecognised.nullsuffix</h1>
-<p class="desc">Context name "2d" plus a "\0" suffix is unrecognised</p>
-
-
-<script>
-var t = async_test("Context name \"2d\" plus a \"\\0\" suffix is unrecognised");
-var t_pass = t.done.bind(t);
-var t_fail = t.step_func(function(reason) {
-    throw reason;
-});
-t.step(function() {
-
-  var canvas = new OffscreenCanvas(100, 50);
-  var ctx = canvas.getContext('2d');
-
-  var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-  assert_throws_js(TypeError, function() { offscreenCanvas2.getContext("2d\0"); });
-  t.done();
-
-});
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.nullsuffix.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.nullsuffix.worker.js
deleted file mode 100644
index 2886010..0000000
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.nullsuffix.worker.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
-// OffscreenCanvas test in a worker:2d.canvas.context.unrecognised.nullsuffix
-// Description:Context name "2d" plus a "\0" suffix is unrecognised
-// Note:
-
-importScripts("/resources/testharness.js");
-importScripts("/html/canvas/resources/canvas-tests.js");
-
-var t = async_test("Context name \"2d\" plus a \"\\0\" suffix is unrecognised");
-var t_pass = t.done.bind(t);
-var t_fail = t.step_func(function(reason) {
-    throw reason;
-});
-t.step(function() {
-
-  var canvas = new OffscreenCanvas(100, 50);
-  var ctx = canvas.getContext('2d');
-
-  var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-  assert_throws_js(TypeError, function() { offscreenCanvas2.getContext("2d\0"); });
-  t.done();
-});
-done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.unicode.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.unicode.html
deleted file mode 100644
index 31612367..0000000
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.unicode.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>OffscreenCanvas test: 2d.canvas.context.unrecognised.unicode</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/html/canvas/resources/canvas-tests.js"></script>
-
-<h1>2d.canvas.context.unrecognised.unicode</h1>
-<p class="desc">Context name which kind of looks like "2d" is unrecognised</p>
-
-
-<script>
-var t = async_test("Context name which kind of looks like \"2d\" is unrecognised");
-var t_pass = t.done.bind(t);
-var t_fail = t.step_func(function(reason) {
-    throw reason;
-});
-t.step(function() {
-
-  var canvas = new OffscreenCanvas(100, 50);
-  var ctx = canvas.getContext('2d');
-
-  var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-  assert_throws_js(TypeError, function() { offscreenCanvas2.getContext("2\uFF44"); });
-  t.done();
-
-});
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.unicode.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.unicode.worker.js
deleted file mode 100644
index 46e562dd..0000000
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-context/2d.canvas.context.unrecognised.unicode.worker.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
-// OffscreenCanvas test in a worker:2d.canvas.context.unrecognised.unicode
-// Description:Context name which kind of looks like "2d" is unrecognised
-// Note:
-
-importScripts("/resources/testharness.js");
-importScripts("/html/canvas/resources/canvas-tests.js");
-
-var t = async_test("Context name which kind of looks like \"2d\" is unrecognised");
-var t_pass = t.done.bind(t);
-var t_fail = t.step_func(function(reason) {
-    throw reason;
-});
-t.step(function() {
-
-  var canvas = new OffscreenCanvas(100, 50);
-  var ctx = canvas.getContext('2d');
-
-  var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-  assert_throws_js(TypeError, function() { offscreenCanvas2.getContext("2\uFF44"); });
-  t.done();
-});
-done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.readonly.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.readonly.html
index 0e7e10c..93262a6 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.readonly.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.readonly.html
@@ -6,11 +6,11 @@
 <script src="/html/canvas/resources/canvas-tests.js"></script>
 
 <h1>2d.canvas.host.readonly</h1>
-<p class="desc">canvas is readonly</p>
+<p class="desc">Canvas objects are readonly</p>
 
 
 <script>
-var t = async_test("canvas is readonly");
+var t = async_test("Canvas objects are readonly");
 var t_pass = t.done.bind(t);
 var t_fail = t.step_func(function(reason) {
     throw reason;
@@ -20,10 +20,10 @@
   var canvas = new OffscreenCanvas(100, 50);
   var ctx = canvas.getContext('2d');
 
-  var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+  var canvas2 = new OffscreenCanvas(100, 50);
   var d = ctx.canvas;
-  _assertDifferent(offscreenCanvas2, d, "offscreenCanvas2", "d");
-  ctx.canvas = offscreenCanvas2;
+  _assertDifferent(canvas2, d, "canvas2", "d");
+  ctx.canvas = canvas2;
   _assertSame(ctx.canvas, d, "ctx.canvas", "d");
   t.done();
 
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.readonly.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.readonly.worker.js
index bbe50dc..5baef1b3 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.readonly.worker.js
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.readonly.worker.js
@@ -1,12 +1,12 @@
 // DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
 // OffscreenCanvas test in a worker:2d.canvas.host.readonly
-// Description:canvas is readonly
+// Description:Canvas objects are readonly
 // Note:
 
 importScripts("/resources/testharness.js");
 importScripts("/html/canvas/resources/canvas-tests.js");
 
-var t = async_test("canvas is readonly");
+var t = async_test("Canvas objects are readonly");
 var t_pass = t.done.bind(t);
 var t_fail = t.step_func(function(reason) {
     throw reason;
@@ -16,10 +16,10 @@
   var canvas = new OffscreenCanvas(100, 50);
   var ctx = canvas.getContext('2d');
 
-  var offscreenCanvas2 = new OffscreenCanvas(100, 50);
+  var canvas2 = new OffscreenCanvas(100, 50);
   var d = ctx.canvas;
-  _assertDifferent(offscreenCanvas2, d, "offscreenCanvas2", "d");
-  ctx.canvas = offscreenCanvas2;
+  _assertDifferent(canvas2, d, "canvas2", "d");
+  ctx.canvas = canvas2;
   _assertSame(ctx.canvas, d, "ctx.canvas", "d");
   t.done();
 });
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.html
index 7030103..b8ce99a 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.html
@@ -20,22 +20,18 @@
   var canvas = new OffscreenCanvas(100, 50);
   var ctx = canvas.getContext('2d');
 
-  canvas.width = "100";
-  canvas.height = "100";
+  canvas.width = '100';
+  canvas.height = '100';
   _assertSame(canvas.width, 100, "canvas.width", "100");
   _assertSame(canvas.height, 100, "canvas.height", "100");
-  canvas.width = "+1.5e2";
-  canvas.height = "0x96";
-  _assertSame(canvas.width, 150, "canvas.width", "150");
-  _assertSame(canvas.height, 150, "canvas.height", "150");
   canvas.width = 301.999;
   canvas.height = 301.001;
   _assertSame(canvas.width, 301, "canvas.width", "301");
   _assertSame(canvas.height, 301, "canvas.height", "301");
-  assert_throws_js(TypeError, function() { canvas.width = "400x"; });
-  assert_throws_js(TypeError, function() { canvas.height = "foo"; });
-  _assertSame(canvas.width, 301, "canvas.width", "301");
-  _assertSame(canvas.height, 301, "canvas.height", "301");
+  canvas.width = "+1.5e2";
+  canvas.height = "0x96";
+  _assertSame(canvas.width, 150, "canvas.width", "150");
+  _assertSame(canvas.height, 150, "canvas.height", "150");
   t.done();
 
 });
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.worker.js
index a00201f..42002e8 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.worker.js
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.size.attributes.idl.worker.js
@@ -16,22 +16,18 @@
   var canvas = new OffscreenCanvas(100, 50);
   var ctx = canvas.getContext('2d');
 
-  canvas.width = "100";
-  canvas.height = "100";
+  canvas.width = '100';
+  canvas.height = '100';
   _assertSame(canvas.width, 100, "canvas.width", "100");
   _assertSame(canvas.height, 100, "canvas.height", "100");
-  canvas.width = "+1.5e2";
-  canvas.height = "0x96";
-  _assertSame(canvas.width, 150, "canvas.width", "150");
-  _assertSame(canvas.height, 150, "canvas.height", "150");
   canvas.width = 301.999;
   canvas.height = 301.001;
   _assertSame(canvas.width, 301, "canvas.width", "301");
   _assertSame(canvas.height, 301, "canvas.height", "301");
-  assert_throws_js(TypeError, function() { canvas.width = "400x"; });
-  assert_throws_js(TypeError, function() { canvas.height = "foo"; });
-  _assertSame(canvas.width, 301, "canvas.width", "301");
-  _assertSame(canvas.height, 301, "canvas.height", "301");
+  canvas.width = "+1.5e2";
+  canvas.height = "0x96";
+  _assertSame(canvas.width, 150, "canvas.width", "150");
+  _assertSame(canvas.height, 150, "canvas.height", "150");
   t.done();
 });
 done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.size.invalid.attributes.idl.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.size.invalid.attributes.idl.html
new file mode 100644
index 0000000..2194de9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.size.invalid.attributes.idl.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.size.invalid.attributes.idl</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.size.invalid.attributes.idl</h1>
+<p class="desc">Getting/setting width/height IDL attributes</p>
+
+
+<script>
+var t = async_test("Getting/setting width/height IDL attributes");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  assert_throws_js(TypeError, function() { canvas.width = 200 - Math.pow(2, 32); });
+  assert_throws_js(TypeError, function() { canvas.height = 200 - Math.pow(2, 32); });
+  assert_throws_js(TypeError, function() { canvas.width = '400x'; });
+  assert_throws_js(TypeError, function() { canvas.height = 'foo'; });
+  t.done();
+
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.size.invalid.attributes.idl.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.size.invalid.attributes.idl.worker.js
new file mode 100644
index 0000000..8adb7a5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.size.invalid.attributes.idl.worker.js
@@ -0,0 +1,25 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.size.invalid.attributes.idl
+// Description:Getting/setting width/height IDL attributes
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("Getting/setting width/height IDL attributes");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  assert_throws_js(TypeError, function() { canvas.width = 200 - Math.pow(2, 32); });
+  assert_throws_js(TypeError, function() { canvas.height = 200 - Math.pow(2, 32); });
+  assert_throws_js(TypeError, function() { canvas.width = '400x'; });
+  assert_throws_js(TypeError, function() { canvas.height = 'foo'; });
+  t.done();
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.type.delete.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.type.delete.html
new file mode 100644
index 0000000..1d2a733
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.type.delete.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.type.delete</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.type.delete</h1>
+<p class="desc">OffscreenCanvas interface object is [[Configurable]]</p>
+
+
+<script>
+var t = async_test("OffscreenCanvas interface object is [[Configurable]]");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  _assertSame(delete window.OffscreenCanvas, true, "delete window.OffscreenCanvas", "true");
+  _assertSame(window.OffscreenCanvas, undefined, "window.OffscreenCanvas", "undefined");
+  t.done();
+
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.type.delete.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.type.delete.worker.js
new file mode 100644
index 0000000..409e12cd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.type.delete.worker.js
@@ -0,0 +1,23 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.type.delete
+// Description:OffscreenCanvas interface object is [[Configurable]]
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("OffscreenCanvas interface object is [[Configurable]]");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  _assertSame(delete self.OffscreenCanvas, true, "delete self.OffscreenCanvas", "true");
+  _assertSame(self.OffscreenCanvas, undefined, "self.OffscreenCanvas", "undefined");
+  t.done();
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.type.name.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.type.name.html
new file mode 100644
index 0000000..5f48c09
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.type.name.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>OffscreenCanvas test: 2d.canvas.host.type.name</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+
+<h1>2d.canvas.host.type.name</h1>
+<p class="desc">OffscreenCanvas type and toString</p>
+
+
+<script>
+var t = async_test("OffscreenCanvas type and toString");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  _assertSame(Object.prototype.toString.call(canvas), '[object OffscreenCanvas]', "Object.prototype.toString.call(canvas)", "'[object OffscreenCanvas]'");
+  t.done();
+
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.type.name.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.type.name.worker.js
new file mode 100644
index 0000000..ea50e4f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/canvas-host/2d.canvas.host.type.name.worker.js
@@ -0,0 +1,22 @@
+// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
+// OffscreenCanvas test in a worker:2d.canvas.host.type.name
+// Description:OffscreenCanvas type and toString
+// Note:
+
+importScripts("/resources/testharness.js");
+importScripts("/html/canvas/resources/canvas-tests.js");
+
+var t = async_test("OffscreenCanvas type and toString");
+var t_pass = t.done.bind(t);
+var t_fail = t.step_func(function(reason) {
+    throw reason;
+});
+t.step(function() {
+
+  var canvas = new OffscreenCanvas(100, 50);
+  var ctx = canvas.getContext('2d');
+
+  _assertSame(Object.prototype.toString.call(canvas), '[object OffscreenCanvas]', "Object.prototype.toString.call(canvas)", "'[object OffscreenCanvas]'");
+  t.done();
+});
+done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/the-canvas.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/the-canvas.yaml
new file mode 100644
index 0000000..4153b8e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/the-canvas.yaml
@@ -0,0 +1,416 @@
+- name: 2d.canvas.host.reference
+  desc: canvas refers back to its canvas
+  code: |
+    @assert ctx.canvas === canvas;
+
+- name: 2d.canvas.host.readonly
+  desc: Canvas objects are readonly
+  code: |
+    var canvas2 = {{ new_canvas }};
+    var d = ctx.canvas;
+    @assert canvas2 !== d;
+    ctx.canvas = canvas2;
+    @assert ctx.canvas === d;
+  variants: &new-canvas-definition
+   - HtmlCanvas:
+       append_variants_to_name: false
+       canvas_types: ['HtmlCanvas']
+       new_canvas: |-
+         document.createElement('canvas')
+     OffscreenCanvas:
+       append_variants_to_name: false
+       canvas_types: ['OffscreenCanvas', 'Worker']
+       new_canvas: |-
+         new OffscreenCanvas(100, 50)
+
+- name: 2d.canvas.host.type.delete
+  canvas_types: ['HtmlCanvas']
+  desc: window.HTMLCanvasElement interface object is [[Configurable]]
+  code: |
+    @assert delete window.HTMLCanvasElement === true;
+    @assert window.HTMLCanvasElement === undefined;
+
+- name: 2d.canvas.host.type.delete
+  canvas_types: ['OffscreenCanvas', 'Worker']
+  desc: OffscreenCanvas interface object is [[Configurable]]
+  code: |
+    {% set root = 'self' if canvas_type == 'Worker' else 'window' %}
+    @assert delete {{ root }}.OffscreenCanvas === true;
+    @assert {{ root }}.OffscreenCanvas === undefined;
+
+- name: 2d.canvas.host.type.name
+  canvas_types: ['HtmlCanvas']
+  desc: HTMLCanvasElement type and toString
+  code: |
+    @assert Object.prototype.toString.call(canvas) === '[object HTMLCanvasElement]';
+
+- name: 2d.canvas.host.type.name
+  canvas_types: ['OffscreenCanvas', 'Worker']
+  desc: OffscreenCanvas type and toString
+  code: |
+    @assert Object.prototype.toString.call(canvas) === '[object OffscreenCanvas]';
+
+- name: 2d.canvas.context.exists
+  desc: The 2D context is implemented
+  code: |
+    @assert canvas.getContext('2d') !== null;
+
+- name: 2d.canvas.context.extraargs.create
+  desc: The 2D context doesn't throw with extra getContext arguments (new context)
+  code: |
+    @assert {{ new_canvas }}.getContext('2d', false, {}, [], 1, "2") !== null;
+    @assert {{ new_canvas }}.getContext('2d', 123) !== null;
+    @assert {{ new_canvas }}.getContext('2d', "test") !== null;
+    @assert {{ new_canvas }}.getContext('2d', undefined) !== null;
+    @assert {{ new_canvas }}.getContext('2d', null) !== null;
+    @assert {{ new_canvas }}.getContext('2d', Symbol.hasInstance) !== null;
+  variants: *new-canvas-definition
+
+- name: 2d.canvas.context.invalid.args
+  desc: Calling getContext with invalid arguments.
+  canvas_types: ['HtmlCanvas']
+  code: |
+    @assert canvas.getContext('') === null;
+    @assert canvas.getContext('2d#') === null;
+    @assert canvas.getContext('This is clearly not a valid context name.') === null;
+    @assert canvas.getContext('2d\0') === null;
+    @assert canvas.getContext('2\uFF44') === null;
+    @assert canvas.getContext('2D') === null;
+    @assert throws TypeError canvas.getContext();
+    @assert canvas.getContext('null') === null;
+    @assert canvas.getContext('undefined') === null;
+
+- name: 2d.canvas.context.invalid.args
+  desc: Calling getContext with invalid arguments.
+  canvas_types: ['OffscreenCanvas', 'Worker']
+  code: |
+    @assert throws TypeError canvas.getContext('');
+    @assert throws TypeError canvas.getContext('This is not an implemented context in any real browser');
+    @assert throws TypeError canvas.getContext('2d#');
+    @assert throws TypeError canvas.getContext('2d\0');
+    @assert throws TypeError canvas.getContext('2\uFF44');
+    @assert throws TypeError canvas.getContext('2D');
+    @assert throws TypeError canvas.getContext();
+    @assert throws TypeError canvas.getContext('null');
+    @assert throws TypeError canvas.getContext('undefined');
+
+
+- name: 2d.canvas.context.extraargs.cache
+  desc: The 2D context doesn't throw with extra getContext arguments (cached)
+  code: |
+    @assert canvas.getContext('2d', false, {}, [], 1, '2') !== null;
+    @assert canvas.getContext('2d', 123) !== null;
+    @assert canvas.getContext('2d', 'test') !== null;
+    @assert canvas.getContext('2d', undefined) !== null;
+    @assert canvas.getContext('2d', null) !== null;
+    @assert canvas.getContext('2d', Symbol.hasInstance) !== null;
+
+- name: 2d.canvas.context.unique
+  desc: getContext('2d') returns the same object
+  code: |
+    @assert canvas.getContext('2d') === canvas.getContext('2d');
+
+- name: 2d.canvas.context.shared
+  desc: getContext('2d') returns objects which share canvas state
+  code: |
+    var ctx2 = canvas.getContext('2d');
+    ctx.fillStyle = '#f00';
+    ctx2.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    @assert pixel 50,25 == 0,255,0,255;
+  expected: green
+
+- name: 2d.canvas.host.initial.color
+  desc: Initial state is transparent black
+  code: |
+    @assert pixel 20,20 == 0,0,0,0;
+
+- name: 2d.canvas.host.initial.reset.different
+  desc: Changing size resets canvas to transparent black
+  code: |
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(0, 0, 50, 50);
+    @assert pixel 20,20 == 255,0,0,255;
+    canvas.width = 50;
+    @assert pixel 20,20 == 0,0,0,0;
+
+- name: 2d.canvas.host.initial.reset.same
+  desc: Setting size (not changing the value) resets canvas to transparent black
+  code: |
+    canvas.width = 100;
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(0, 0, 50, 50);
+    @assert pixel 20,20 == 255,0,0,255;
+    canvas.width = 100;
+    @assert pixel 20,20 == 0,0,0,0;
+
+
+- name: 2d.canvas.host.initial.reset.path
+  desc: Resetting the canvas state resets the current path
+  code: |
+    canvas.width = 100;
+    ctx.rect(0, 0, 100, 50);
+    canvas.width = 100;
+    ctx.fillStyle = '#f00';
+    ctx.fill();
+    @assert pixel 20,20 == 0,0,0,0;
+
+- name: 2d.canvas.host.initial.reset.clip
+  desc: Resetting the canvas state resets the current clip region
+  code: |
+    canvas.width = 100;
+    ctx.rect(0, 0, 1, 1);
+    ctx.clip();
+    canvas.width = 100;
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    @assert pixel 20,20 == 0,255,0,255;
+
+- name: 2d.canvas.host.initial.reset.transform
+  desc: Resetting the canvas state resets the current transformation matrix
+  code: |
+    canvas.width = 100;
+    ctx.scale(0.1, 0.1);
+    canvas.width = 100;
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 100, 50);
+    @assert pixel 20,20 == 0,255,0,255;
+
+- name: 2d.canvas.host.initial.reset.gradient
+  desc: Resetting the canvas state does not invalidate any existing gradients
+  code: |
+    canvas.width = 50;
+    var g = ctx.createLinearGradient(0, 0, 100, 0);
+    g.addColorStop(0, '#0f0');
+    g.addColorStop(1, '#0f0');
+    canvas.width = 100;
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.fillStyle = g;
+    ctx.fillRect(0, 0, 100, 50);
+    @assert pixel 50,25 == 0,255,0,255;
+
+- name: 2d.canvas.host.initial.reset.pattern
+  desc: Resetting the canvas state does not invalidate any existing patterns
+  code: |
+    canvas.width = 30;
+    ctx.fillStyle = '#0f0';
+    ctx.fillRect(0, 0, 30, 50);
+    var p = ctx.createPattern(canvas, 'repeat-x');
+    canvas.width = 100;
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.fillStyle = p;
+    ctx.fillRect(0, 0, 100, 50);
+    @assert pixel 50,25 == 0,255,0,255;
+
+- name: 2d.canvas.host.size.attributes.idl.set.zero
+  desc: Setting width/height IDL attributes to 0
+  code: |
+    canvas.width = 0;
+    canvas.height = 0;
+    @assert canvas.width === 0;
+    @assert canvas.height === 0;
+
+- name: 2d.canvas.host.size.attributes.idl
+  desc: Getting/setting width/height IDL attributes
+  code: |
+    canvas.width = '100';
+    canvas.height = '100';
+    @assert canvas.width === 100;
+    @assert canvas.height === 100;
+    canvas.width = 301.999;
+    canvas.height = 301.001;
+    @assert canvas.width === 301;
+    @assert canvas.height === 301;
+    canvas.width = "+1.5e2";
+    canvas.height = "0x96";
+    @assert canvas.width === 150;
+    @assert canvas.height === 150;
+
+- name: 2d.canvas.host.size.invalid.attributes.idl
+  canvas_types: ['OffscreenCanvas', 'Worker']
+  desc: Getting/setting width/height IDL attributes
+  code: |
+    @assert throws TypeError canvas.width = 200 - Math.pow(2, 32);
+    @assert throws TypeError canvas.height = 200 - Math.pow(2, 32);
+    @assert throws TypeError canvas.width = '400x';
+    @assert throws TypeError canvas.height = 'foo';
+
+- name: 2d.canvas.host.size.invalid.attributes.idl
+  canvas_types: ['HtmlCanvas']
+  desc: Getting/setting width/height IDL attributes
+  code: |
+    canvas.width = 200 - Math.pow(2, 32);
+    canvas.height = 200 - Math.pow(2, 32);
+    @assert canvas.width === 200;
+    @assert canvas.height === 200;
+    canvas.width = '400x';
+    canvas.height = 'foo';
+    @assert canvas.width === 0;
+    @assert canvas.height === 0;
+
+- name: 2d.canvas.host.size.attributes.default
+  desc: Default width/height when attributes are missing
+  code: |
+    @assert canvas.width === 100;
+    @assert canvas.height === 50;
+
+- name: 2d.canvas.host.size.attributes.removed
+  size: [120, 50]
+  canvas_types: ['HtmlCanvas']
+  desc: Removing content attributes reverts to default size
+  code: |
+    @assert canvas.width === 120;
+    canvas.removeAttribute('width');
+    @assert canvas.width === 300;
+
+
+- name: 2d.canvas.host.size.attributes.reflect.setidl
+  desc: Setting IDL attributes updates IDL and content attributes
+  code: |
+    canvas.width = 120;
+    canvas.height = 60;
+    @assert canvas.width === 120;
+    @assert canvas.height === 60;
+    {% if canvas_type == 'HtmlCanvas' %}
+    @assert canvas.getAttribute('width') === '120';
+    @assert canvas.getAttribute('height') === '60';
+    {% endif %}
+
+- name: 2d.canvas.host.size.attributes.reflect.setidlzero
+  desc: Setting IDL attributes to 0 updates IDL and content attributes
+  code: |
+    canvas.width = 0;
+    canvas.height = 0;
+    {% if canvas_type == 'HtmlCanvas' %}
+    _assertSame(canvas.getAttribute('width'), '0', "canvas.getAttribute('width')", "'0'");
+    _assertSame(canvas.getAttribute('height'), '0', "canvas.getAttribute('height')", "'0'");
+    {% endif %}
+    @assert canvas.width === 0;
+    @assert canvas.height === 0;
+
+- name: 2d.canvas.host.size.attributes.reflect.setcontent
+  canvas_types: ['HtmlCanvas']
+  desc: Setting content attributes updates IDL and content attributes
+  code: |
+    canvas.setAttribute('width', '120');
+    canvas.setAttribute('height', '60');
+    @assert canvas.getAttribute('width') === '120';
+    @assert canvas.getAttribute('height') === '60';
+    @assert canvas.width === 120;
+    @assert canvas.height === 60;
+
+- name: 2d.canvas.host.size.large
+  notes: Not sure how reasonable this is, but the spec doesn't say there's an upper
+    limit on the size.
+  code: |
+    var n = 2147483647; // 2^31 - 1, which should be supported by any sensible definition of "long"
+    canvas.width = n;
+    canvas.height = n;
+    @assert canvas.width === n;
+    @assert canvas.height === n;
+
+- name: 2d.canvas.context.prototype
+  desc: checks CanvasRenderingContext2D prototype
+  canvas_types: ['HtmlCanvas']
+  code: |
+    @assert Object.getPrototypeOf(CanvasRenderingContext2D.prototype) === Object.prototype;
+    @assert Object.getPrototypeOf(ctx) === CanvasRenderingContext2D.prototype;
+
+- name: 2d.canvas.context.prototype
+  desc: checks OffscreenCanvasRenderingContext2D prototype
+  canvas_types: ['OffscreenCanvas', 'Worker']
+  code: |
+    @assert Object.getPrototypeOf(OffscreenCanvasRenderingContext2D.prototype) === Object.prototype;
+    @assert Object.getPrototypeOf(ctx) === OffscreenCanvasRenderingContext2D.prototype;
+
+- name: 2d.canvas.host.scaled
+  desc: CSS-scaled canvases get drawn correctly
+  canvas_types: ['HtmlCanvas']
+  size: [50, 25]
+  canvas: 'style="width: 100px; height: 50px"'
+  manual:
+  code: |
+    ctx.fillStyle = '#00f';
+    ctx.fillRect(0, 0, 50, 25);
+    ctx.fillStyle = '#0ff';
+    ctx.fillRect(0, 0, 25, 10);
+  expected: |
+    size 100 50
+    cr.set_source_rgb(0, 0, 1)
+    cr.rectangle(0, 0, 100, 50)
+    cr.fill()
+    cr.set_source_rgb(0, 1, 1)
+    cr.rectangle(0, 0, 50, 20)
+    cr.fill()
+
+- name: 2d.canvas.context.type.exists
+  desc: The 2D context interface is a property of '{{ root }}'
+  notes: &bindings Defined in "Web IDL" (draft)
+  code: |
+    @assert {{ root }}.{{ context_object }};
+  variants: &get-context-definition
+    - HtmlCanvas:
+        append_variants_to_name: false
+        canvas_types: ['HtmlCanvas']
+        root: window
+        context_object: CanvasRenderingContext2D
+      OffscreenCanvas:
+        append_variants_to_name: false
+        canvas_types: ['OffscreenCanvas']
+        root: window
+        context_object: OffscreenCanvasRenderingContext2D
+      Worker:
+        append_variants_to_name: false
+        canvas_types: ['Worker']
+        root: self
+        context_object: OffscreenCanvasRenderingContext2D
+
+- name: 2d.canvas.context.type.extend
+  desc: Interface methods can be added
+  notes: *bindings
+  code: |
+    {{ root }}.{{ context_object }}.prototype.fillRectGreen = function (x, y, w, h)
+    {
+        this.fillStyle = '#0f0';
+        this.fillRect(x, y, w, h);
+    };
+    ctx.fillStyle = '#f00';
+    ctx.fillRectGreen(0, 0, 100, 50);
+    @assert pixel 50,25 == 0,255,0,255;
+  expected: green
+  variants: *get-context-definition
+
+- name: 2d.canvas.context.type.replace
+  desc: Interface methods can be overridden
+  notes: *bindings
+  code: |
+    var fillRect = {{ root }}.{{ context_object }}.prototype.fillRect;
+    {{ root }}.{{ context_object }}.prototype.fillRect = function (x, y, w, h)
+    {
+        this.fillStyle = '#0f0';
+        fillRect.call(this, x, y, w, h);
+    };
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(0, 0, 100, 50);
+    @assert pixel 50,25 == 0,255,0,255;
+  expected: green
+  variants: *get-context-definition
+
+- name: 2d.canvas.context.type.prototype
+  desc: window.CanvasRenderingContext2D.prototype are not [[Writable]] and not [[Configurable]],
+    and its methods are [[Configurable]].
+  notes: *bindings
+  code: |
+    @assert {{ root }}.{{ context_object }}.prototype;
+    @assert {{ root }}.{{ context_object }}.prototype.fill;
+    {{ root }}.{{ context_object }}.prototype = null;
+    @assert {{ root }}.{{ context_object }}.prototype;
+    delete {{ root }}.{{ context_object }}.prototype;
+    @assert {{ root }}.{{ context_object }}.prototype;
+    {{ root }}.{{ context_object }}.prototype.fill = 1;
+    @assert {{ root }}.{{ context_object }}.prototype.fill === 1;
+    delete {{ root }}.{{ context_object }}.prototype.fill;
+    @assert {{ root }}.{{ context_object }}.prototype.fill === undefined;
+  variants: *get-context-definition
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/the-canvas-element.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/the-canvas-element.yaml
deleted file mode 100644
index 1ecf8ccd..0000000
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/the-canvas-element.yaml
+++ /dev/null
@@ -1,143 +0,0 @@
-- name: 2d.canvas.context.exists
-  desc: The 2D context is implemented
-  code: |
-    @assert canvas.getContext('2d') !== null;
-
-- name: 2d.canvas.context.invalid.args
-  desc: Calling getContext with invalid arguments.
-  code: |
-    @assert canvas.getContext('') === null;
-    @assert canvas.getContext('2d#') === null;
-    @assert canvas.getContext('This is clearly not a valid context name.') === null;
-    @assert canvas.getContext('2d\0') === null;
-    @assert canvas.getContext('2\uFF44') === null;
-    @assert canvas.getContext('2D') === null;
-    @assert throws TypeError canvas.getContext();
-    @assert canvas.getContext('null') === null;
-    @assert canvas.getContext('undefined') === null;
-
-- name: 2d.canvas.context.extraargs.create
-  desc: The 2D context doesn't throw with extra getContext arguments (new context)
-  code: |
-    @assert document.createElement("canvas").getContext('2d', false, {}, [], 1, "2") !== null;
-    @assert document.createElement("canvas").getContext('2d', 123) !== null;
-    @assert document.createElement("canvas").getContext('2d', "test") !== null;
-    @assert document.createElement("canvas").getContext('2d', undefined) !== null;
-    @assert document.createElement("canvas").getContext('2d', null) !== null;
-    @assert document.createElement("canvas").getContext('2d', Symbol.hasInstance) !== null;
-
-- name: 2d.canvas.context.extraargs.cache
-  desc: The 2D context doesn't throw with extra getContext arguments (cached)
-  code: |
-    @assert canvas.getContext('2d', false, {}, [], 1, "2") !== null;
-    @assert canvas.getContext('2d', 123) !== null;
-    @assert canvas.getContext('2d', "test") !== null;
-    @assert canvas.getContext('2d', undefined) !== null;
-    @assert canvas.getContext('2d', null) !== null;
-    @assert canvas.getContext('2d', Symbol.hasInstance) !== null;
-
-- name: 2d.canvas.context.type.exists
-  desc: The 2D context interface is a property of 'window'
-  notes: &bindings Defined in "Web IDL" (draft)
-  code: |
-    @assert window.CanvasRenderingContext2D;
-
-- name: 2d.canvas.context.type.prototype
-  desc: window.CanvasRenderingContext2D.prototype are not [[Writable]] and not [[Configurable]],
-    and its methods are [[Configurable]].
-  notes: *bindings
-  code: |
-    @assert window.CanvasRenderingContext2D.prototype;
-    @assert window.CanvasRenderingContext2D.prototype.fill;
-    window.CanvasRenderingContext2D.prototype = null;
-    @assert window.CanvasRenderingContext2D.prototype;
-    delete window.CanvasRenderingContext2D.prototype;
-    @assert window.CanvasRenderingContext2D.prototype;
-    window.CanvasRenderingContext2D.prototype.fill = 1;
-    @assert window.CanvasRenderingContext2D.prototype.fill === 1;
-    delete window.CanvasRenderingContext2D.prototype.fill;
-    @assert window.CanvasRenderingContext2D.prototype.fill === undefined;
-
-- name: 2d.canvas.context.type.replace
-  desc: Interface methods can be overridden
-  notes: *bindings
-  code: |
-    var fillRect = window.CanvasRenderingContext2D.prototype.fillRect;
-    window.CanvasRenderingContext2D.prototype.fillRect = function (x, y, w, h)
-    {
-        this.fillStyle = '#0f0';
-        fillRect.call(this, x, y, w, h);
-    };
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(0, 0, 100, 50);
-    @assert pixel 50,25 == 0,255,0,255;
-  expected: green
-
-- name: 2d.canvas.context.type.extend
-  desc: Interface methods can be added
-  notes: *bindings
-  code: |
-    window.CanvasRenderingContext2D.prototype.fillRectGreen = function (x, y, w, h)
-    {
-        this.fillStyle = '#0f0';
-        this.fillRect(x, y, w, h);
-    };
-    ctx.fillStyle = '#f00';
-    ctx.fillRectGreen(0, 0, 100, 50);
-    @assert pixel 50,25 == 0,255,0,255;
-  expected: green
-
-- name: 2d.canvas.context.unique
-  desc: getContext('2d') returns the same object
-  code: |
-    @assert canvas.getContext('2d') === canvas.getContext('2d');
-
-- name: 2d.canvas.context.shared
-  desc: getContext('2d') returns objects which share canvas state
-  code: |
-    var ctx2 = canvas.getContext('2d');
-    ctx.fillStyle = '#f00';
-    ctx2.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    @assert pixel 50,25 == 0,255,0,255;
-  expected: green
-
-- name: 2d.canvas.host.scaled
-  desc: CSS-scaled canvases get drawn correctly
-  size: 50, 25
-  canvas: 'style="width: 100px; height: 50px"'
-  manual:
-  code: |
-    ctx.fillStyle = '#00f';
-    ctx.fillRect(0, 0, 50, 25);
-    ctx.fillStyle = '#0ff';
-    ctx.fillRect(0, 0, 25, 10);
-  expected: |
-    size 100 50
-    cr.set_source_rgb(0, 0, 1)
-    cr.rectangle(0, 0, 100, 50)
-    cr.fill()
-    cr.set_source_rgb(0, 1, 1)
-    cr.rectangle(0, 0, 50, 20)
-    cr.fill()
-
-- name: 2d.canvas.host.reference
-  desc: CanvasRenderingContext2D.canvas refers back to its canvas
-  code: |
-    @assert ctx.canvas === canvas;
-
-- name: 2d.canvas.host.readonly
-  desc: CanvasRenderingContext2D.canvas is readonly
-  code: |
-    var c = document.createElement('canvas');
-    var d = ctx.canvas;
-    @assert c !== d;
-    ctx.canvas = c;
-    @assert ctx.canvas === d;
-
-- name: 2d.canvas.context.prototype
-  desc: checks CanvasRenderingContext2D prototype
-  code: |
-    @assert Object.getPrototypeOf(CanvasRenderingContext2D.prototype) === Object.prototype;
-    @assert Object.getPrototypeOf(ctx) === CanvasRenderingContext2D.prototype;
-    t.done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/offscreen/the-offscreen-canvas.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/offscreen/the-offscreen-canvas.yaml
deleted file mode 100644
index ccabe09..0000000
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/offscreen/the-offscreen-canvas.yaml
+++ /dev/null
@@ -1,269 +0,0 @@
-- name: 2d.canvas.host.reference
-  desc: canvas refers back to its canvas
-  code: |
-    @assert ctx.canvas === canvas;
-    t.done();
-
-- name: 2d.canvas.host.readonly
-  desc: canvas is readonly
-  code: |
-    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-    var d = ctx.canvas;
-    @assert offscreenCanvas2 !== d;
-    ctx.canvas = offscreenCanvas2;
-    @assert ctx.canvas === d;
-    t.done();
-
-- name: 2d.canvas.context.exists
-  desc: The 2D context is implemented
-  code: |
-    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-    @assert offscreenCanvas2.getContext('2d') !== null;
-    t.done();
-
-- name: 2d.canvas.context.extraargs.create
-  desc: The 2D context doesn't throw with extra getContext arguments (new context)
-  code: |
-    @assert (new OffscreenCanvas(100, 50)).getContext('2d', false, {}, [], 1, "2") !== null;
-    @assert (new OffscreenCanvas(100, 50)).getContext('2d', 123) !== null;
-    @assert (new OffscreenCanvas(100, 50)).getContext('2d', "test") !== null;
-    @assert (new OffscreenCanvas(100, 50)).getContext('2d', undefined) !== null;
-    @assert (new OffscreenCanvas(100, 50)).getContext('2d', null) !== null;
-    @assert (new OffscreenCanvas(100, 50)).getContext('2d', Symbol.hasInstance) !== null;
-    t.done();
-
-- name: 2d.canvas.context.extraargs.cache
-  desc: The 2D context doesn't throw with extra getContext arguments (cached)
-  code: |
-    @assert canvas.getContext('2d', false, {}, [], 1, "2") !== null;
-    @assert canvas.getContext('2d', 123) !== null;
-    @assert canvas.getContext('2d', "test") !== null;
-    @assert canvas.getContext('2d', undefined) !== null;
-    @assert canvas.getContext('2d', null) !== null;
-    @assert canvas.getContext('2d', Symbol.hasInstance) !== null;
-    t.done();
-
-- name: 2d.canvas.context.unique
-  desc: getContext('2d') returns the same object
-  code: |
-    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-    @assert offscreenCanvas2.getContext('2d') === offscreenCanvas2.getContext('2d');
-    t.done();
-
-- name: 2d.canvas.context.shared
-  desc: getContext('2d') returns objects which share canvas state
-  code: |
-    var ctx2 = canvas.getContext('2d');
-    ctx.fillStyle = '#f00';
-    ctx2.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    @assert pixel 50,25 == 0,255,0,255;
-    t.done();
-
-- name: 2d.canvas.context.emptystring
-  desc: getContext with empty string returns null
-  code: |
-    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-    @assert throws TypeError offscreenCanvas2.getContext("");
-    t.done();
-
-- name: 2d.canvas.context.unrecognised.badname
-  desc: getContext with unrecognised context name returns null
-  code: |
-    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-    @assert throws TypeError offscreenCanvas2.getContext('This is not an implemented context in any real browser');
-    t.done();
-
-- name: 2d.canvas.context.unrecognised.badsuffix
-  desc: Context name "2d" plus a suffix is unrecognised
-  code: |
-    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-    @assert throws TypeError offscreenCanvas2.getContext("2d#");
-    t.done();
-
-- name: 2d.canvas.context.unrecognised.nullsuffix
-  desc: Context name "2d" plus a "\0" suffix is unrecognised
-  code: |
-    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-    @assert throws TypeError offscreenCanvas2.getContext("2d\0");
-    t.done();
-
-- name: 2d.canvas.context.unrecognised.unicode
-  desc: Context name which kind of looks like "2d" is unrecognised
-  code: |
-    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-    @assert throws TypeError offscreenCanvas2.getContext("2\uFF44");
-    t.done();
-
-- name: 2d.canvas.context.casesensitive
-  desc: Context name "2D" is unrecognised; matching is case sensitive
-  code: |
-    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-    @assert throws TypeError offscreenCanvas2.getContext('2D');
-    t.done();
-
-- name: 2d.canvas.context.arguments.missing
-  code: |
-    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
-    @assert throws TypeError offscreenCanvas2.getContext(); @moz-todo
-    t.done();
-
-
-- name: 2d.canvas.host.initial.color
-  desc: Initial state is transparent black
-  code: |
-    @assert pixel 20,20 == 0,0,0,0;
-    t.done();
-
-- name: 2d.canvas.host.initial.reset.different
-  desc: Changing size resets canvas to transparent black
-  code: |
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(0, 0, 50, 50);
-    @assert pixel 20,20 == 255,0,0,255;
-    canvas.width = 50;
-    @assert pixel 20,20 == 0,0,0,0;
-    t.done();
-
-- name: 2d.canvas.host.initial.reset.same
-  desc: Setting size (not changing the value) resets canvas to transparent black
-  code: |
-    canvas.width = 100;
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(0, 0, 50, 50);
-    @assert pixel 20,20 == 255,0,0,255;
-    canvas.width = 100;
-    @assert pixel 20,20 == 0,0,0,0;
-    t.done();
-
-- name: 2d.canvas.host.initial.reset.path
-  desc: Resetting the canvas state resets the current path
-  code: |
-    canvas.width = 100;
-    ctx.rect(0, 0, 100, 50);
-    canvas.width = 100;
-    ctx.fillStyle = '#f00';
-    ctx.fill();
-    @assert pixel 20,20 == 0,0,0,0;
-    t.done();
-
-- name: 2d.canvas.host.initial.reset.clip
-  desc: Resetting the canvas state resets the current clip region
-  code: |
-    canvas.width = 100;
-    ctx.rect(0, 0, 1, 1);
-    ctx.clip();
-    canvas.width = 100;
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    @assert pixel 20,20 == 0,255,0,255;
-    t.done();
-
-- name: 2d.canvas.host.initial.reset.transform
-  desc: Resetting the canvas state resets the current transformation matrix
-  code: |
-    canvas.width = 100;
-    ctx.scale(0.1, 0.1);
-    canvas.width = 100;
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 100, 50);
-    @assert pixel 20,20 == 0,255,0,255;
-    t.done();
-
-- name: 2d.canvas.host.initial.reset.gradient
-  desc: Resetting the canvas state does not invalidate any existing gradients
-  code: |
-    canvas.width = 50;
-    var g = ctx.createLinearGradient(0, 0, 100, 0);
-    g.addColorStop(0, '#0f0');
-    g.addColorStop(1, '#0f0');
-    canvas.width = 100;
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.fillStyle = g;
-    ctx.fillRect(0, 0, 100, 50);
-    @assert pixel 50,25 == 0,255,0,255;
-    t.done();
-
-- name: 2d.canvas.host.initial.reset.pattern
-  desc: Resetting the canvas state does not invalidate any existing patterns
-  code: |
-    canvas.width = 30;
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(0, 0, 30, 50);
-    var p = ctx.createPattern(canvas, 'repeat-x');
-    canvas.width = 100;
-    ctx.fillStyle = '#f00';
-    ctx.fillRect(0, 0, 100, 50);
-    ctx.fillStyle = p;
-    ctx.fillRect(0, 0, 100, 50);
-    @assert pixel 50,25 == 0,255,0,255;
-    t.done();
-
-- name: 2d.canvas.host.size.attributes.idl.set.zero
-  desc: Setting width/height IDL attributes to 0
-  code: |
-    canvas.width = 0;
-    canvas.height = 0;
-    @assert canvas.width === 0;
-    @assert canvas.height === 0;
-    t.done();
-
-- name: 2d.canvas.host.size.attributes.idl
-  desc: Getting/setting width/height IDL attributes
-  webidl:
-  - es-unsigned-long
-  code: |
-    canvas.width = "100";
-    canvas.height = "100";
-    @assert canvas.width === 100;
-    @assert canvas.height === 100;
-    canvas.width = "+1.5e2";
-    canvas.height = "0x96";
-    @assert canvas.width === 150;
-    @assert canvas.height === 150;
-    canvas.width = 301.999;
-    canvas.height = 301.001;
-    @assert canvas.width === 301;
-    @assert canvas.height === 301;
-    @assert throws TypeError canvas.width = "400x";
-    @assert throws TypeError canvas.height = "foo";
-    @assert canvas.width === 301;
-    @assert canvas.height === 301;
-    t.done();
-
-- name: 2d.canvas.host.size.attributes.default
-  desc: Default width/height when attributes are missing
-  code: |
-    @assert canvas.width === 100;
-    @assert canvas.height === 50;
-    t.done();
-
-- name: 2d.canvas.host.size.attributes.reflect.setidl
-  desc: Setting IDL attributes updates IDL and content attributes
-  code: |
-    canvas.width = 120;
-    canvas.height = 60;
-    @assert canvas.width === 120;
-    @assert canvas.height === 60;
-    t.done();
-
-- name: 2d.canvas.host.size.attributes.reflect.setidlzero
-  desc: Setting IDL attributes to 0 updates IDL and content attributes
-  code: |
-    canvas.width = 0;
-    canvas.height = 0;
-    @assert canvas.width === 0;
-    @assert canvas.height === 0;
-    t.done();
-
-- name: 2d.canvas.host.size.large
-  notes: Not sure how reasonable this is, but the spec doesn't say there's an upper
-    limit on the size.
-  code: |
-    var n = 2147483647; // 2^31 - 1, which should be supported by any sensible definition of "long"
-    canvas.width = n;
-    canvas.height = n;
-    @assert canvas.width === n;
-    @assert canvas.height === n;
-    t.done();
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.colour.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.colour.html
deleted file mode 100644
index 166732a5..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.colour.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: initial.colour</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/html/canvas/resources/canvas-tests.js"></script>
-<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
-<body class="show_output">
-
-<h1>initial.colour</h1>
-<p class="desc">Initial state is transparent black</p>
-
-<p class="notes">Output should be transparent black (not transparent anything-else), but manual
-verification can only confirm that it's transparent - it's not possible to make
-the actual blackness visible.
-
-<p class="output">Actual output:</p>
-<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-<p class="output expectedtext">Expected output:<p><img src="initial.colour.png" class="output expected" id="expected" alt="">
-<ul id="d"></ul>
-<script>
-var t = async_test("Initial state is transparent black");
-_addTest(function(canvas, ctx) {
-
-_assertPixel(canvas, 20,20, 0,0,0,0);
-
-
-});
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.colour.png b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.colour.png
deleted file mode 100644
index eeedd0f..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.colour.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.different.png b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.different.png
deleted file mode 100644
index d83fdd55b..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.different.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.path.png b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.path.png
deleted file mode 100644
index eeedd0f..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.path.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.same.png b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.same.png
deleted file mode 100644
index eeedd0f..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/initial.reset.same.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.default.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.default.html
deleted file mode 100644
index ecf35285..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.default.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE html>
-<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: size.attributes.default</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/html/canvas/resources/canvas-tests.js"></script>
-<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
-<body class="show_output">
-
-<h1>size.attributes.default</h1>
-<p class="desc">Default width/height when attributes are missing</p>
-
-
-<p class="output">Actual output:</p>
-<canvas id="c" class="output" ><p class="fallback">FAIL (fallback content)</p></canvas>
-<p class="output expectedtext">Expected output:<p><img src="size.attributes.default.png" class="output expected" id="expected" alt="">
-<ul id="d"></ul>
-<script>
-var t = async_test("Default width/height when attributes are missing");
-_addTest(function(canvas, ctx) {
-
-_assertSame(canvas.width, 300, "canvas.width", "300");
-_assertSame(canvas.height, 150, "canvas.height", "150");
-_assert(!canvas.hasAttribute('width'), "!canvas.hasAttribute('width')");
-_assert(!canvas.hasAttribute('height'), "!canvas.hasAttribute('height')");
-
-
-});
-</script>
-
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.default.png b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.default.png
deleted file mode 100644
index a72d047..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.default.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.get.png b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.get.png
deleted file mode 100644
index 47830c8..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.get.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.idl.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.idl.html
deleted file mode 100644
index 1594a1c..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.idl.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!DOCTYPE html>
-<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: size.attributes.idl</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/html/canvas/resources/canvas-tests.js"></script>
-<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
-<body class="show_output">
-
-<h1>size.attributes.idl</h1>
-<p class="desc">Getting/setting width/height IDL attributes</p>
-
-
-<p class="output">Actual output:</p>
-<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-
-<ul id="d"></ul>
-<script>
-var t = async_test("Getting/setting width/height IDL attributes");
-_addTest(function(canvas, ctx) {
-
-canvas.width = "100";
-canvas.height = "100";
-_assertSame(canvas.width, 100, "canvas.width", "100");
-_assertSame(canvas.height, 100, "canvas.height", "100");
-
-canvas.width = "+1.5e2";
-canvas.height = "0x96";
-_assertSame(canvas.width, 150, "canvas.width", "150");
-_assertSame(canvas.height, 150, "canvas.height", "150");
-
-canvas.width = 200 - Math.pow(2, 32);
-canvas.height = 200 - Math.pow(2, 32);
-_assertSame(canvas.width, 200, "canvas.width", "200");
-_assertSame(canvas.height, 200, "canvas.height", "200");
-
-canvas.width = 301.999;
-canvas.height = 301.001;
-_assertSame(canvas.width, 301, "canvas.width", "301");
-_assertSame(canvas.height, 301, "canvas.height", "301");
-
-canvas.width = "400x";
-canvas.height = "foo";
-_assertSame(canvas.width, 0, "canvas.width", "0");
-_assertSame(canvas.height, 0, "canvas.height", "0");
-
-
-});
-</script>
-
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setcontent.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setcontent.html
deleted file mode 100644
index a25c4b7..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setcontent.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE html>
-<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: size.attributes.reflect.setcontent</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/html/canvas/resources/canvas-tests.js"></script>
-<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
-<body class="show_output">
-
-<h1>size.attributes.reflect.setcontent</h1>
-<p class="desc">Setting content attributes updates IDL and content attributes</p>
-
-
-<p class="output">Actual output:</p>
-<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-<p class="output expectedtext">Expected output:<p><img src="size.attributes.reflect.setcontent.png" class="output expected" id="expected" alt="">
-<ul id="d"></ul>
-<script>
-var t = async_test("Setting content attributes updates IDL and content attributes");
-_addTest(function(canvas, ctx) {
-
-canvas.setAttribute('width', '120');
-canvas.setAttribute('height', '60');
-_assertSame(canvas.getAttribute('width'), '120', "canvas.getAttribute('width')", "'120'");
-_assertSame(canvas.getAttribute('height'), '60', "canvas.getAttribute('height')", "'60'");
-_assertSame(canvas.width, 120, "canvas.width", "120");
-_assertSame(canvas.height, 60, "canvas.height", "60");
-
-
-});
-</script>
-
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setcontent.png b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setcontent.png
deleted file mode 100644
index 47830c8..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setcontent.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidl.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidl.html
deleted file mode 100644
index e228276d..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidl.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE html>
-<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: size.attributes.reflect.setidl</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/html/canvas/resources/canvas-tests.js"></script>
-<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
-<body class="show_output">
-
-<h1>size.attributes.reflect.setidl</h1>
-<p class="desc">Setting IDL attributes updates IDL and content attributes</p>
-
-
-<p class="output">Actual output:</p>
-<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-<p class="output expectedtext">Expected output:<p><img src="size.attributes.reflect.setidl.png" class="output expected" id="expected" alt="">
-<ul id="d"></ul>
-<script>
-var t = async_test("Setting IDL attributes updates IDL and content attributes");
-_addTest(function(canvas, ctx) {
-
-canvas.width = 120;
-canvas.height = 60;
-_assertSame(canvas.getAttribute('width'), '120', "canvas.getAttribute('width')", "'120'");
-_assertSame(canvas.getAttribute('height'), '60', "canvas.getAttribute('height')", "'60'");
-_assertSame(canvas.width, 120, "canvas.width", "120");
-_assertSame(canvas.height, 60, "canvas.height", "60");
-
-
-});
-</script>
-
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidl.png b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidl.png
deleted file mode 100644
index 47830c8..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidl.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.removed.png b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.removed.png
deleted file mode 100644
index 1ebf30d..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.removed.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.set.png b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.set.png
deleted file mode 100644
index 47830c8..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.set.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.extend.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.extend.html
deleted file mode 100644
index e17209f4..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.extend.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: type.extend</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/html/canvas/resources/canvas-tests.js"></script>
-<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
-<body class="show_output">
-
-<h1>type.extend</h1>
-<p class="desc">HTMLCanvasElement methods can be added, and the new methods used by canvases</p>
-
-<p class="notes">Defined in "Web IDL" (draft)
-<p class="output">Actual output:</p>
-<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-
-<ul id="d"></ul>
-<script>
-var t = async_test("HTMLCanvasElement methods can be added, and the new methods used by canvases");
-_addTest(function(canvas, ctx) {
-
-window.HTMLCanvasElement.prototype.getZero = function () { return 0; };
-_assertSame(canvas.getZero(), 0, "canvas.getZero()", "0");
-
-
-});
-</script>
-
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.prototype.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.prototype.html
deleted file mode 100644
index f47f7553..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.prototype.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE html>
-<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: type.prototype</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/html/canvas/resources/canvas-tests.js"></script>
-<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
-<body class="show_output">
-
-<h1>type.prototype</h1>
-<p class="desc">window.HTMLCanvasElement has prototype, which is { ReadOnly, DontDelete }. prototype has getContext, which is not</p>
-
-<p class="notes">Defined in "Web IDL" (draft)
-<p class="output">Actual output:</p>
-<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-
-<ul id="d"></ul>
-<script>
-var t = async_test("window.HTMLCanvasElement has prototype, which is { ReadOnly, DontDelete }. prototype has getContext, which is not");
-_addTest(function(canvas, ctx) {
-
-_assert(window.HTMLCanvasElement.prototype, "window.HTMLCanvasElement.prototype");
-_assert(window.HTMLCanvasElement.prototype.getContext, "window.HTMLCanvasElement.prototype.getContext");
-window.HTMLCanvasElement.prototype = null;
-_assert(window.HTMLCanvasElement.prototype, "window.HTMLCanvasElement.prototype");
-delete window.HTMLCanvasElement.prototype;
-_assert(window.HTMLCanvasElement.prototype, "window.HTMLCanvasElement.prototype");
-window.HTMLCanvasElement.prototype.getContext = 1;
-_assertSame(window.HTMLCanvasElement.prototype.getContext, 1, "window.HTMLCanvasElement.prototype.getContext", "1");
-delete window.HTMLCanvasElement.prototype.getContext;
-_assertSame(window.HTMLCanvasElement.prototype.getContext, undefined, "window.HTMLCanvasElement.prototype.getContext", "undefined");
-
-
-});
-</script>
-
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.replace.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.replace.html
deleted file mode 100644
index e67fe7c4..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/type.replace.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
-<title>Canvas test: type.replace</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/html/canvas/resources/canvas-tests.js"></script>
-<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
-<body class="show_output">
-
-<h1>type.replace</h1>
-<p class="desc">HTMLCanvasElement methods can be replaced, and the replacement methods used by canvases</p>
-
-<p class="notes">Defined in "Web IDL" (draft)
-<p class="output">Actual output:</p>
-<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
-
-<ul id="d"></ul>
-<script>
-var t = async_test("HTMLCanvasElement methods can be replaced, and the replacement methods used by canvases");
-_addTest(function(canvas, ctx) {
-
-window.HTMLCanvasElement.prototype.getContext = function (name) { return 0; };
-_assertSame(canvas.getContext('2d'), 0, "canvas.getContext('2d')", "0");
-
-
-});
-</script>
-
diff --git a/third_party/blink/web_tests/external/wpt/intersection-observer/callback-cross-realm-report-exception.html b/third_party/blink/web_tests/external/wpt/intersection-observer/callback-cross-realm-report-exception.html
index 0bec7204..7fa97916 100644
--- a/third_party/blink/web_tests/external/wpt/intersection-observer/callback-cross-realm-report-exception.html
+++ b/third_party/blink/web_tests/external/wpt/intersection-observer/callback-cross-realm-report-exception.html
@@ -24,7 +24,7 @@
     t.step_timeout(() => {
       assert_array_equals(onerrorCalls, ["frame1"]);
       t.done();
-    }, 25);
+    }, 100);
   });
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures_bidi.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures_bidi.py
index a9cefd00..dd99e80 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures_bidi.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/support/fixtures_bidi.py
@@ -149,7 +149,7 @@
                 asyncio.shield(future),
                 timeout=timeout * configuration["timeout_multiplier"],
             )
-        except asyncio.exceptions.TimeoutError:
+        except asyncio.TimeoutError:
             raise TimeoutException("Future did not resolve within the given timeout")
 
     return wait_for_future_safe
diff --git a/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-center-special-ligatures-expected.html b/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-center-special-ligatures-expected.html
deleted file mode 100644
index bf2c71b..0000000
--- a/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-center-special-ligatures-expected.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE HTML>
-<head>
-<meta charset="UTF-8">
-</head>
-<canvas id="canvas" width="700" height="200">
-  <p class="fallback">FAIL (fallback content)</p>
-</canvas>
-<script>
-  const canvas = document.getElementById("canvas");
-  var ctx = canvas.getContext('2d');
-
-  ctx.font = '50px Arial';
-  const midpoint = canvas.width / 2;
-
-  // Reference line. Text should be centered around it.
-  ctx.fillStyle = '#0f0';
-  ctx.fillRect(midpoint, 0, 1, 200);
-
-  ctx.fillStyle = 'black';
-  ctx.textAlign = 'left';
-
-  let metrics = ctx.measureText('غالي والطلب رخيص');
-  ctx.fillText('غالي والطلب رخيص', midpoint - metrics.width / 2, 50);
-
-  metrics = ctx.measureText('اين المكتبة؟');
-  ctx.fillText('اين المكتبة؟', midpoint - metrics.width / 2, 150);
-</script>
diff --git a/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-center-special-ligatures-worker-expected.html b/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-center-special-ligatures-worker-expected.html
deleted file mode 100644
index bf2c71b..0000000
--- a/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-center-special-ligatures-worker-expected.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE HTML>
-<head>
-<meta charset="UTF-8">
-</head>
-<canvas id="canvas" width="700" height="200">
-  <p class="fallback">FAIL (fallback content)</p>
-</canvas>
-<script>
-  const canvas = document.getElementById("canvas");
-  var ctx = canvas.getContext('2d');
-
-  ctx.font = '50px Arial';
-  const midpoint = canvas.width / 2;
-
-  // Reference line. Text should be centered around it.
-  ctx.fillStyle = '#0f0';
-  ctx.fillRect(midpoint, 0, 1, 200);
-
-  ctx.fillStyle = 'black';
-  ctx.textAlign = 'left';
-
-  let metrics = ctx.measureText('غالي والطلب رخيص');
-  ctx.fillText('غالي والطلب رخيص', midpoint - metrics.width / 2, 50);
-
-  metrics = ctx.measureText('اين المكتبة؟');
-  ctx.fillText('اين المكتبة؟', midpoint - metrics.width / 2, 150);
-</script>
diff --git a/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-center-special-ligatures-worker.html b/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-center-special-ligatures-worker.html
deleted file mode 100644
index 11058b4e..0000000
--- a/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-center-special-ligatures-worker.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE HTML>
-<head>
-<meta charset="UTF-8">
-</head>
-<canvas id="output" width="700" height="200">
-  <p class="fallback">FAIL (fallback content)</p>
-</canvas>
-<script id='myWorker' type='text/worker'>
-  self.onmessage = function(e) {
-    const canvas = new OffscreenCanvas(700, 200);
-    const ctx = canvas.getContext('2d');
-
-    ctx.font = '50px Arial';
-    const midpoint = canvas.width / 2;
-
-    // Reference line. Text should be centered around it.
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(midpoint, 0, 1, 200);
-
-    ctx.fillStyle = 'black';
-    ctx.textAlign = 'center';
-    ctx.fillText('غالي والطلب رخيص', midpoint, 50);
-    ctx.fillText('اين المكتبة؟', midpoint, 150);
-
-    const image = canvas.transferToImageBitmap();
-    self.postMessage(image, [image]);
-  };
-</script>
-<script>
-  if (window.testRunner) {
-    testRunner.waitUntilDone();
-  }
-
-  var blob = new Blob([document.getElementById('myWorker').textContent]);
-  var worker = new Worker(URL.createObjectURL(blob));
-  worker.addEventListener('message', msg => {
-    var outputCtx = document.getElementById('output').getContext('bitmaprenderer');
-    outputCtx.transferFromImageBitmap(msg.data);
-    if (window.testRunner) {
-      testRunner.notifyDone();
-    }
-  });
-  worker.postMessage("");
-</script>
diff --git a/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-center-special-ligatures.html b/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-center-special-ligatures.html
deleted file mode 100644
index bdd3a48b..0000000
--- a/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-center-special-ligatures.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE HTML>
-<head>
-<meta charset="UTF-8">
-</head>
-<canvas id="output" width="700" height="200">
-  <p class="fallback">FAIL (fallback content)</p>
-</canvas>
-<script>
-  const canvas = new OffscreenCanvas(700, 300);
-  const ctx = canvas.getContext('2d');
-
-  ctx.font = '50px Arial';
-  const midpoint = canvas.width / 2;
-
-  // Reference line. Text should be centered around it.
-  ctx.fillStyle = '#0f0';
-  ctx.fillRect(midpoint, 0, 1, 200);
-
-  ctx.fillStyle = 'black';
-  ctx.textAlign = 'center';
-  ctx.fillText('غالي والطلب رخيص', midpoint, 50);
-  ctx.fillText('اين المكتبة؟', midpoint, 150);
-
-  const output_ctx = document.getElementById('output').getContext('2d');
-  output_ctx.drawImage(canvas, 0 , 0);
-</script>
diff --git a/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-right-special-ligatures-expected.html b/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-right-special-ligatures-expected.html
deleted file mode 100644
index afef968c..0000000
--- a/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-right-special-ligatures-expected.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE HTML>
-<head>
-<meta charset="UTF-8">
-</head>
-<canvas id="canvas" width="700" height="200">
-  <p class="fallback">FAIL (fallback content)</p>
-</canvas>
-<script>
-  const canvas = document.getElementById("canvas");
-  var ctx = canvas.getContext('2d');
-
-  ctx.font = '50px Arial';
-  const base_position = 600;
-
-  // Reference line. Text should be centered around it.
-  ctx.fillStyle = '#0f0';
-  ctx.fillRect(base_position, 0, 1, 200);
-
-  ctx.fillStyle = 'black';
-  ctx.textAlign = 'left';
-
-  let metrics = ctx.measureText('غالي والطلب رخيص');
-  ctx.fillText('غالي والطلب رخيص', base_position - metrics.width, 50);
-
-  metrics = ctx.measureText('اين المكتبة؟');
-  ctx.fillText('اين المكتبة؟', base_position - metrics.width, 150);
-</script>
diff --git a/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-right-special-ligatures-worker-expected.html b/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-right-special-ligatures-worker-expected.html
deleted file mode 100644
index afef968c..0000000
--- a/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-right-special-ligatures-worker-expected.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE HTML>
-<head>
-<meta charset="UTF-8">
-</head>
-<canvas id="canvas" width="700" height="200">
-  <p class="fallback">FAIL (fallback content)</p>
-</canvas>
-<script>
-  const canvas = document.getElementById("canvas");
-  var ctx = canvas.getContext('2d');
-
-  ctx.font = '50px Arial';
-  const base_position = 600;
-
-  // Reference line. Text should be centered around it.
-  ctx.fillStyle = '#0f0';
-  ctx.fillRect(base_position, 0, 1, 200);
-
-  ctx.fillStyle = 'black';
-  ctx.textAlign = 'left';
-
-  let metrics = ctx.measureText('غالي والطلب رخيص');
-  ctx.fillText('غالي والطلب رخيص', base_position - metrics.width, 50);
-
-  metrics = ctx.measureText('اين المكتبة؟');
-  ctx.fillText('اين المكتبة؟', base_position - metrics.width, 150);
-</script>
diff --git a/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-right-special-ligatures-worker.html b/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-right-special-ligatures-worker.html
deleted file mode 100644
index f45182de..0000000
--- a/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-right-special-ligatures-worker.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE HTML>
-<head>
-<meta charset="UTF-8">
-</head>
-<canvas id="output" width="700" height="200">
-  <p class="fallback">FAIL (fallback content)</p>
-</canvas>
-<script id='myWorker' type='text/worker'>
-  self.onmessage = function(e) {
-    const canvas = new OffscreenCanvas(700, 200);
-    const ctx = canvas.getContext('2d');
-
-    ctx.font = '50px Arial';
-    const base_position = 600;
-
-    // Reference line. Text should be left from it.
-    ctx.fillStyle = '#0f0';
-    ctx.fillRect(base_position, 0, 1, 200);
-
-    ctx.fillStyle = 'black';
-    ctx.textAlign = 'right';
-    ctx.fillText('غالي والطلب رخيص', base_position, 50);
-    ctx.fillText('اين المكتبة؟', base_position, 150);
-
-    const image = canvas.transferToImageBitmap();
-    self.postMessage(image, [image]);
-  };
-</script>
-<script>
-  if (window.testRunner) {
-    testRunner.waitUntilDone();
-  }
-
-  var blob = new Blob([document.getElementById('myWorker').textContent]);
-  var worker = new Worker(URL.createObjectURL(blob));
-  worker.addEventListener('message', msg => {
-    var outputCtx = document.getElementById('output').getContext('bitmaprenderer');
-    outputCtx.transferFromImageBitmap(msg.data);
-    if (window.testRunner) {
-      testRunner.notifyDone();
-    }
-  });
-  worker.postMessage("");
-</script>
diff --git a/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-right-special-ligatures.html b/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-right-special-ligatures.html
deleted file mode 100644
index 891780ec..0000000
--- a/third_party/blink/web_tests/fast/canvas/OffscreenCanvas-textAlign-right-special-ligatures.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE HTML>
-<head>
-<meta charset="UTF-8">
-</head>
-<canvas id="output" width="700" height="200">
-  <p class="fallback">FAIL (fallback content)</p>
-</canvas>
-<script>
-  const canvas = new OffscreenCanvas(700, 300);
-  const ctx = canvas.getContext('2d');
-
-  ctx.font = '50px Arial';
-  const base_position = 600;
-
-  // Reference line. Text should be left from it.
-  ctx.fillStyle = '#0f0';
-  ctx.fillRect(base_position, 0, 1, 200);
-
-  ctx.fillStyle = 'black';
-  ctx.textAlign = 'right';
-  ctx.fillText('غالي والطلب رخيص', base_position, 50);
-  ctx.fillText('اين المكتبة؟', base_position, 150);
-
-  const output_ctx = document.getElementById('output').getContext('2d');
-  output_ctx.drawImage(canvas, 0 , 0);
-</script>
diff --git a/third_party/blink/web_tests/fast/canvas/canvas-textAlign-center-special-ligatures-expected.html b/third_party/blink/web_tests/fast/canvas/canvas-textAlign-center-special-ligatures-expected.html
deleted file mode 100644
index bf2c71b..0000000
--- a/third_party/blink/web_tests/fast/canvas/canvas-textAlign-center-special-ligatures-expected.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE HTML>
-<head>
-<meta charset="UTF-8">
-</head>
-<canvas id="canvas" width="700" height="200">
-  <p class="fallback">FAIL (fallback content)</p>
-</canvas>
-<script>
-  const canvas = document.getElementById("canvas");
-  var ctx = canvas.getContext('2d');
-
-  ctx.font = '50px Arial';
-  const midpoint = canvas.width / 2;
-
-  // Reference line. Text should be centered around it.
-  ctx.fillStyle = '#0f0';
-  ctx.fillRect(midpoint, 0, 1, 200);
-
-  ctx.fillStyle = 'black';
-  ctx.textAlign = 'left';
-
-  let metrics = ctx.measureText('غالي والطلب رخيص');
-  ctx.fillText('غالي والطلب رخيص', midpoint - metrics.width / 2, 50);
-
-  metrics = ctx.measureText('اين المكتبة؟');
-  ctx.fillText('اين المكتبة؟', midpoint - metrics.width / 2, 150);
-</script>
diff --git a/third_party/blink/web_tests/fast/canvas/canvas-textAlign-center-special-ligatures.html b/third_party/blink/web_tests/fast/canvas/canvas-textAlign-center-special-ligatures.html
deleted file mode 100644
index ab50cafa..0000000
--- a/third_party/blink/web_tests/fast/canvas/canvas-textAlign-center-special-ligatures.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE HTML>
-<head>
-<meta charset="UTF-8">
-</head>
-<canvas id="canvas" width="700" height="200">
-  <p class="fallback">FAIL (fallback content)</p>
-</canvas>
-<script>
-  const canvas = document.getElementById("canvas");
-  const ctx = canvas.getContext('2d');
-
-  ctx.font = '50px Arial';
-  const midpoint = canvas.width / 2;
-
-  // Reference line. Text should be centered around it.
-  ctx.fillStyle = '#0f0';
-  ctx.fillRect(midpoint, 0, 1, 200);
-
-  ctx.fillStyle = 'black';
-  ctx.textAlign = 'center';
-  ctx.fillText('غالي والطلب رخيص', midpoint, 50);
-  ctx.fillText('اين المكتبة؟', midpoint, 150);
-</script>
diff --git a/third_party/blink/web_tests/fast/canvas/canvas-textAlign-right-special-ligatures-expected.html b/third_party/blink/web_tests/fast/canvas/canvas-textAlign-right-special-ligatures-expected.html
deleted file mode 100644
index afef968c..0000000
--- a/third_party/blink/web_tests/fast/canvas/canvas-textAlign-right-special-ligatures-expected.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE HTML>
-<head>
-<meta charset="UTF-8">
-</head>
-<canvas id="canvas" width="700" height="200">
-  <p class="fallback">FAIL (fallback content)</p>
-</canvas>
-<script>
-  const canvas = document.getElementById("canvas");
-  var ctx = canvas.getContext('2d');
-
-  ctx.font = '50px Arial';
-  const base_position = 600;
-
-  // Reference line. Text should be centered around it.
-  ctx.fillStyle = '#0f0';
-  ctx.fillRect(base_position, 0, 1, 200);
-
-  ctx.fillStyle = 'black';
-  ctx.textAlign = 'left';
-
-  let metrics = ctx.measureText('غالي والطلب رخيص');
-  ctx.fillText('غالي والطلب رخيص', base_position - metrics.width, 50);
-
-  metrics = ctx.measureText('اين المكتبة؟');
-  ctx.fillText('اين المكتبة؟', base_position - metrics.width, 150);
-</script>
diff --git a/third_party/blink/web_tests/fast/canvas/canvas-textAlign-right-special-ligatures.html b/third_party/blink/web_tests/fast/canvas/canvas-textAlign-right-special-ligatures.html
deleted file mode 100644
index 4305a03..0000000
--- a/third_party/blink/web_tests/fast/canvas/canvas-textAlign-right-special-ligatures.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE HTML>
-<head>
-<meta charset="UTF-8">
-</head>
-<canvas id="canvas" width="700" height="200">
-  <p class="fallback">FAIL (fallback content)</p>
-</canvas>
-<script>
-  const canvas = document.getElementById("canvas");
-  const ctx = canvas.getContext('2d');
-
-  ctx.font = '50px Arial';
-  const base_position = 600;
-
-  // Reference line. Text should be left from it.
-  ctx.fillStyle = '#0f0';
-  ctx.fillRect(base_position, 0, 1, 200);
-
-  ctx.fillStyle = 'black';
-  ctx.textAlign = 'right';
-  ctx.fillText('غالي والطلب رخيص', base_position, 50);
-  ctx.fillText('اين المكتبة؟', base_position, 150);
-</script>
diff --git a/third_party/blink/web_tests/http/tests/devtools/service-workers/user-agent-override.js b/third_party/blink/web_tests/http/tests/devtools/service-workers/user-agent-override.js
index f4a6a39..16f338ad 100644
--- a/third_party/blink/web_tests/http/tests/devtools/service-workers/user-agent-override.js
+++ b/third_party/blink/web_tests/http/tests/devtools/service-workers/user-agent-override.js
@@ -38,7 +38,8 @@
       function sniff(e) {
         if (e.data && regex.test(e.data.messageText)) {
           resolve(e.data);
-          SDK.consoleModel.removeEventListener(SDK.ConsoleModel.Events.MessageAdded, sniff);
+          const consoleModel = SDK.TargetManager.TargetManager.instance().primaryPageTarget().model(SDK.ConsoleModel.ConsoleModel);
+          consoleModel.removeEventListener(SDK.ConsoleModel.Events.MessageAdded, sniff);
         }
       }
     });
diff --git a/third_party/blink/web_tests/inspector-protocol/layout-fonts/cross-platform-cbdt-sbix-cff2-expected.txt b/third_party/blink/web_tests/inspector-protocol/layout-fonts/cross-platform-cbdt-sbix-cff2-expected.txt
index acb88eab..bb8f681d 100644
--- a/third_party/blink/web_tests/inspector-protocol/layout-fonts/cross-platform-cbdt-sbix-cff2-expected.txt
+++ b/third_party/blink/web_tests/inspector-protocol/layout-fonts/cross-platform-cbdt-sbix-cff2-expected.txt
@@ -1,13 +1,13 @@
 abcdefghijklmnopqrstuvwxyz
 #cff2_support__should_be_using_adobe_variable_font_protoptype_only:
-"Adobe Variable Font Prototype" : 26
+"Adobe Variable Font Prototype (Fontations)" : 26
 
 
 #sbix_support__should_be_using_chromacheck_only:
-"PixelAmbacht ChromaCheck" : 7
+"PixelAmbacht ChromaCheck (Fontations)" : 7
 
 
 #cbdt_support__should_be_using_notocoloremoji_only:
-"ChromaCheck CBDT" : 7
+"ChromaCheck CBDT (Fontations)" : 7
 
 
diff --git a/third_party/blink/web_tests/inspector-protocol/layout-fonts/emoji-cluster-fallback-expected.txt b/third_party/blink/web_tests/inspector-protocol/layout-fonts/emoji-cluster-fallback-expected.txt
index 8a663758..a0fe5cd 100644
--- a/third_party/blink/web_tests/inspector-protocol/layout-fonts/emoji-cluster-fallback-expected.txt
+++ b/third_party/blink/web_tests/inspector-protocol/layout-fonts/emoji-cluster-fallback-expected.txt
@@ -2,7 +2,7 @@
 Note: Emoji rendering output in this text only representation is not equivalent to internal page appearance.
 👮‍♀️👮‍♂️👮🏻‍♀️👮🏻‍♂️👮🏼‍♀️👮🏼‍♂️👮🏽‍♀️👮🏽‍♂️👮🏾‍♀️👮🏾‍♂️👮🏿‍♀️👮🏿‍♂️👱‍♀️👱‍♂️👱🏻‍♀️👱🏻‍♂️👱🏼‍♀️👱🏼‍♂️👱🏽‍♀️👱🏽‍♂️👱🏾‍♀️👱🏾‍♂️👱🏿‍♀️👱🏿‍♂️👳‍♀️👳‍♂️👳🏻‍♀️👳🏻‍♂️👳🏼‍♀️👳🏼‍♂️👳🏽‍♀️👳🏽‍♂️👳🏾‍♀️👳🏾‍♂️👳🏿‍♀️👳🏿‍♂️👷‍♀️👷‍♂️👷🏻‍♀️👷🏻‍♂️👷🏼‍♀️👷🏼‍♂️👷🏽‍♀️👷🏽‍♂️👷🏾‍♀️👷🏾‍♂️👷🏿‍♀️👷🏿‍♂️💂‍♀️💂‍♂️💂🏻‍♀️💂🏻‍♂️💂🏼‍♀️💂🏼‍♂️💂🏽‍♀️💂🏽‍♂️💂🏾‍♀️💂🏾‍♂️💂🏿‍♀️💂🏿‍♂️🕵🏻‍♀️🕵🏻‍♂️🕵🏼‍♀️🕵🏼‍♂️🕵🏽‍♀️🕵🏽‍♂️🕵🏾‍♀️🕵🏾‍♂️🕵🏿‍♀️🕵🏿‍♂️🕵️‍♀️🕵️‍♂️🧙‍♀️🧙‍♂️🧙🏻‍♀️🧙🏻‍♂️🧙🏼‍♀️🧙🏼‍♂️🧙🏽‍♀️🧙🏽‍♂️🧙🏾‍♀️🧙🏾‍♂️🧙🏿‍♀️🧙🏿‍♂️🧚‍♀️🧚‍♂️🧚🏻‍♀️🧚🏻‍♂️🧚🏼‍♀️🧚🏼‍♂️🧚🏽‍♀️🧚🏽‍♂️🧚🏾‍♀️🧚🏾‍♂️🧚🏿‍♀️🧚🏿‍♂️🧛‍♀️🧛‍♂️🧛🏻‍♀️🧛🏻‍♂️🧛🏼‍♀️🧛🏼‍♂️🧛🏽‍♀️🧛🏽‍♂️🧛🏾‍♀️🧛🏾‍♂️🧛🏿‍♀️🧛🏿‍♂️🧜‍♀️🧜‍♂️🧜🏻‍♀️🧜🏻‍♂️🧜🏼‍♀️🧜🏼‍♂️🧜🏽‍♀️🧜🏽‍♂️🧜🏾‍♀️🧜🏾‍♂️🧜🏿‍♀️🧜🏿‍♂️🧝‍♀️🧝‍♂️🧝🏻‍♀️🧝🏻‍♂️🧝🏼‍♀️🧝🏼‍♂️🧝🏽‍♀️🧝🏽‍♂️🧝🏾‍♀️🧝🏾‍♂️🧝🏿‍♀️🧝🏿‍♂️🧞‍♀️🧞‍♂️🧟‍♀️🧟‍♂️⛹🏻‍♀️⛹🏻‍♂️⛹🏼‍♀️⛹🏼‍♂️⛹🏽‍♀️⛹🏽‍♂️⛹🏾‍♀️⛹🏾‍♂️⛹🏿‍♀️⛹🏿‍♂️⛹️‍♀️⛹️‍♂️🏃‍♀️🏃‍♂️🏃🏻‍♀️🏃🏻‍♂️🏃🏼‍♀️🏃🏼‍♂️🏃🏽‍♀️🏃🏽‍♂️🏃🏾‍♀️🏃🏾‍♂️🏃🏿‍♀️🏃🏿‍♂️🏄‍♀️🏄‍♂️🏄🏻‍♀️🏄🏻‍♂️🏄🏼‍♀️🏄🏼‍♂️🏄🏽‍♀️🏄🏽‍♂️🏄🏾‍♀️🏄🏾‍♂️🏄🏿‍♀️🏄🏿‍♂️🏊‍♀️🏊‍♂️🏊🏻‍♀️🏊🏻‍♂️🏊🏼‍♀️🏊🏼‍♂️🏊🏽‍♀️🏊🏽‍♂️🏊🏾‍♀️🏊🏾‍♂️🏊🏿‍♀️🏊🏿‍♂️🏋🏻‍♀️🏋🏻‍♂️🏋🏼‍♀️🏋🏼‍♂️🏋🏽‍♀️🏋🏽‍♂️🏋🏾‍♀️🏋🏾‍♂️🏋🏿‍♀️🏋🏿‍♂️🏋️‍♀️🏋️‍♂️🏌🏻‍♀️🏌🏻‍♂️🏌🏼‍♀️🏌🏼‍♂️🏌🏽‍♀️🏌🏽‍♂️🏌🏾‍♀️🏌🏾‍♂️🏌🏿‍♀️🏌🏿‍♂️🏌️‍♀️🏌️‍♂️👯‍♀️👯‍♂️💆‍♀️💆‍♂️💆🏻‍♀️💆🏻‍♂️💆🏼‍♀️💆🏼‍♂️💆🏽‍♀️💆🏽‍♂️💆🏾‍♀️💆🏾‍♂️💆🏿‍♀️💆🏿‍♂️💇‍♀️💇‍♂️💇🏻‍♀️💇🏻‍♂️💇🏼‍♀️💇🏼‍♂️💇🏽‍♀️💇🏽‍♂️💇🏾‍♀️💇🏾‍♂️💇🏿‍♀️💇🏿‍♂️🚣‍♀️🚣‍♂️🚣🏻‍♀️🚣🏻‍♂️🚣🏼‍♀️🚣🏼‍♂️🚣🏽‍♀️🚣🏽‍♂️🚣🏾‍♀️🚣🏾‍♂️🚣🏿‍♀️🚣🏿‍♂️🚴‍♀️🚴‍♂️🚴🏻‍♀️🚴🏻‍♂️🚴🏼‍♀️🚴🏼‍♂️🚴🏽‍♀️🚴🏽‍♂️🚴🏾‍♀️🚴🏾‍♂️🚴🏿‍♀️🚴🏿‍♂️🚵‍♀️🚵‍♂️🚵🏻‍♀️🚵🏻‍♂️🚵🏼‍♀️🚵🏼‍♂️🚵🏽‍♀️🚵🏽‍♂️🚵🏾‍♀️🚵🏾‍♂️🚵🏿‍♀️🚵🏿‍♂️🚶‍♀️🚶‍♂️🚶🏻‍♀️🚶🏻‍♂️🚶🏼‍♀️🚶🏼‍♂️🚶🏽‍♀️🚶🏽‍♂️🚶🏾‍♀️🚶🏾‍♂️🚶🏿‍♀️🚶🏿‍♂️🤸‍♀️🤸‍♂️🤸🏻‍♀️🤸🏻‍♂️🤸🏼‍♀️🤸🏼‍♂️🤸🏽‍♀️🤸🏽‍♂️🤸🏾‍♀️🤸🏾‍♂️🤸🏿‍♀️🤸🏿‍♂️🤹‍♀️🤹‍♂️🤹🏻‍♀️🤹🏻‍♂️🤹🏼‍♀️🤹🏼‍♂️🤹🏽‍♀️🤹🏽‍♂️🤹🏾‍♀️🤹🏾‍♂️🤹🏿‍♀️🤹🏿‍♂️🤼‍♀️🤼‍♂️🤽‍♀️🤽‍♂️🤽🏻‍♀️🤽🏻‍♂️🤽🏼‍♀️🤽🏼‍♂️🤽🏽‍♀️🤽🏽‍♂️🤽🏾‍♀️🤽🏾‍♂️🤽🏿‍♀️🤽🏿‍♂️🤾‍♀️🤾‍♂️🤾🏻‍♀️🤾🏻‍♂️🤾🏼‍♀️🤾🏼‍♂️🤾🏽‍♀️🤾🏽‍♂️🤾🏾‍♀️🤾🏾‍♂️🤾🏿‍♀️🤾🏿‍♂️🧖‍♀️🧖‍♂️🧖🏻‍♀️🧖🏻‍♂️🧖🏼‍♀️🧖🏼‍♂️🧖🏽‍♀️🧖🏽‍♂️🧖🏾‍♀️🧖🏾‍♂️🧖🏿‍♀️🧖🏿‍♂️🧗‍♀️🧗‍♂️🧗🏻‍♀️🧗🏻‍♂️🧗🏼‍♀️🧗🏼‍♂️🧗🏽‍♀️🧗🏽‍♂️🧗🏾‍♀️🧗🏾‍♂️🧗🏿‍♀️🧗🏿‍♂️🧘‍♀️🧘‍♂️🧘🏻‍♀️🧘🏻‍♂️🧘🏼‍♀️🧘🏼‍♂️🧘🏽‍♀️🧘🏽‍♂️🧘🏾‍♀️🧘🏾‍♂️🧘🏿‍♀️🧘🏿‍♂️💁‍♀️💁‍♂️💁🏻‍♀️💁🏻‍♂️💁🏼‍♀️💁🏼‍♂️💁🏽‍♀️💁🏽‍♂️💁🏾‍♀️💁🏾‍♂️💁🏿‍♀️💁🏿‍♂️🙅‍♀️🙅‍♂️🙅🏻‍♀️🙅🏻‍♂️🙅🏼‍♀️🙅🏼‍♂️🙅🏽‍♀️🙅🏽‍♂️🙅🏾‍♀️🙅🏾‍♂️🙅🏿‍♀️🙅🏿‍♂️🙆‍♀️🙆‍♂️🙆🏻‍♀️🙆🏻‍♂️🙆🏼‍♀️🙆🏼‍♂️🙆🏽‍♀️🙆🏽‍♂️🙆🏾‍♀️🙆🏾‍♂️🙆🏿‍♀️🙆🏿‍♂️🙇‍♀️🙇‍♂️🙇🏻‍♀️🙇🏻‍♂️🙇🏼‍♀️🙇🏼‍♂️🙇🏽‍♀️🙇🏽‍♂️🙇🏾‍♀️🙇🏾‍♂️🙇🏿‍♀️🙇🏿‍♂️🙋‍♀️🙋‍♂️🙋🏻‍♀️🙋🏻‍♂️🙋🏼‍♀️🙋🏼‍♂️🙋🏽‍♀️🙋🏽‍♂️🙋🏾‍♀️🙋🏾‍♂️🙋🏿‍♀️🙋🏿‍♂️🙍‍♀️🙍‍♂️🙍🏻‍♀️🙍🏻‍♂️🙍🏼‍♀️🙍🏼‍♂️🙍🏽‍♀️🙍🏽‍♂️🙍🏾‍♀️🙍🏾‍♂️🙍🏿‍♀️🙍🏿‍♂️🙎‍♀️🙎‍♂️🙎🏻‍♀️🙎🏻‍♂️🙎🏼‍♀️🙎🏼‍♂️🙎🏽‍♀️🙎🏽‍♂️🙎🏾‍♀️🙎🏾‍♂️🙎🏿‍♀️🙎🏿‍♂️🤦‍♀️🤦‍♂️🤦🏻‍♀️🤦🏻‍♂️🤦🏼‍♀️🤦🏼‍♂️🤦🏽‍♀️🤦🏽‍♂️🤦🏾‍♀️🤦🏾‍♂️🤦🏿‍♀️🤦🏿‍♂️🤷‍♀️🤷‍♂️🤷🏻‍♀️🤷🏻‍♂️🤷🏼‍♀️🤷🏼‍♂️🤷🏽‍♀️🤷🏽‍♂️🤷🏾‍♀️🤷🏾‍♂️🤷🏿‍♀️🤷🏿‍♂️
 #emoji_male_female_zwj_sequences:
-"Noto Color Emoji" : 476
+"Noto Color Emoji (Fontations)" : 476
 
 PASS
 
diff --git a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/cff2-synthetic-bold-italic-expected.png b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/cff2-synthetic-bold-italic-expected.png
new file mode 100644
index 0000000..16dc891
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/cff2-synthetic-bold-italic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/colrv1-expected.png b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/colrv1-expected.png
index 45c1cbd8..4929f99 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/colrv1-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/colrv1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/colrv1-variable-expected.png b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/colrv1-variable-expected.png
index 365ba61..55ba0f5 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/colrv1-variable-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/colrv1-variable-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/font-format-support-color-cff2-expected.png b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/font-format-support-color-cff2-expected.png
index e6568c93..de2a92aa 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/font-format-support-color-cff2-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/font-format-support-color-cff2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/variable-fonts/cff2-variations-expected.png b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/variable-fonts/cff2-variations-expected.png
index 4c1cd1a..6cf1e9d 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/text-antialias/variable-fonts/cff2-variations-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/text-antialias/variable-fonts/cff2-variations-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/text-antialias/colrv1-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/text-antialias/colrv1-expected.png
index 4788bb4..69420ab 100644
--- a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/text-antialias/colrv1-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/text-antialias/colrv1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/text-antialias/colrv1-variable-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/text-antialias/colrv1-variable-expected.png
index f6559a6..1248877 100644
--- a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/text-antialias/colrv1-variable-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/text-antialias/colrv1-variable-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/text-antialias/font-format-support-color-cff2-expected.png b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/text-antialias/font-format-support-color-cff2-expected.png
index 7ae4286..38c8ed6 100644
--- a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/text-antialias/font-format-support-color-cff2-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/text-antialias/font-format-support-color-cff2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/text-antialias/colrv1-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/text-antialias/colrv1-expected.png
index 4788bb4..69420ab 100644
--- a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/text-antialias/colrv1-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/text-antialias/colrv1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/text-antialias/colrv1-variable-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/text-antialias/colrv1-variable-expected.png
index f6559a6..1248877 100644
--- a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/text-antialias/colrv1-variable-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/text-antialias/colrv1-variable-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/text-antialias/font-format-support-color-cff2-expected.png b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/text-antialias/font-format-support-color-cff2-expected.png
index 7ae4286..38c8ed6 100644
--- a/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/text-antialias/font-format-support-color-cff2-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/virtual/text-antialias/font-format-support-color-cff2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac12/virtual/text-antialias/font-format-support-color-cff2-expected.png b/third_party/blink/web_tests/platform/mac-mac12/virtual/text-antialias/font-format-support-color-cff2-expected.png
index 8e6114a..f2787b58 100644
--- a/third_party/blink/web_tests/platform/mac-mac12/virtual/text-antialias/font-format-support-color-cff2-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac12/virtual/text-antialias/font-format-support-color-cff2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/text-antialias/colrv1-expected.png b/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/text-antialias/colrv1-expected.png
index 4788bb4..69420ab 100644
--- a/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/text-antialias/colrv1-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/text-antialias/colrv1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/text-antialias/colrv1-variable-expected.png b/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/text-antialias/colrv1-variable-expected.png
index f6559a6..1248877 100644
--- a/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/text-antialias/colrv1-variable-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/text-antialias/colrv1-variable-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/text-antialias/font-format-support-color-cff2-expected.png b/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/text-antialias/font-format-support-color-cff2-expected.png
index b260b9f4..d64ec4c3 100644
--- a/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/text-antialias/font-format-support-color-cff2-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac13-arm64/virtual/text-antialias/font-format-support-color-cff2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/text-antialias/colrv1-expected.png b/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/text-antialias/colrv1-expected.png
index 4788bb4..69420ab 100644
--- a/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/text-antialias/colrv1-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/text-antialias/colrv1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/text-antialias/colrv1-variable-expected.png b/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/text-antialias/colrv1-variable-expected.png
index f6559a6..1248877 100644
--- a/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/text-antialias/colrv1-variable-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/text-antialias/colrv1-variable-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/text-antialias/font-format-support-color-cff2-expected.png b/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/text-antialias/font-format-support-color-cff2-expected.png
index 6828760..d64ec4c3 100644
--- a/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/text-antialias/font-format-support-color-cff2-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/text-antialias/font-format-support-color-cff2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/inspector-protocol/layout-fonts/cross-platform-cbdt-sbix-cff2-expected.txt b/third_party/blink/web_tests/platform/mac/inspector-protocol/layout-fonts/cross-platform-cbdt-sbix-cff2-expected.txt
new file mode 100644
index 0000000..0c48b91
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/inspector-protocol/layout-fonts/cross-platform-cbdt-sbix-cff2-expected.txt
@@ -0,0 +1,13 @@
+abcdefghijklmnopqrstuvwxyz
+#cff2_support__should_be_using_adobe_variable_font_protoptype_only:
+"Adobe Variable Font Prototype (Fontations)" : 26
+
+
+#sbix_support__should_be_using_chromacheck_only:
+"PixelAmbacht ChromaCheck" : 7
+
+
+#cbdt_support__should_be_using_notocoloremoji_only:
+"ChromaCheck CBDT (Fontations)" : 7
+
+
diff --git a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/cff2-synthetic-bold-italic-expected.png b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/cff2-synthetic-bold-italic-expected.png
new file mode 100644
index 0000000..1f866a41
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/cff2-synthetic-bold-italic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/colrv1-expected.png b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/colrv1-expected.png
index f1c06c01..4bb7d39 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/colrv1-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/colrv1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/colrv1-variable-expected.png b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/colrv1-variable-expected.png
index 169c756..b39bfc6 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/colrv1-variable-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/colrv1-variable-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/font-format-support-color-cff2-expected.png b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/font-format-support-color-cff2-expected.png
index 8183f8f..caf54db 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/font-format-support-color-cff2-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/font-format-support-color-cff2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/variable-fonts/cff2-variations-expected.png b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/variable-fonts/cff2-variations-expected.png
index be4b47a5..17e8003 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/text-antialias/variable-fonts/cff2-variations-expected.png
+++ b/third_party/blink/web_tests/platform/mac/virtual/text-antialias/variable-fonts/cff2-variations-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/text-antialias/cff2-synthetic-bold-italic-expected.png b/third_party/blink/web_tests/platform/win/virtual/text-antialias/cff2-synthetic-bold-italic-expected.png
new file mode 100644
index 0000000..14e559f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/virtual/text-antialias/cff2-synthetic-bold-italic-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/text-antialias/colrv1-expected.png b/third_party/blink/web_tests/platform/win/virtual/text-antialias/colrv1-expected.png
index c100b562..194a036b 100644
--- a/third_party/blink/web_tests/platform/win/virtual/text-antialias/colrv1-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/text-antialias/colrv1-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/text-antialias/colrv1-variable-expected.png b/third_party/blink/web_tests/platform/win/virtual/text-antialias/colrv1-variable-expected.png
index 685ab4d1..ab2a594c 100644
--- a/third_party/blink/web_tests/platform/win/virtual/text-antialias/colrv1-variable-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/text-antialias/colrv1-variable-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/text-antialias/font-format-support-color-cff2-expected.png b/third_party/blink/web_tests/platform/win/virtual/text-antialias/font-format-support-color-cff2-expected.png
index b76cfb8e..b65e44a 100644
--- a/third_party/blink/web_tests/platform/win/virtual/text-antialias/font-format-support-color-cff2-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/text-antialias/font-format-support-color-cff2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/text-antialias/variable-fonts/cff2-variations-expected.png b/third_party/blink/web_tests/platform/win/virtual/text-antialias/variable-fonts/cff2-variations-expected.png
index 0ce72d5f..d2eec327 100644
--- a/third_party/blink/web_tests/platform/win/virtual/text-antialias/variable-fonts/cff2-variations-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/text-antialias/variable-fonts/cff2-variations-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win10/virtual/text-antialias/font-format-support-color-cff2-expected.png b/third_party/blink/web_tests/platform/win10/virtual/text-antialias/font-format-support-color-cff2-expected.png
index 9a884aed..b11f8c15 100644
--- a/third_party/blink/web_tests/platform/win10/virtual/text-antialias/font-format-support-color-cff2-expected.png
+++ b/third_party/blink/web_tests/platform/win10/virtual/text-antialias/font-format-support-color-cff2-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win11-arm64/virtual/text-antialias/cff2-synthetic-bold-italic-expected.png b/third_party/blink/web_tests/platform/win11-arm64/virtual/text-antialias/cff2-synthetic-bold-italic-expected.png
new file mode 100644
index 0000000..5b37deb
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win11-arm64/virtual/text-antialias/cff2-synthetic-bold-italic-expected.png
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+All subtests passed and are omitted for brevity.
+See https://chromium.googlesource.com/chromium/src/+/HEAD/docs/testing/writing_web_tests.md#Text-Test-Baselines for details.
+Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/win11-arm64/virtual/text-antialias/variable-fonts/cff2-variations-expected.png b/third_party/blink/web_tests/platform/win11-arm64/virtual/text-antialias/variable-fonts/cff2-variations-expected.png
new file mode 100644
index 0000000..0ce72d5f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win11-arm64/virtual/text-antialias/variable-fonts/cff2-variations-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/dom-parts-minimal/external/wpt/dom/parts/basic-dom-part-declarative-brace-syntax.tentative-expected.txt b/third_party/blink/web_tests/virtual/dom-parts-minimal/external/wpt/dom/parts/basic-dom-part-declarative-brace-syntax.tentative-expected.txt
index bd88eb7e..fe9d3611 100644
--- a/third_party/blink/web_tests/virtual/dom-parts-minimal/external/wpt/dom/parts/basic-dom-part-declarative-brace-syntax.tentative-expected.txt
+++ b/third_party/blink/web_tests/virtual/dom-parts-minimal/external/wpt/dom/parts/basic-dom-part-declarative-brace-syntax.tentative-expected.txt
@@ -1,8 +1,8 @@
 This is a testharness.js-based test.
 [FAIL] Basic declarative DOM Parts (Main Document)
-  assert_equals: expected "" but got "S"
+  assert_equals: Second level childpart should have NodePart and AttributePart: lengths differ expected 2 but got 1
 [FAIL] Basic declarative DOM Parts (Template)
-  assert_equals: expected "" but got "S"
+  assert_equals: Second level childpart should have NodePart and AttributePart: lengths differ expected 2 but got 1
 [FAIL] Basic declarative DOM Parts (PartClone)
   assert_equals: undefined: lengths differ expected 0 but got 1
 [FAIL] Post-parsing structure of child parts, and stickiness
diff --git a/third_party/blink/web_tests/virtual/fledge-bidding-and-auction/README.md b/third_party/blink/web_tests/virtual/fledge-bidding-and-auction/README.md
new file mode 100644
index 0000000..6a500fb
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/fledge-bidding-and-auction/README.md
@@ -0,0 +1 @@
+This directory is to test some Protected Audience (https://github.com/WICG/turtledove/blob/main/FLEDGE.md) features with `BiddingAndAuctionServices` turned on.
diff --git a/third_party/blink/web_tests/virtual/fledge-bidding-and-auction/external/wpt/fledge/tentative/get-interest-group-auction-data.https.window_1-4-expected.txt b/third_party/blink/web_tests/virtual/fledge-bidding-and-auction/external/wpt/fledge/tentative/get-interest-group-auction-data.https.window_1-4-expected.txt
new file mode 100644
index 0000000..d2490db
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/fledge-bidding-and-auction/external/wpt/fledge/tentative/get-interest-group-auction-data.https.window_1-4-expected.txt
@@ -0,0 +1,3 @@
+This is a testharness.js-based test.
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/payment-request-mandatory-total/README.md b/third_party/blink/web_tests/virtual/payment-request-mandatory-total/README.md
deleted file mode 100644
index 042fb5db..0000000
--- a/third_party/blink/web_tests/virtual/payment-request-mandatory-total/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Since the flag is default to be disabled in production but enabled in waterfall builders, we create this virtual test suite to test the cases where the flag disabled in waterfall builders.
diff --git a/third_party/blink/web_tests/virtual/payment-request-mandatory-total/http/tests/payments/README.txt b/third_party/blink/web_tests/virtual/payment-request-mandatory-total/http/tests/payments/README.txt
deleted file mode 100644
index 446ce28..0000000
--- a/third_party/blink/web_tests/virtual/payment-request-mandatory-total/http/tests/payments/README.txt
+++ /dev/null
@@ -1 +0,0 @@
-Since PaymentRequestOptioanalTotal is default to be enabled in waterfall builder, we create this test suite to ensure the cases where PaymentRequestOptioanalTotal is disabled is covered.
diff --git a/third_party/blink/web_tests/virtual/text-antialias/cff2-synthetic-bold-italic.html b/third_party/blink/web_tests/virtual/text-antialias/cff2-synthetic-bold-italic.html
new file mode 100644
index 0000000..251a0d2
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/text-antialias/cff2-synthetic-bold-italic.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+  <meta charset="UTF-8" />
+  <style type="text/css">
+    .explain {
+      font-family: sans-serif;
+    }
+    @font-face {
+      font-family: "adobevfproto";
+      font-weight: 389.34425;
+      src: url("../../third_party/AdobeVF/AdobeVFPrototype.otf");
+    }
+  </style>
+  <p class="explain">
+    Test ensures that synthetic bold and italic work when switching CFF2 fonts
+    rendering to Fontations.
+  </p>
+  <p>Regular</p>
+  <p style="font-weight: bold">Synthetic Bold</p>
+  <p style="font-style: italic">Synthetic Italic</p>
+  <p style="font-weight: bold; font-style: italic">Synthetic bold & italic</p>
+</html>
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
index 35054c8..6e9e3ea 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -1449,7 +1449,6 @@
     getter rootContainer
     method clone
     method constructor
-    method getPartNode
     method getParts
     method replaceChildren
 interface Clipboard : EventTarget
@@ -2404,7 +2403,6 @@
     getter rootContainer
     method clone
     method constructor
-    method getPartNode
     method getParts
 interface DocumentPictureInPicture : EventTarget
     attribute @@toStringTag
diff --git a/third_party/blink/web_tests/wpt_internal/digital-credentials/identity-get.tentative.https.html b/third_party/blink/web_tests/wpt_internal/digital-credentials/identity-get.tentative.https.html
new file mode 100644
index 0000000..fd0b18a
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/digital-credentials/identity-get.tentative.https.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<title>Digital Identity Credential tests.</title>
+<link rel="help" href="https://wicg.github.io/digital-identities/">
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<body>
+  <iframe id="same-origin"></iframe>
+  <iframe id="cross-origin"></iframe>
+<script type="module">
+import { buildValidNavigatorIdentityRequest, buildValidNavigatorIdentityRequestWithRequestObject, loadIframe, requestIdentityWithActivation, sendMessage } from '/wpt_internal/digital-credentials/support/helper.js';
+
+const iframeSameOrigin = document.querySelector("iframe#same-origin");
+const iframeCrossOrigin = document.querySelector("iframe#cross-origin");
+
+promise_setup(async () => {
+  const hostInfo = get_host_info();
+  await Promise.all([
+    loadIframe(
+      iframeCrossOrigin,
+      `${hostInfo.HTTPS_REMOTE_ORIGIN}/wpt_internal/digital-credentials/support/iframe.html`
+    ),
+    loadIframe(iframeSameOrigin, "/wpt_internal/digital-credentials/support/iframe.html"),
+  ]);
+});
+
+// Tests for success are here because the tests rely on the
+// --use-fake-ui-for-digital-identity command line flag. Moving the tests to
+// /external requires a WebDriver testing API.
+
+promise_test(async t => {
+  let request = buildValidNavigatorIdentityRequest();
+  let credential = await requestIdentityWithActivation(test_driver, request);
+  assert_equals("urn:openid.net:oid4vp", credential.protocol);
+  assert_equals("fake_test_token", credential.data);
+}, "navigator.identity.get() API works in toplevel frame.");
+
+promise_test(async t => {
+  const request = buildValidNavigatorIdentityRequestWithRequestObject();
+  let credential = await requestIdentityWithActivation(test_driver, request);
+  assert_equals("urn:openid.net:oid4vp", credential.protocol);
+  assert_equals("fake_test_token", credential.data);
+}, "navigator.identity.get() API succeeds when IdentityRequestProvider#request is an object instead of stringified JSON object");
+
+promise_test(async t=> {
+  let abortController = new AbortController();
+  let request = buildValidNavigatorIdentityRequest();
+  request.signal = abortController.signal;
+  let requestPromise = requestIdentityWithActivation(test_driver, request);
+  abortController.abort();
+  await promise_rejects_dom(t, "AbortError", requestPromise);
+}, "navigator.identity.get() promise is rejected when the page aborts the request.");
+
+promise_test(async t=> {
+  const result = await sendMessage(iframeSameOrigin);
+  assert_equals(result.constructor, "DigitalCredential");
+  assert_equals(result.data, "fake_test_token");
+}, "navigator.identity.get() succeeds in same-origin iframe");
+
+// Internal test because the spec does not have a 1 provider limit.
+promise_test(async t => {
+  let request = buildValidNavigatorIdentityRequest();
+  let providerCopy = structuredClone(request.digital.providers[0]);
+  request.digital.providers.push(providerCopy);
+  await promise_rejects_js(t, TypeError, requestIdentityWithActivation(test_driver, request));
+}, "navigator.identity.get() API fails if there is more than one provider.");
+
+// Internal test because this test is more of an integration test. The spec does
+// not define the behavior if the passed-in request object is super big.
+promise_test(async t => {
+  const request = buildValidNavigatorIdentityRequestWithRequestObject();
+  const largeList = [];
+  for (let i = 0; i < 1000000; ++i) {
+    largeList.push("Value " + i);
+  }
+  request.digital.providers[0].request.random = largeList;
+  await promise_rejects_js(t, TypeError, requestIdentityWithActivation(test_driver, request));
+}, "navigator.identity.get() API fails when IdentityRequestProvider#request object is too big");
+
+</script>
diff --git a/third_party/blink/web_tests/wpt_internal/digital-credentials/support/helper.js b/third_party/blink/web_tests/wpt_internal/digital-credentials/support/helper.js
new file mode 100644
index 0000000..6667da6c
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/digital-credentials/support/helper.js
@@ -0,0 +1,84 @@
+// Builds valid digital identity request for navigator.identity.get() API.
+export function buildValidNavigatorIdentityRequest() {
+  return {
+      digital: {
+        providers: [{
+          protocol: "urn:openid.net:oid4vp",
+          request: JSON.stringify({
+            // Based on https://github.com/openid/OpenID4VP/issues/125
+            client_id: "client.example.org",
+            client_id_scheme: "web-origin",
+            nonce: "n-0S6_WzA2Mj",
+            presentation_definition: {
+              // Presentation Exchange request, omitted for brevity
+            }
+          }),
+        }],
+      },
+  };
+}
+
+// Builds a valid navigator.identity.get() request where
+// IdentityRequestProvider#request is an object.
+export function buildValidNavigatorIdentityRequestWithRequestObject() {
+  return {
+      digital: {
+        providers: [{
+          protocol: "urn:openid.net:oid4vp",
+          request: {
+            // Based on https://github.com/openid/OpenID4VP/issues/125
+            client_id: "client.example.org",
+            client_id_scheme: "web-origin",
+            nonce: "n-0S6_WzA2Mj",
+            presentation_definition: {
+              // Presentation Exchange request, omitted for brevity
+            }
+          },
+        }],
+      },
+  };
+}
+
+// Requests digital identity with user activation.
+export function requestIdentityWithActivation(test_driver, request) {
+  return test_driver.bless("request identity with activation", async function() {
+    return await navigator.identity.get(request);
+  });
+}
+
+/**
+ * @type {SendMessage}
+ **/
+export function sendMessage(iframe) {
+  return new Promise((resolve, reject) => {
+    window.addEventListener("message", function messageListener(event) {
+      if (event.source === iframe.contentWindow) {
+        window.removeEventListener("message", messageListener);
+        resolve(event.data);
+      }
+    });
+    if (!iframe.contentWindow) {
+      reject(
+        new Error("iframe.contentWindow is undefined, cannot send message.")
+      );
+      return;
+    }
+    iframe.contentWindow.postMessage({}, "*");
+  });
+}
+
+/**
+ * @param {HTMLIFrameElement} iframe
+ * @param {string|URL} url
+ * @returns {Promise<void>}
+ */
+export function loadIframe(iframe, url) {
+  return new Promise((resolve, reject) => {
+    iframe.addEventListener("load", resolve, { once: true });
+    iframe.addEventListener("error", reject, { once: true });
+    if (!iframe.isConnected) {
+      document.body.appendChild(iframe);
+    }
+    iframe.src = url.toString();
+  });
+}
diff --git a/third_party/blink/web_tests/wpt_internal/digital-credentials/support/iframe.html b/third_party/blink/web_tests/wpt_internal/digital-credentials/support/iframe.html
new file mode 100644
index 0000000..4e49110
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/digital-credentials/support/iframe.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script type="module">
+import { buildValidNavigatorIdentityRequest, requestIdentityWithActivation } from './helper.js';
+
+// iframe.html will make a digital credential request when it gets a message,
+// and trigger a postMessage on completion.
+async function messageListener(event) {
+  let result;
+  try {
+    let request = buildValidNavigatorIdentityRequest();
+    let requestResult = await requestIdentityWithActivation(test_driver, request);
+    result = {
+      constructor: requestResult.constructor.name,
+      data: requestResult.data
+    };
+  } catch (error) {
+    result = {
+      constructor: error.constructor.name,
+      name: error.name,
+      message: error.message,
+    };
+  } finally {
+    event.source?.postMessage(result, event.origin);
+  }
+}
+
+window.addEventListener("message", messageListener);
+</script>
diff --git a/third_party/catapult b/third_party/catapult
index 68fe632..8c184bf 160000
--- a/third_party/catapult
+++ b/third_party/catapult
@@ -1 +1 @@
-Subproject commit 68fe632a004e438f1f20f13e435fc27412562c99
+Subproject commit 8c184bf50d33dddcb0fa650999e6e4a4aa8f01b6
diff --git a/third_party/chromite b/third_party/chromite
index aae6a185..7559f18 160000
--- a/third_party/chromite
+++ b/third_party/chromite
@@ -1 +1 @@
-Subproject commit aae6a185626c2b51c2c07f5d17cf6aa554e4ad9f
+Subproject commit 7559f18d7844ac156ac74d49a4b5823218079a86
diff --git a/third_party/chromium-variations b/third_party/chromium-variations
index 2d85606..dd19926 160000
--- a/third_party/chromium-variations
+++ b/third_party/chromium-variations
@@ -1 +1 @@
-Subproject commit 2d85606f2917fe6c93f1012fa8fc719ad2610b07
+Subproject commit dd19926430790b671b4455b17f9f5a9fa9c30fee
diff --git a/third_party/dawn b/third_party/dawn
index d16f1c5..6b46c4a 160000
--- a/third_party/dawn
+++ b/third_party/dawn
@@ -1 +1 @@
-Subproject commit d16f1c5767ebfe40278cd4dcb31b0f181bff2e03
+Subproject commit 6b46c4ac1055d9980b05983bcd988fa90d6ed1e9
diff --git a/third_party/depot_tools b/third_party/depot_tools
index 1d1f17a..66df2a3 160000
--- a/third_party/depot_tools
+++ b/third_party/depot_tools
@@ -1 +1 @@
-Subproject commit 1d1f17af898bc5158fb1128952894ac061b06f56
+Subproject commit 66df2a3ec70d0628d47df1fdba69838a870a1303
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal
index c9b4206..342adbf 160000
--- a/third_party/devtools-frontend-internal
+++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@
-Subproject commit c9b420694f06ed9657c694d3a39296b7bafcb592
+Subproject commit 342adbf2db4473a5fcbc49fb9d7f7c4c017c74c8
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src
index 33f1e4c..5839d81 160000
--- a/third_party/devtools-frontend/src
+++ b/third_party/devtools-frontend/src
@@ -1 +1 @@
-Subproject commit 33f1e4ca2f50a8ade4dd8c58d34efc05d5f204b6
+Subproject commit 5839d81905907f4ca1ce08192a23257b2788f121
diff --git a/third_party/perfetto b/third_party/perfetto
index 6f8d4eb..1990573 160000
--- a/third_party/perfetto
+++ b/third_party/perfetto
@@ -1 +1 @@
-Subproject commit 6f8d4eba872ebf682e638c7def3052e8cb6e4d75
+Subproject commit 1990573f6d71b581cb1fb48df3445883e93020a5
diff --git a/third_party/polymer/v3_0/BUILD.gn b/third_party/polymer/v3_0/BUILD.gn
index eb37582..6533c5a0 100644
--- a/third_party/polymer/v3_0/BUILD.gn
+++ b/third_party/polymer/v3_0/BUILD.gn
@@ -196,6 +196,7 @@
     "components-chromium/iron-a11y-keys-behavior/iron-a11y-keys-behavior.d.ts",
     "components-chromium/iron-a11y-keys/iron-a11y-keys.d.ts",
     "components-chromium/iron-behaviors/iron-control-state.d.ts",
+    "components-chromium/iron-fit-behavior/iron-fit-behavior.d.ts",
     "components-chromium/iron-flex-layout/iron-flex-layout-classes.d.ts",
     "components-chromium/iron-icon/iron-icon.d.ts",
     "components-chromium/iron-iconset-svg/iron-iconset-svg.d.ts",
diff --git a/third_party/r8/3pp/3pp.pb b/third_party/r8/3pp/3pp.pb
index 111ebed..400e5cb3 100644
--- a/third_party/r8/3pp/3pp.pb
+++ b/third_party/r8/3pp/3pp.pb
@@ -3,6 +3,7 @@
     script { name: "fetch.py" }
     unpack_archive: true
     patch_dir: "patches"
+    patch_version: "cr1"
   }
 
   build {
diff --git a/third_party/skia b/third_party/skia
index 2121bbc..330eeb1 160000
--- a/third_party/skia
+++ b/third_party/skia
@@ -1 +1 @@
-Subproject commit 2121bbc603c722bb2bc530a3a447900c635668ec
+Subproject commit 330eeb106170f34c75b546e5a0b9859251dfe642
diff --git a/third_party/swiftshader b/third_party/swiftshader
index 085997d..cea33ab 160000
--- a/third_party/swiftshader
+++ b/third_party/swiftshader
@@ -1 +1 @@
-Subproject commit 085997ddb08b9df39e55dd727f8145d1a7aa9ce4
+Subproject commit cea33ab2d5ad50cd7f1881fb9c36ffcaecdd69fc
diff --git a/third_party/turbine/3pp/3pp.pb b/third_party/turbine/3pp/3pp.pb
index 69104b20..4e2f4c5 100644
--- a/third_party/turbine/3pp/3pp.pb
+++ b/third_party/turbine/3pp/3pp.pb
@@ -2,6 +2,7 @@
   source {
     script { name: "fetch.py" }
     unpack_archive: true
+    patch_version: "cr1"
   }
 
   build {
diff --git a/third_party/turbine/3pp/install.sh b/third_party/turbine/3pp/install.sh
index 239aa863..cdd70300 100755
--- a/third_party/turbine/3pp/install.sh
+++ b/third_party/turbine/3pp/install.sh
@@ -11,10 +11,10 @@
 DEPS_PREFIX="$2"
 
 # Verify mvn works
-JAVA_HOME=$DEPS_PREFIX/current mvn -v
+JAVA_HOME=$DEPS_PREFIX mvn -v
 
 # Build
-JAVA_HOME=$DEPS_PREFIX/current mvn package -DskipTests=true -q -f pom.xml
+JAVA_HOME=$DEPS_PREFIX mvn package -DskipTests=true -q -f pom.xml
 cp target/turbine-HEAD-SNAPSHOT-all-deps.jar turbine.jar
 
 mkdir -p $PREFIX/
diff --git a/third_party/vulkan-deps b/third_party/vulkan-deps
index 897d900..7f05a36 160000
--- a/third_party/vulkan-deps
+++ b/third_party/vulkan-deps
@@ -1 +1 @@
-Subproject commit 897d900fc1b1a504302f1620e416cb7421fcbf7c
+Subproject commit 7f05a36fb6d9c2c6283eaad78b0b9047e6eb19da
diff --git a/third_party/vulkan-validation-layers/src b/third_party/vulkan-validation-layers/src
index 9bb8d05..8f3d3736 160000
--- a/third_party/vulkan-validation-layers/src
+++ b/third_party/vulkan-validation-layers/src
@@ -1 +1 @@
-Subproject commit 9bb8d0513ee37db2a57abe8a8edd16ac95ae5bd9
+Subproject commit 8f3d3736ce1c4167958882c2b69dd4ba753457ee
diff --git a/third_party/webrtc b/third_party/webrtc
index 72302cc..feea82f 160000
--- a/third_party/webrtc
+++ b/third_party/webrtc
@@ -1 +1 @@
-Subproject commit 72302cc5e4ea5aa820e5fe3bc10440dbde2ba362
+Subproject commit feea82fad5d472cf787c54455f147d86b219196f
diff --git a/third_party/wpt_tools/README.chromium b/third_party/wpt_tools/README.chromium
index 2cf08b62..9dd53df 100644
--- a/third_party/wpt_tools/README.chromium
+++ b/third_party/wpt_tools/README.chromium
@@ -1,7 +1,7 @@
 Name: web-platform-tests - Test Suites for Web Platform specifications
 Short Name: wpt
 URL: https://github.com/web-platform-tests/wpt/
-Version: 65ba9a606e045367bab11bbfbe8033dab14a9ecd
+Version: 7cf0eb5642e6a0d921cc583929933e7357bea874
 License: LICENSES FOR W3C TEST SUITES (https://www.w3.org/Consortium/Legal/2008/03-bsd-license.html)
 Security Critical: no
 Shipped: no
diff --git a/third_party/wpt_tools/wpt/tools/conftest.py b/third_party/wpt_tools/wpt/tools/conftest.py
index 8d1f585..5652181 100644
--- a/third_party/wpt_tools/wpt/tools/conftest.py
+++ b/third_party/wpt_tools/wpt/tools/conftest.py
@@ -17,7 +17,7 @@
                                 "default" if impl != "PyPy" else "pypy"))
 
 
-def pytest_ignore_collect(collection_path, path, config):
+def pytest_ignore_collect(collection_path, config):
     # ignore directories which have their own tox.ini
     assert collection_path != config.rootpath
     if (collection_path / "tox.ini").is_file():
diff --git a/third_party/wpt_tools/wpt/tools/localpaths.py b/third_party/wpt_tools/wpt/tools/localpaths.py
index a027af8..ebd3c54 100644
--- a/third_party/wpt_tools/wpt/tools/localpaths.py
+++ b/third_party/wpt_tools/wpt/tools/localpaths.py
@@ -11,6 +11,7 @@
 sys.path.insert(0, os.path.join(here, "third_party", "attrs", "src"))
 sys.path.insert(0, os.path.join(here, "third_party", "html5lib"))
 sys.path.insert(0, os.path.join(here, "third_party", "zipp"))
+sys.path.insert(0, os.path.join(here, "third_party", "exceptiongroup", "src"))
 sys.path.insert(0, os.path.join(here, "third_party", "more-itertools"))
 sys.path.insert(0, os.path.join(here, "third_party", "packaging"))
 sys.path.insert(0, os.path.join(here, "third_party", "pathlib2"))
diff --git a/third_party/wpt_tools/wpt/tools/third_party_modified/mozlog/mozlog/capture.py b/third_party/wpt_tools/wpt/tools/third_party_modified/mozlog/mozlog/capture.py
index 75717d62c..78da63b 100644
--- a/third_party/wpt_tools/wpt/tools/third_party_modified/mozlog/mozlog/capture.py
+++ b/third_party/wpt_tools/wpt/tools/third_party_modified/mozlog/mozlog/capture.py
@@ -88,7 +88,7 @@
                 while not self.logging_queue.empty():
                     try:
                         self.logger.warning(
-                            "Dropping log message: %r", self.logging_queue.get()
+                            "Dropping log message: %r" % self.logging_queue.get()
                         )
                     except Exception:
                         pass
diff --git a/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/error.py b/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/error.py
index bb3bd4d..c77b2e4 100644
--- a/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/error.py
+++ b/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/error.py
@@ -12,14 +12,14 @@
     error_code: ClassVar[str]
 
     def __init__(self, message: str, stacktrace: Optional[str] = None):
-        super()
+        super().__init__()
 
         self.message = message
         self.stacktrace = stacktrace
 
     def __repr__(self):
         """Return the object representation in string format."""
-        return f"{self.__class__.__name__}({self.error}, {self.message}, {self.stacktrace})"
+        return f"{self.__class__.__name__}({self.error_code}, {self.message}, {self.stacktrace})"
 
     def __str__(self):
         """Return the string representation of the object."""
diff --git a/third_party/wpt_tools/wpt/tools/webdriver/webdriver/error.py b/third_party/wpt_tools/wpt/tools/webdriver/webdriver/error.py
index 25e4b39a..b19693e2 100644
--- a/third_party/wpt_tools/wpt/tools/webdriver/webdriver/error.py
+++ b/third_party/wpt_tools/wpt/tools/webdriver/webdriver/error.py
@@ -16,7 +16,7 @@
     status_code: ClassVar[str]
 
     def __init__(self, http_status=None, status_code=None, message=None, stacktrace=None):
-        super()
+        super().__init__()
 
         if http_status is not None:
             self.http_status = http_status
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/browsers/base.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/browsers/base.py
index dd4fc314..6b1465cd 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/browsers/base.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/browsers/base.py
@@ -3,6 +3,8 @@
 import os
 import platform
 import socket
+import time
+import traceback
 from abc import ABCMeta, abstractmethod
 from typing import cast, Any, List, Mapping, Optional, Tuple, Type
 
@@ -10,6 +12,7 @@
 from mozdebug import DebuggerInfo
 from mozlog.structuredlog import StructuredLogger
 
+from ..environment import wait_for_service
 from ..testloader import GroupMetadata
 from ..wptcommandline import require_arg  # noqa: F401
 from ..wpttest import Test
@@ -316,6 +319,7 @@
         self.env = os.environ.copy() if env is None else env
         self.webdriver_args = webdriver_args if webdriver_args is not None else []
 
+        self.init_deadline: Optional[float] = None
         self._output_handler: Optional[OutputHandler] = None
         self._cmd = None
         self._proc: Optional[mozprocess.ProcessHandler] = None
@@ -326,6 +330,7 @@
         return [self.webdriver_binary] + self.webdriver_args
 
     def start(self, group_metadata: GroupMetadata, **kwargs: Any) -> None:
+        self.init_deadline = time.time() + self.init_timeout
         try:
             self._run_server(group_metadata, **kwargs)
         except KeyboardInterrupt:
@@ -340,6 +345,7 @@
         return OutputHandler(self.logger, cmd)
 
     def _run_server(self, group_metadata: GroupMetadata, **kwargs: Any) -> None:
+        assert self.init_deadline is not None
         cmd = self.make_command()
         self._output_handler = self.create_output_handler(cmd)
 
@@ -359,7 +365,21 @@
             raise
         self._output_handler.after_process_start(self._proc.pid)
 
-        self._output_handler.start(group_metadata=group_metadata, **kwargs)
+        try:
+            wait_for_service(
+                self.logger,
+                self.host,
+                self.port,
+                timeout=self.init_deadline - time.time(),
+                server_process=self._proc,
+            )
+        except Exception:
+            self.logger.error(
+                "WebDriver was not accessible "
+                f"within the timeout:\n{traceback.format_exc()}")
+            raise
+        finally:
+            self._output_handler.start(group_metadata=group_metadata, **kwargs)
         self.logger.debug("_run complete")
 
     def stop(self, force: bool = False) -> bool:
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/browsers/chrome_ios.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/browsers/chrome_ios.py
index 20fcb90..e559a5d7 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/browsers/chrome_ios.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/browsers/chrome_ios.py
@@ -1,12 +1,9 @@
 # mypy: allow-untyped-defs
 
-import traceback
 from .base import WebDriverBrowser, require_arg
 from .base import get_timeout_multiplier   # noqa: F401
-from ..environment import wait_for_service
 from ..executors import executor_kwargs as base_executor_kwargs
 from ..executors.base import WdspecExecutor  # noqa: F401
-from ..executors.executorchrome import ChromeDriverPrintRefTestExecutor  # noqa: F401
 from ..executors.executorwebdriver import (WebDriverCrashtestExecutor,  # noqa: F401
                                            WebDriverTestharnessExecutor,  # noqa: F401
                                            WebDriverRefTestExecutor)  # noqa: F401
@@ -17,7 +14,6 @@
                  "browser": "ChromeiOSBrowser",
                  "executor": {"testharness": "WebDriverTestharnessExecutor",
                               "reftest": "WebDriverRefTestExecutor",
-                              "print-reftest": "ChromeDriverPrintRefTestExecutor",
                               "crashtest": "WebDriverCrashtestExecutor"},
                  "browser_kwargs": "browser_kwargs",
                  "executor_kwargs": "executor_kwargs",
@@ -62,19 +58,3 @@
     def make_command(self):
         return ([self.webdriver_binary, f"--port={self.port}"] +
                 self.webdriver_args)
-
-    def start(self, group_metadata, **kwargs):
-        super().start(group_metadata, **kwargs)
-        try:
-            wait_for_service(
-                self.logger,
-                self.host,
-                self.port,
-                timeout=self.init_timeout,
-                server_process=self._proc,
-            )
-        except Exception:
-            self.logger.error(
-                "WebDriver was not accessible "
-                f"within the timeout:\n{traceback.format_exc()}")
-            raise
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/browsers/firefox.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/browsers/firefox.py
index d22da85..d977930 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/browsers/firefox.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/browsers/firefox.py
@@ -910,7 +910,6 @@
         self.binary = binary
         self.package_name = package_name
         self.webdriver_binary = webdriver_binary
-        self.init_deadline = None
 
         self.stackfix_dir = stackfix_dir
         self.symbols_path = symbols_path
@@ -959,7 +958,6 @@
 
     def start(self, group_metadata, **kwargs):
         self.leak_report_file = setup_leak_report(self.leak_check, self.profile, self.env)
-        self.init_deadline = time.time() + self.init_timeout
         super().start(group_metadata, **kwargs)
 
     def stop(self, force=False):
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorwebdriver.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorwebdriver.py
index 69013e5..f985d48 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorwebdriver.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorwebdriver.py
@@ -517,7 +517,7 @@
             # 5 seconds of extra_timeout we have as maximum to end the test before
             # the external timeout from testrunner triggers.
             self.webdriver.send_session_command("GET", "window", timeout=2)
-        except (socket.timeout, error.UnknownErrorException, error.InvalidSessionIdException):
+        except (OSError, error.WebDriverException):
             return False
         return True
 
@@ -630,11 +630,7 @@
             #
             # https://github.com/w3c/webdriver/issues/1308
             if not isinstance(result, list) or len(result) != 3:
-                try:
-                    is_alive = self.is_alive()
-                except error.WebDriverException:
-                    is_alive = False
-
+                is_alive = self.is_alive()
                 if not is_alive:
                     raise Exception("Browser crashed during script execution.")
 
@@ -700,6 +696,9 @@
             """return [window.outerWidth - window.innerWidth,
                        window.outerHeight - window.innerHeight];"""
         )
+        # width_offset and height_offset should never be negative
+        width_offset = max(width_offset, 0)
+        height_offset = max(height_offset, 0)
         try:
             self.protocol.webdriver.window.position = (0, 0)
         except error.InvalidArgumentException:
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/protocol.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/protocol.py
index 3d588738..5ebdeed 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/protocol.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/protocol.py
@@ -776,9 +776,12 @@
         proof enough to us that the server is alive and kicking.
         """
         conn = HTTPConnection(self.browser.host, self.browser.port)
-        conn.request("HEAD", "/invalid")
-        res = conn.getresponse()
-        return res.status == 404
+        try:
+            conn.request("HEAD", "/invalid")
+            res = conn.getresponse()
+            return res.status == 404
+        except OSError:
+            return False
 
 
 class VirtualSensorProtocolPart(ProtocolPart):
diff --git a/tools/checkbins/checkbins.py b/tools/checkbins/checkbins.py
index ea15978..33dd361 100755
--- a/tools/checkbins/checkbins.py
+++ b/tools/checkbins/checkbins.py
@@ -30,6 +30,7 @@
 NO_SEH_FLAG = 0x0400
 GUARD_CF_FLAG = 0x4000
 MACHINE_TYPE_AMD64 = 0x8664
+MACHINE_TYPE_ARM64 = 0xaa64
 CETCOMPAT_BIT = 0  # offset in extended dll characteristics
 
 # Please do not add your file here without confirming that it indeed doesn't
@@ -129,7 +130,7 @@
         (hasattr(pe, "DIRECTORY_ENTRY_LOAD_CONFIG") and
          pe.DIRECTORY_ENTRY_LOAD_CONFIG.struct.SEHandlerCount > 0 and
          pe.DIRECTORY_ENTRY_LOAD_CONFIG.struct.SEHandlerTable != 0) or
-        pe.FILE_HEADER.Machine == MACHINE_TYPE_AMD64):
+        pe.FILE_HEADER.Machine in (MACHINE_TYPE_AMD64, MACHINE_TYPE_ARM64)):
       if options.verbose:
         print("Checking %s for /SAFESEH... PASS" % path)
     else:
@@ -138,7 +139,7 @@
 
     # ASLR is weakened on Windows 64-bit when the ImageBase is below 4GB
     # (because the loader will never be rebase the image above 4GB).
-    if pe.FILE_HEADER.Machine == MACHINE_TYPE_AMD64:
+    if pe.FILE_HEADER.Machine in (MACHINE_TYPE_AMD64, MACHINE_TYPE_ARM64):
       if pe.OPTIONAL_HEADER.ImageBase <= 0xFFFFFFFF:
         print("Checking %s ImageBase (0x%X < 4GB)... FAIL" %
               (path, pe.OPTIONAL_HEADER.ImageBase))
diff --git a/tools/metrics/histograms/metadata/android/enums.xml b/tools/metrics/histograms/metadata/android/enums.xml
index 2270580..0511009 100644
--- a/tools/metrics/histograms/metadata/android/enums.xml
+++ b/tools/metrics/histograms/metadata/android/enums.xml
@@ -589,6 +589,14 @@
   <int value="2" label="FINISHED">AsyncTask is done.</int>
 </enum>
 
+<enum name="AwIpProtectionTokenBatchRequestResult">
+  <int value="0" label="Success"/>
+  <int value="1" label="Failed - BSA Transient Error"/>
+  <int value="2" label="Failed - BSA Persistent Error"/>
+  <int value="3" label="Failed - BSA Error Other"/>
+  <int value="4" label="Disabled feature"/>
+</enum>
+
 <enum name="BackgroundTaskId">
   <int value="-1" label="Not found"/>
   <int value="0" label="Test task (should not appear)"/>
diff --git a/tools/metrics/histograms/metadata/apps/histograms.xml b/tools/metrics/histograms/metadata/apps/histograms.xml
index aee6676..52ae08d 100644
--- a/tools/metrics/histograms/metadata/apps/histograms.xml
+++ b/tools/metrics/histograms/metadata/apps/histograms.xml
@@ -894,7 +894,7 @@
 </histogram>
 
 <histogram name="Apps.AppList.NumberOfAppsInNonSystemFolders" units="count"
-    expires_after="2024-06-30">
+    expires_after="2024-12-30">
   <owner>tbarzic@chromium.org</owner>
   <owner>jamescook@chromium.org</owner>
   <owner>mmourgos@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/bluetooth/histograms.xml b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
index b389f54..0285f71f 100644
--- a/tools/metrics/histograms/metadata/bluetooth/histograms.xml
+++ b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
@@ -68,6 +68,18 @@
   <token key="MethodName" variants="BlueZDBusMethodName"/>
 </histogram>
 
+<histogram name="Bluetooth.ChromeOS.ConnectionToastShownIn24Hours.Count"
+    units="count" expires_after="2025-05-30">
+  <owner>longbowei@google.com</owner>
+  <owner>dpad@google.com</owner>
+  <owner>cros-peripherals@google.com</owner>
+  <summary>
+    Record the number of times the connection toast is shown to user in the
+    24-hour period, starting at local midnight. Fires at system start or on
+    Bluetooth connection if 24 hours have passed.
+  </summary>
+</histogram>
+
 <histogram name="Bluetooth.ChromeOS.DeviceConnected.{ConnectionType}"
     enum="BluetoothDeviceType" expires_after="2025-02-20">
   <owner>khorimoto@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml
index 88723559..41c2b493a 100644
--- a/tools/metrics/histograms/metadata/compositing/histograms.xml
+++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -464,41 +464,6 @@
   </summary>
 </histogram>
 
-<histogram name="Compositing.Display.OverlayProcessorOzone.MaxPlanesSupported"
-    units="units" expires_after="2024-06-30">
-  <owner>khaslett@chromium.org</owner>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    This is logged every time a valid HardwareCapabilities is received from DRM
-    when display configuration may have changed. It records the number of
-    overlay planes we have available on this device including the primary plane.
-    Note: this metric was expired from 2023-08-20 to 2024-02-05.
-  </summary>
-</histogram>
-
-<histogram
-    name="Compositing.Display.OverlayProcessorUsingStrategy.CheckOverlaySupportCallCount"
-    units="units" expires_after="2024-06-30">
-  <owner>khaslett@chromium.org</owner>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    This is logged once per frame, the number of times CheckOverlaySupport is
-    called this frame.
-  </summary>
-</histogram>
-
-<histogram
-    name="Compositing.Display.OverlayProcessorUsingStrategy.CheckOverlaySupportUs"
-    units="microseconds" expires_after="2024-06-30">
-  <owner>khaslett@chromium.org</owner>
-  <owner>kylechar@chromium.org</owner>
-  <summary>
-    Logged zero or more times per frame, the time spent checking if a set of
-    candidates can be promoted to overlay. Only reported for platforms
-    supporting high resolution clocks.
-  </summary>
-</histogram>
-
 <histogram
     name="Compositing.Display.OverlayProcessorUsingStrategy.FramesAttemptingRequiredOverlays"
     enum="Boolean" expires_after="2024-12-08">
diff --git a/tools/metrics/histograms/metadata/dev/enums.xml b/tools/metrics/histograms/metadata/dev/enums.xml
index f15b7135..376b2051 100644
--- a/tools/metrics/histograms/metadata/dev/enums.xml
+++ b/tools/metrics/histograms/metadata/dev/enums.xml
@@ -790,6 +790,8 @@
       label="Animations panel - Scroll driven animation group selected"/>
   <int value="144"
       label="Animations panel - Scroll driven animation group scrubbed"/>
+  <int value="145" label="Freestyler panel - Opened through Elements panel"/>
+  <int value="146" label="Freestyler panel - Opened through Styles tab"/>
 </enum>
 
 <enum name="DevToolsAnimationPlaybackRateChanged">
diff --git a/tools/metrics/histograms/metadata/families/enums.xml b/tools/metrics/histograms/metadata/families/enums.xml
index b550c38b..ac67e1d 100644
--- a/tools/metrics/histograms/metadata/families/enums.xml
+++ b/tools/metrics/histograms/metadata/families/enums.xml
@@ -448,7 +448,13 @@
 <!-- LINT.IfChange(SupervisedUserProtoFetcherStatus) -->
 
 <enum name="SupervisedUserProtoFetcherStatus">
-  <int value="0" label="NoError"/>
+  <int value="0" label="NoError">
+    The overall request was successul.
+
+    If this endpoint uses BestEffort credentials mode, it is possible there was
+    an access token error, in which case the separate {RequestType}.AuthError
+    histogram is also output (but not the AuthError bucket of this histogram).
+  </int>
   <int value="1" label="AuthError">
     The request failed due to an error fetching the access token. The
     {RequestType}.AuthError histogram contains more fine-grained error details.
diff --git a/tools/metrics/histograms/metadata/families/histograms.xml b/tools/metrics/histograms/metadata/families/histograms.xml
index 3596a6c..d260341 100644
--- a/tools/metrics/histograms/metadata/families/histograms.xml
+++ b/tools/metrics/histograms/metadata/families/histograms.xml
@@ -945,7 +945,8 @@
   <owner>chrome-kids-eng@google.com</owner>
   <summary>
     The detailed reason for AuthError failures. Recorded for each request to the
-    API where {RequestType}.Status is AuthError.
+    API where Chrome was unable to get a valid access token (whether or not this
+    error was fatal).
   </summary>
   <token key="RequestType" variants="ProtoFetcherRequestType"/>
 </histogram>
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml
index 7fb1908c6..6ff9c98 100644
--- a/tools/metrics/histograms/metadata/ios/histograms.xml
+++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -2122,7 +2122,7 @@
 </histogram>
 
 <histogram name="IOS.Notifications.Tips.ClientStatus.Enabled.ByProvider"
-    enum="Boolean" expires_after="2024-06-26">
+    enum="Boolean" expires_after="2024-10-26">
   <owner>hiramahmood@google.com</owner>
   <owner>scottyoder@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/network/histograms.xml b/tools/metrics/histograms/metadata/network/histograms.xml
index 80e366f..b475f5f 100644
--- a/tools/metrics/histograms/metadata/network/histograms.xml
+++ b/tools/metrics/histograms/metadata/network/histograms.xml
@@ -4688,6 +4688,36 @@
   </summary>
 </histogram>
 
+<histogram name="NetworkService.AwIpProtection.TokenBatchRequestTime"
+    units="ms" expires_after="2024-09-29">
+  <owner>ciaramcmullin@google.com</owner>
+  <owner>ashleynewson@chromium.org</owner>
+  <owner>src/android_webview/OWNERS</owner>
+  <owner>src/chrome/browser/ip_protection/OWNERS</owner>
+  <summary>
+    Records the elapsed time for successful requests by IpProtectionConfigGetter
+    for blind-signed tokens from BSA.
+
+    This metric only measures part of the Android WebView specific blind-signing
+    implementation and does not encompass the full token batch generation
+    process.
+  </summary>
+</histogram>
+
+<histogram name="NetworkService.AwIpProtection.TryGetAuthTokensResult"
+    enum="AwIpProtectionTokenBatchRequestResult" expires_after="2024-09-15">
+  <owner>ciaramcmullin@google.com</owner>
+  <owner>ashleynewson@chromium.org</owner>
+  <owner>src/android_webview/OWNERS</owner>
+  <owner>src/chrome/browser/ip_protection/OWNERS</owner>
+  <summary>
+    The result of handling a request by the network service to the Android
+    WebView's browser logic for a batch of blind-signed auth tokens. This is
+    recorded per request attempt. Retries may result in multiple logs for the
+    same request.
+  </summary>
+</histogram>
+
 <histogram name="NetworkService.CorsPreflightMethodAllowed"
     enum="NetworkServiceCorsPreflightMethodAllowed" expires_after="2023-06-18">
   <owner>hiroshige@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml
index 43786c3..cf4084a 100644
--- a/tools/metrics/histograms/metadata/password/histograms.xml
+++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -688,7 +688,7 @@
 </histogram>
 
 <histogram name="PasswordManager.AffiliationDatabase.Error"
-    enum="SqliteLoggedResultCode" expires_after="2024-07-21">
+    enum="SqliteLoggedResultCode" expires_after="M130">
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/performance_manager/histograms.xml b/tools/metrics/histograms/metadata/performance_manager/histograms.xml
index b9f214e..e460bc7 100644
--- a/tools/metrics/histograms/metadata/performance_manager/histograms.xml
+++ b/tools/metrics/histograms/metadata/performance_manager/histograms.xml
@@ -217,6 +217,25 @@
   </summary>
 </histogram>
 
+<histogram name="PerformanceManager.LoadingNotQuiescentPageCount.{Visibility}"
+    units="pages" expires_after="2024-12-10">
+  <owner>joenotcharles@google.com</owner>
+  <owner>chrome-catan@google.com</owner>
+  <summary>
+    Recorded every 30 seconds with the number of PageNodes that have started
+    loading and not reached quiescence at the end of the interval (ie. in
+    LoadingState kLoading or kLoadedBusy). This variant records pages that are
+    {Visibility} for the entire load. PerformanceManager.QuiescentPageCount is
+    recorded at the same time for comparison.
+  </summary>
+  <token key="Visibility">
+    <variant name="All" summary="in any visibility state"/>
+    <variant name="Hidden" summary="hidden"/>
+    <variant name="MixedVisibility" summary="in a mix of visibility states"/>
+    <variant name="Visible" summary="visible"/>
+  </token>
+</histogram>
+
 <histogram
     name="PerformanceManager.PerformanceInterventions.CPU.AverageBackgroundCPU.{Timing}"
     units="%" expires_after="2024-11-03">
@@ -381,6 +400,19 @@
   <token key="Timing" variants="PerformanceInterventionsCPUTiming"/>
 </histogram>
 
+<histogram name="PerformanceManager.QuiescentPageCount" units="pages"
+    expires_after="2024-12-10">
+  <owner>joenotcharles@google.com</owner>
+  <owner>chrome-catan@google.com</owner>
+  <summary>
+    Recorded every 30 seconds with the number of PageNodes that have not started
+    loading (ie. in LoadingState kLoadingNotStarted or kLoadingTimedOut) or have
+    reached quiescence (ie. in LoadingState kLoadedIdle) at the end of the
+    interval. PerformanceManager.LoadingNotQuiescentPageCount is recorded at the
+    same time for comparison.
+  </summary>
+</histogram>
+
 <histogram name="PerformanceManager.SiteDB.DatabaseInit"
     enum="LocalSiteCharacteristicsDBInitStatus" expires_after="2023-12-28">
   <owner>joenotcharles@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/renderer/histograms.xml b/tools/metrics/histograms/metadata/renderer/histograms.xml
index c204728c..b8337a9 100644
--- a/tools/metrics/histograms/metadata/renderer/histograms.xml
+++ b/tools/metrics/histograms/metadata/renderer/histograms.xml
@@ -109,20 +109,26 @@
     units="ms" expires_after="2024-08-01">
   <owner>jonross@chromium.org</owner>
   <owner>sahir.vellani@microsoft.com</owner>
+  <improvement direction="HIGHER_IS_BETTER"/>
   <summary>
-    The latency improvement provided by the delegated ink trail API, both with
-    and without prediction, in milliseconds. This latency improvement is the
+    The latency improvement provided by the delegated ink trail API
+    {Prediction}, in milliseconds {Renderer}. This latency improvement is the
     difference between the timestamp of the pointerevent provided to the API,
     and the final point of the trail that is drawn. Points are forwarded from
     the browser to viz when this API is being used, so viz will have points
     ahead of what the app provided the API, and they are used to draw the trail.
+    This metric measures how much closer the trail is to the pointer, in time,
+    compared to the last API drawn point. The bigger the histogram's value, the
+    closer Delegated Ink got us to the last pointer position.
   </summary>
   <token key="Renderer">
-    <variant name="Skia"/>
+    <variant name="OS" summary="using the native OS Delegated Ink API"/>
+    <variant name="Skia"
+        summary="using the Skia implementation for Delegated Ink"/>
   </token>
   <token key="Prediction">
-    <variant name="WithoutPrediction"/>
-    <variant name="WithPrediction"/>
+    <variant name="WithoutPrediction" summary="without point prediction"/>
+    <variant name="WithPrediction" summary="using point draw prediction"/>
   </token>
 </histogram>
 
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
index 121733a..71b2e2e 100644
--- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
+++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -3263,26 +3263,6 @@
   </summary>
 </histogram>
 
-<histogram name="SafeBrowsing.WebApiHandshakeCheck.Skipped"
-    enum="BooleanSkipped" expires_after="2024-11-03">
-  <owner>thefrog@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Logged when a web API handshake decides whether to skip its associated Safe
-    Browsing check.
-  </summary>
-</histogram>
-
-<histogram name="SafeBrowsing.WebApiHandshakeCheck.UrlScheme"
-    enum="SafeBrowsingUrlScheme" expires_after="2024-12-08">
-  <owner>thefrog@chromium.org</owner>
-  <owner>chrome-counter-abuse-alerts@google.com</owner>
-  <summary>
-    Logged when a web API handshake is determining whether to run a Safe
-    Browsing check. Records the scheme of the URL that would be checked.
-  </summary>
-</histogram>
-
 <histogram name="SafeBrowsing.WebSocketCheck.Skipped" enum="BooleanSkipped"
     expires_after="2024-11-03">
   <owner>thefrog@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/storage/enums.xml b/tools/metrics/histograms/metadata/storage/enums.xml
index 48e704e1..0c05501 100644
--- a/tools/metrics/histograms/metadata/storage/enums.xml
+++ b/tools/metrics/histograms/metadata/storage/enums.xml
@@ -112,6 +112,20 @@
   <int value="9" label="Filenames"/>
 </enum>
 
+<enum name="FileReaderLoaderFailureType">
+  <int value="0" label="Mojo pipe creation failed"/>
+  <int value="1" label="Data incomplete after synchronous reading"/>
+  <int value="2" label="OnComplete never called after synchronous reading"/>
+  <int value="3"
+      label="Backend read error, see Storage.Blob.FileReaderLoader.ReadError"/>
+  <int value="4" label="The size read does not match the size reported"/>
+  <int value="5"
+      label="The data pipe is not readable and there are bytes left to read"/>
+  <int value="6" label="The data pipe closed early"/>
+  <int value="7" label="Data pipe reading failed with an unexpected error"/>
+  <int value="8" label="File reader client reporter a problem"/>
+</enum>
+
 <enum name="FileSystemAccessPermissionRequestOutcome">
   <int value="0" label="Blocked by Content Setting"/>
   <int value="1" label="Blocked from invalid frame"/>
diff --git a/tools/metrics/histograms/metadata/storage/histograms.xml b/tools/metrics/histograms/metadata/storage/histograms.xml
index b1f28ce..b19ab9b 100644
--- a/tools/metrics/histograms/metadata/storage/histograms.xml
+++ b/tools/metrics/histograms/metadata/storage/histograms.xml
@@ -443,6 +443,30 @@
   </summary>
 </histogram>
 
+<histogram name="Storage.Blob.FileReaderLoader.FailureType2"
+    enum="FileReaderLoaderFailureType" expires_after="2024-12-14">
+  <owner>estade@chromium.org</owner>
+  <owner>chrome-owp-storage@google.com</owner>
+  <summary>
+    Recorded when an error occurs in the FileReaderLoader, which is used to load
+    blobs in the Renderer. FileReaderUser is mostly used for Javascript's
+    'FileReader', but can also be used to read blobs for the IndexedDB
+    renderer-side implementation. For the read error category, see
+    Storage.Blob.FileReaderLoader.ReadError for a breakdown of the specific read
+    error reasons.
+  </summary>
+</histogram>
+
+<histogram name="Storage.Blob.FileReaderLoader.ReadError2" enum="NetErrorCodes"
+    expires_after="2024-12-14">
+  <owner>estade@chromium.org</owner>
+  <owner>chrome-owp-storage@google.com</owner>
+  <summary>
+    The error code reported by the blob system while trying to read a blob in
+    the FileReaderLoader.
+  </summary>
+</histogram>
+
 <histogram name="Storage.Buckets.BucketCount" units="buckets"
     expires_after="2025-04-01">
   <owner>estade@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/sync/histograms.xml b/tools/metrics/histograms/metadata/sync/histograms.xml
index ae96c401..9c83b5a 100644
--- a/tools/metrics/histograms/metadata/sync/histograms.xml
+++ b/tools/metrics/histograms/metadata/sync/histograms.xml
@@ -1192,14 +1192,14 @@
 </histogram>
 
 <histogram name="Sync.PassphraseType2" enum="PassphraseTypeForMetrics"
-    expires_after="2025-04-30">
+    expires_after="2025-06-17">
   <owner>mmoskvitin@google.com</owner>
   <owner>mastiz@chromium.org</owner>
   <summary>
-    TODO(crbug.com/338027160): Remove this histogram once the new
-    PassphraseType3 reaches the stable channel. That one relies on a pref that
-    caches the passphrase type and thus can record the correct value before sync
-    engine initialization.
+    TODO(crbug.com/347711860): Remove this on 06/2025, once Sync.PassphraseType3
+    has been available for a year. That one relies on a pref that caches the
+    passphrase type and thus can record the correct value before sync engine
+    initialization.
 
     Sync passphrase type collected at each metrics upload. Also used for the
     &quot;Sync passphrase type&quot; filter in the dashboard.
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 4dedea6..f56b723 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,8 +5,8 @@
             "full_remote_path": "perfetto-luci-artifacts/v46.0/linux-arm64/trace_processor_shell"
         },
         "win": {
-            "hash": "79895ea001cb99eefc73567a68740d0f8492070a",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/efccce3b6513b30307f5836a2a0b43819a68738b/trace_processor_shell.exe"
+            "hash": "f87ccfcfe2aed41ca68bdb41a38762b1625a7fe2",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/1f7279a2c37ffbe5dd83ce1f28858b4daa7aabcf/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "871ca76c36e35af95152c733fa906677dc04b9d9",
@@ -21,8 +21,8 @@
             "full_remote_path": "perfetto-luci-artifacts/v46.0/mac-arm64/trace_processor_shell"
         },
         "linux": {
-            "hash": "baa57df037273281088f78ad938c7f5521205b2a",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/6f8d4eba872ebf682e638c7def3052e8cb6e4d75/trace_processor_shell"
+            "hash": "715a594126750856c36922eaafdf3ddaa686def7",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/d692646ebc654efcadca55cbcad822c554b39b65/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/utr/run.py b/tools/utr/run.py
index 067e177..bb901d0b 100755
--- a/tools/utr/run.py
+++ b/tools/utr/run.py
@@ -45,12 +45,12 @@
                       help='Skip all prompts about config mismatches.')
   parser.add_argument('--test',
                       '-t',
-                      required=True,
                       action='append',
                       default=[],
                       dest='tests',
                       help='Name of test suite(s) to replicate. Pass multiple '
-                      'times for multiple tests.')
+                      'times for multiple tests. Optional with the "compile" '
+                      'run mode which will compile "all".')
   parser.add_argument('--builder',
                       '-b',
                       required=True,
@@ -143,6 +143,11 @@
   if args.reuse_task and args.run_mode != 'test':
     parser.print_help()
     parser.error('reuse-task is only compatible with "test"')
+  if not args.tests:
+    # Only compile mode should default to compile all
+    if args.run_mode != 'compile':
+      parser.print_help()
+      parser.error('Please provide a test to run')
   return args
 
 
diff --git a/ui/accessibility/accessibility_features.cc b/ui/accessibility/accessibility_features.cc
index 761b49b..b5ab4e4 100644
--- a/ui/accessibility/accessibility_features.cc
+++ b/ui/accessibility/accessibility_features.cc
@@ -309,9 +309,7 @@
              "ReadAnythingLocalSidePanel",
              base::FEATURE_ENABLED_BY_DEFAULT);
 bool IsReadAnythingLocalSidePanelEnabled() {
-  return base::FeatureList::IsEnabled(
-             ::features::kReadAnythingLocalSidePanel) &&
-         base::FeatureList::IsEnabled(::features::kReadAnythingWebUIToolbar);
+  return base::FeatureList::IsEnabled(::features::kReadAnythingLocalSidePanel);
 }
 
 BASE_FEATURE(kReadAnythingReadAloud,
@@ -356,13 +354,6 @@
              ::features::kReadAnythingReadAloudPhraseHighlighting);
 }
 
-BASE_FEATURE(kReadAnythingWebUIToolbar,
-             "ReadAnythingWebUIToolbar",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-bool IsReadAnythingWebUIToolbarEnabled() {
-  return base::FeatureList::IsEnabled(::features::kReadAnythingWebUIToolbar);
-}
-
 BASE_FEATURE(kReadAnythingWithScreen2x,
              "ReadAnythingWithScreen2x",
              base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/ui/accessibility/accessibility_features.h b/ui/accessibility/accessibility_features.h
index 07d336f..6f292f23 100644
--- a/ui/accessibility/accessibility_features.h
+++ b/ui/accessibility/accessibility_features.h
@@ -254,10 +254,6 @@
 AX_BASE_EXPORT BASE_DECLARE_FEATURE(kReadAnythingReadAloudPhraseHighlighting);
 AX_BASE_EXPORT bool IsReadAnythingReadAloudPhraseHighlightingEnabled();
 
-// Use the WebUI toolbar in Read Anything.
-AX_BASE_EXPORT BASE_DECLARE_FEATURE(kReadAnythingWebUIToolbar);
-AX_BASE_EXPORT bool IsReadAnythingWebUIToolbarEnabled();
-
 // Use screen2x integration for Read Anything to distill web pages
 // using an ML model.
 AX_BASE_EXPORT BASE_DECLARE_FEATURE(kReadAnythingWithScreen2x);
diff --git a/ui/base/resource/data_pack.cc b/ui/base/resource/data_pack.cc
index 635115e6..7801d9b 100644
--- a/ui/base/resource/data_pack.cc
+++ b/ui/base/resource/data_pack.cc
@@ -20,6 +20,7 @@
 #include "base/files/memory_mapped_file.h"
 #include "base/logging.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_span.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/synchronization/lock.h"
 #include "net/filter/gzip_header.h"
@@ -165,7 +166,7 @@
   const uint8_t* GetData() const override { return buffer_.data(); }
 
  private:
-  base::span<const uint8_t> buffer_;
+  base::raw_span<const uint8_t> buffer_;
 };
 
 DataPack::DataPack(ResourceScaleFactor resource_scale_factor)
diff --git a/ui/base/x/x11_display_util.cc b/ui/base/x/x11_display_util.cc
index ffaea4fe..faf59929 100644
--- a/ui/base/x/x11_display_util.cc
+++ b/ui/base/x/x11_display_util.cc
@@ -299,6 +299,7 @@
     const display::DisplayConfig& display_config,
     size_t* primary_display_index_out) {
   DCHECK(primary_display_index_out);
+  auto* command_line = base::CommandLine::ForCurrentProcess();
   const float primary_scale = display_config.primary_scale;
 
   auto* connection = x11::Connection::Get();
@@ -348,7 +349,7 @@
   connection->Flush();
 
   std::vector<x11::Future<x11::GetPropertyReply>> icc_futures{n_iccs};
-  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kHeadless)) {
+  if (!command_line->HasSwitch(switches::kHeadless)) {
     for (size_t monitor = 0; monitor < n_iccs; ++monitor) {
       icc_futures[monitor] = GetIccProfileFuture(connection, monitor);
     }
@@ -446,11 +447,18 @@
     }
 
     const std::string name(output_info->name.begin(), output_info->name.end());
+    auto process_type =
+        command_line->GetSwitchValueASCII("type");
     if (base::StartsWith(name, "eDP") || base::StartsWith(name, "LVDS")) {
       display::SetInternalDisplayIds({display_id});
-      // Use localized variant of "Built-in display" for internal displays.
+      // For browser process which has access to resource bundle,
+      // use localized variant of "Built-in display" for internal displays.
       // This follows the ozone DRM behavior (i.e. ChromeOS).
-      display.set_label(l10n_util::GetStringUTF8(IDS_DISPLAY_NAME_INTERNAL));
+      if (process_type.empty()) {
+        display.set_label(l10n_util::GetStringUTF8(IDS_DISPLAY_NAME_INTERNAL));
+      } else {
+        display.set_label("Built-in display");
+      }
     } else {
       display.set_label(edid_parser.display_name());
     }
diff --git a/ui/compositor/throughput_tracker.cc b/ui/compositor/throughput_tracker.cc
index 545b143d..31077b1 100644
--- a/ui/compositor/throughput_tracker.cc
+++ b/ui/compositor/throughput_tracker.cc
@@ -51,10 +51,14 @@
 bool ThroughputTracker::Stop() {
   DCHECK_EQ(state_, State::kStarted);
 
-  state_ = State::kWaitForReport;
-  if (host_)
-    return host_->StopThroughputTracker(id_);
+  if (host_ && host_->StopThroughputTracker(id_)) {
+    state_ = State::kWaitForReport;
+    return true;
+  }
 
+  // No data will be reported. This could happen when gpu process crashed.
+  // Treat the case as `kCanceled`.
+  state_ = State::kCanceled;
   return false;
 }
 
@@ -69,7 +73,10 @@
 }
 
 void ThroughputTracker::CancelReport() {
-  DCHECK(state_ == State::kStarted || state_ == State::kWaitForReport);
+  // Report is only possible in `kStarted` and `kWaitForReport` state.
+  if (state_ != State::kStarted && state_ != State::kWaitForReport) {
+    return;
+  }
 
   state_ = State::kCanceled;
   if (host_)
diff --git a/ui/gl/delegated_ink_point_renderer_gpu.cc b/ui/gl/delegated_ink_point_renderer_gpu.cc
index e9470df..0d00cdef 100644
--- a/ui/gl/delegated_ink_point_renderer_gpu.cc
+++ b/ui/gl/delegated_ink_point_renderer_gpu.cc
@@ -9,6 +9,7 @@
 #include <memory>
 #include <utility>
 
+#include "base/metrics/histogram_functions.h "
 #include "base/metrics/histogram_macros.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
@@ -105,11 +106,18 @@
   if (points_to_be_drawn_.empty()) {
     return;
   }
+  CHECK(metadata_);
   const base::TimeTicks now = base::TimeTicks::Now();
+  base::TimeTicks most_recent_timestamp = base::TimeTicks::Min();
   for (const auto& timestamp : points_to_be_drawn_) {
     UMA_HISTOGRAM_TIMES("Renderer.DelegatedInkTrail.OS.TimeToDrawPointsMillis",
                         now - timestamp);
+    most_recent_timestamp = std::max(timestamp, most_recent_timestamp);
   }
+  CHECK_GE(most_recent_timestamp, metadata_->timestamp());
+  base::UmaHistogramTimes(
+      "Renderer.DelegatedInkTrail.LatencyImprovement.OS.WithoutPrediction",
+      most_recent_timestamp - metadata_->timestamp());
   points_to_be_drawn_.clear();
 }
 
diff --git a/ui/gl/delegated_ink_point_renderer_gpu_unittest.cc b/ui/gl/delegated_ink_point_renderer_gpu_unittest.cc
index f265373..d6eee0eb 100644
--- a/ui/gl/delegated_ink_point_renderer_gpu_unittest.cc
+++ b/ui/gl/delegated_ink_point_renderer_gpu_unittest.cc
@@ -169,10 +169,6 @@
 // Test to confirm that points and tokens are stored and removed correctly based
 // on when the metadata and points arrive.
 TEST_F(DelegatedInkPointRendererGpuTest, StoreAndRemovePointsAndTokens) {
-  if (!presenter() || !presenter()->SupportsDelegatedInk()) {
-    return;
-  }
-
   // Send some points and make sure they are all stored even with no metadata.
   const int32_t kPointerId = 1;
   SendDelegatedInkPoint(gfx::DelegatedInkPoint(
@@ -228,10 +224,6 @@
 // Basic test to confirm that points are drawn as they arrive if they are in the
 // presentation area and after the metadata's timestamp.
 TEST_F(DelegatedInkPointRendererGpuTest, DrawPointsAsTheyArrive) {
-  if (!presenter() || !presenter()->SupportsDelegatedInk()) {
-    return;
-  }
-
   gfx::DelegatedInkMetadata metadata(
       gfx::PointF(12, 12), /*diameter=*/3, SK_ColorBLACK,
       base::TimeTicks::Now(), gfx::RectF(10, 10, 90, 90), /*hovering=*/false);
@@ -282,10 +274,6 @@
 
 // Confirm that points with different pointer ids are handled correctly.
 TEST_F(DelegatedInkPointRendererGpuTest, MultiplePointerIds) {
-  if (!presenter() || !presenter()->SupportsDelegatedInk()) {
-    return;
-  }
-
   const int32_t kPointerId1 = 1;
   const int32_t kPointerId2 = 2;
 
@@ -379,10 +367,6 @@
 // Make sure that the DelegatedInkPoint with the earliest timestamp is removed
 // if we have reached the maximum number of pointer ids.
 TEST_F(DelegatedInkPointRendererGpuTest, MaximumPointerIds) {
-  if (!presenter() || !presenter()->SupportsDelegatedInk()) {
-    return;
-  }
-
   // First add DelegatedInkPoints with unique pointer ids up to the limit and
   // make sure they are all correctly added separately.
   const base::TimeTicks kEarliestTimestamp =
@@ -438,9 +422,6 @@
 // added to the API's trail, and that the TimeToDrawPointsMillis histogram is
 // reported correctly on draw.
 TEST_F(DelegatedInkPointRendererGpuTest, ReportTimeToDraw) {
-  if (!presenter() || !presenter()->SupportsDelegatedInk()) {
-    return;
-  }
   const std::string kHistogramName =
       "Renderer.DelegatedInkTrail.OS.TimeToDrawPointsMillis";
   const base::HistogramTester histogram_tester;
@@ -476,5 +457,42 @@
   EXPECT_TRUE(ink_renderer()->PointstoBeDrawnForTesting().empty());
 }
 
+TEST_F(DelegatedInkPointRendererGpuTest, ReportLatencyImprovement) {
+  const std::string kHistogramName =
+      "Renderer.DelegatedInkTrail.LatencyImprovement.OS.WithoutPrediction";
+  const base::HistogramTester histogram_tester;
+  constexpr int32_t kPointerId = 1u;
+
+  ink_renderer()->ReportPointsDrawn();
+  // No histogram should be fired if `points_to_be_drawn_` is empty.
+  EXPECT_TRUE(ink_renderer()->PointstoBeDrawnForTesting().empty());
+  histogram_tester.ExpectTotalCount(kHistogramName, 0);
+
+  // Create three points, `kMicrosecondsBetweenEachPoint` milliseconds apart
+  // from each other (the histogram is measured in ms, microseconds would be
+  // too small of a difference).
+  gfx::DelegatedInkPoint point_1(gfx::PointF(20, 20), base::TimeTicks::Now(),
+                                 kPointerId);
+  gfx::DelegatedInkPoint point_2(
+      point_1.point() + gfx::Vector2dF(5, 5),
+      point_1.timestamp() + base::Milliseconds(kMicrosecondsBetweenEachPoint),
+      kPointerId);
+  gfx::DelegatedInkPoint point_3(
+      point_2.point() + gfx::Vector2dF(5, 5),
+      point_2.timestamp() + base::Milliseconds(kMicrosecondsBetweenEachPoint),
+      kPointerId);
+  SendDelegatedInkPoint(point_1);
+  SendDelegatedInkPoint(point_2);
+  SendDelegatedInkPoint(point_3);
+  SendMetadataBasedOnStoredPoint(0);
+  ink_renderer()->ReportPointsDrawn();
+
+  // One histogram should've been fired with the delta between the metadata's
+  // creation times and the `point_3`'s timestamp, in milliseconds.
+  histogram_tester.ExpectUniqueSample(kHistogramName,
+                                      kMicrosecondsBetweenEachPoint * 2, 1);
+  EXPECT_TRUE(ink_renderer()->PointstoBeDrawnForTesting().empty());
+}
+
 }  // namespace
 }  // namespace gl
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py
index d0e124a8..37d9eb1 100755
--- a/ui/gl/generate_bindings.py
+++ b/ui/gl/generate_bindings.py
@@ -92,14 +92,12 @@
   'arguments': 'GLenum target, GLuint index, GLuint buffer, GLintptr offset, '
                'GLsizeiptr size', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glBindFragDataLocation',
-                 'extensions': ['GL_ARB_blend_func_extended'] },
+  'versions': [{ 'name': 'glBindFragDataLocation' },
                { 'name': 'glBindFragDataLocationEXT',
                  'extensions': ['GL_EXT_blend_func_extended'] }],
   'arguments': 'GLuint program, GLuint colorNumber, const char* name', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glBindFragDataLocationIndexed',
-                 'extensions': ['GL_ARB_blend_func_extended'] },
+  'versions': [{ 'name': 'glBindFragDataLocationIndexed' },
                { 'name': 'glBindFragDataLocationIndexedEXT',
                  'extensions': ['GL_EXT_blend_func_extended'] }],
   'arguments':
@@ -110,8 +108,7 @@
   'arguments': 'GLenum target, GLuint framebuffer', },
 { 'return_type': 'void',
   'known_as': 'glBindImageTextureEXT',
-  'versions': [{ 'name': 'glBindImageTexture',
-                 'extensions': ['GL_ARB_shader_image_load_store'] },
+  'versions': [{ 'name': 'glBindImageTexture' },
                { 'name': 'glBindImageTextureEXT',
                  'extensions': ['GL_EXT_shader_image_load_store'] }],
   'arguments': 'GLuint index, GLuint texture, GLint level, GLboolean layered,'
@@ -259,8 +256,7 @@
   'names': ['glClearStencil'],
   'arguments': 'GLint s', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glClearTexImage',
-                 'extensions': ['GL_ARB_clear_texture'] },
+  'versions': [{ 'name': 'glClearTexImage' },
                { 'name': 'glClearTexImageEXT',
                  'extensions': ['GL_EXT_clear_texture'] }],
   'arguments':
@@ -653,9 +649,7 @@
   'names': ['glFlush'],
   'arguments': 'void', },
 { 'return_type': 'void',
-  'versions': [{'name': 'glFlushMappedBufferRange',
-                'extensions': ['GL_ARB_map_buffer_range']},
-               {'name': 'glFlushMappedBufferRangeEXT'}],
+  'names': ['glFlushMappedBufferRange', 'glFlushMappedBufferRangeEXT'],
   'arguments': 'GLenum target, GLintptr offset, GLsizeiptr length', },
 { 'return_type': 'void',
   'versions': [{'name': 'glFramebufferMemorylessPixelLocalStorageANGLE',
@@ -868,8 +862,7 @@
   'arguments':
       'GLenum pname, GLsizei bufSize, GLsizei* length, GLfloat* data', },
 { 'return_type': 'GLint',
-  'versions': [{'name': 'glGetFragDataIndex',
-                'extensions': ['GL_ARB_blend_func_extended']},
+  'versions': [{'name': 'glGetFragDataIndex' },
                {'name': 'glGetFragDataIndexEXT',
                 'extensions': ['GL_EXT_blend_func_extended']}],
   'arguments': 'GLuint program, const char* name', },
@@ -1471,8 +1464,7 @@
   'arguments': 'GLenum target, GLenum access', },
 { 'return_type': 'void*',
   'known_as': 'glMapBufferRange',
-  'versions': [{ 'name': 'glMapBufferRange',
-                 'extensions': ['GL_ARB_map_buffer_range'] },
+  'versions': [{ 'name': 'glMapBufferRange' },
                { 'name': 'glMapBufferRangeEXT',
                  'extensions': ['GL_EXT_map_buffer_range'] }],
   'arguments':
@@ -1487,8 +1479,7 @@
   'arguments': 'GLbitfield barriers', },
 {'return_type': 'void',
   'known_as': 'glMemoryBarrierEXT',
-  'versions': [{ 'name': 'glMemoryBarrier',
-                 'extensions': ['GL_ARB_shader_image_load_store'] },
+  'versions': [{ 'name': 'glMemoryBarrier' },
                { 'name': 'glMemoryBarrierEXT',
                  'extensions': ['GL_EXT_shader_image_load_store'] }],
   'arguments': 'GLbitfield barriers', },
@@ -1547,8 +1538,7 @@
                  'extensions': ['GL_KHR_debug'] }],
   'arguments': 'void* ptr, GLsizei length, const char* label', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glPatchParameteri',
-                 'extensions': ['GL_ARB_tessellation_shader'] },
+  'versions': [{ 'name': 'glPatchParameteri' },
                { 'name': 'glPatchParameteriOES',
                  'extensions': ['GL_OES_tessellation_shader'] }],
   'arguments': 'GLenum pname, GLint value', },
@@ -1774,7 +1764,7 @@
   'arguments':
       'GLenum target, GLenum internalformat, GLsizei width, GLsizei height', },
 { 'return_type': 'void',
- 'versions' : [{'name': 'glRenderbufferStorageMultisample',
+  'versions': [{'name': 'glRenderbufferStorageMultisample',
                 'extensions': ['GL_ARB_framebuffer_object']},
                {'name': 'glRenderbufferStorageMultisampleANGLE'},
                {'name': 'glRenderbufferStorageMultisampleEXT',
@@ -1783,13 +1773,13 @@
   'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, '
                'GLsizei width, GLsizei height', },
 { 'return_type': 'void',
- 'versions' : [{'name': 'glRenderbufferStorageMultisampleAdvancedAMD',
+  'versions': [{'name': 'glRenderbufferStorageMultisampleAdvancedAMD',
                 'extensions': ['GL_AMD_framebuffer_multisample_advanced'] ,
                 'explicit_only': True}],
   'arguments': 'GLenum target, GLsizei samples, GLsizei storageSamples, '
                'GLenum internalformat,GLsizei width, GLsizei height', },
 { 'return_type': 'void',
- 'versions' : [{'name': 'glRenderbufferStorageMultisampleEXT',
+  'versions': [{'name': 'glRenderbufferStorageMultisampleEXT',
                 'extensions': ['GL_EXT_multisampled_render_to_texture'],
                 'explicit_only': True},
                {'name': 'glRenderbufferStorageMultisampleIMG'}],
diff --git a/ui/gl/gl_bindings_autogen_gl.cc b/ui/gl/gl_bindings_autogen_gl.cc
index 4112999..0c4e3b30 100644
--- a/ui/gl/gl_bindings_autogen_gl.cc
+++ b/ui/gl/gl_bindings_autogen_gl.cc
@@ -329,10 +329,6 @@
       gfx::HasExtension(extensions, "GL_ARB_ES2_compatibility");
   ext.b_GL_ARB_base_instance =
       gfx::HasExtension(extensions, "GL_ARB_base_instance");
-  ext.b_GL_ARB_blend_func_extended =
-      gfx::HasExtension(extensions, "GL_ARB_blend_func_extended");
-  ext.b_GL_ARB_clear_texture =
-      gfx::HasExtension(extensions, "GL_ARB_clear_texture");
   ext.b_GL_ARB_draw_buffers =
       gfx::HasExtension(extensions, "GL_ARB_draw_buffers");
   ext.b_GL_ARB_draw_instanced =
@@ -343,18 +339,12 @@
       gfx::HasExtension(extensions, "GL_ARB_instanced_arrays");
   ext.b_GL_ARB_internalformat_query =
       gfx::HasExtension(extensions, "GL_ARB_internalformat_query");
-  ext.b_GL_ARB_map_buffer_range =
-      gfx::HasExtension(extensions, "GL_ARB_map_buffer_range");
   ext.b_GL_ARB_occlusion_query =
       gfx::HasExtension(extensions, "GL_ARB_occlusion_query");
   ext.b_GL_ARB_robustness = gfx::HasExtension(extensions, "GL_ARB_robustness");
   ext.b_GL_ARB_sampler_objects =
       gfx::HasExtension(extensions, "GL_ARB_sampler_objects");
-  ext.b_GL_ARB_shader_image_load_store =
-      gfx::HasExtension(extensions, "GL_ARB_shader_image_load_store");
   ext.b_GL_ARB_sync = gfx::HasExtension(extensions, "GL_ARB_sync");
-  ext.b_GL_ARB_tessellation_shader =
-      gfx::HasExtension(extensions, "GL_ARB_tessellation_shader");
   ext.b_GL_ARB_texture_multisample =
       gfx::HasExtension(extensions, "GL_ARB_texture_multisample");
   ext.b_GL_ARB_texture_swizzle =
@@ -525,7 +515,7 @@
         GetGLProcAddress("glBindBufferRangeEXT"));
   }
 
-  if (ver->IsAtLeastGL(3u, 0u) || ext.b_GL_ARB_blend_func_extended) {
+  if (ver->IsAtLeastGL(3u, 0u)) {
     fn.glBindFragDataLocationFn = reinterpret_cast<glBindFragDataLocationProc>(
         GetGLProcAddress("glBindFragDataLocation"));
   } else if (ext.b_GL_EXT_blend_func_extended || ext.b_GL_EXT_gpu_shader4) {
@@ -533,7 +523,7 @@
         GetGLProcAddress("glBindFragDataLocationEXT"));
   }
 
-  if (ver->IsAtLeastGL(3u, 3u) || ext.b_GL_ARB_blend_func_extended) {
+  if (ver->IsAtLeastGL(3u, 3u)) {
     fn.glBindFragDataLocationIndexedFn =
         reinterpret_cast<glBindFragDataLocationIndexedProc>(
             GetGLProcAddress("glBindFragDataLocationIndexed"));
@@ -551,8 +541,7 @@
         GetGLProcAddress("glBindFramebufferEXT"));
   }
 
-  if (ver->IsAtLeastGL(4u, 2u) || ver->IsAtLeastGLES(3u, 1u) ||
-      ext.b_GL_ARB_shader_image_load_store) {
+  if (ver->IsAtLeastGL(4u, 2u) || ver->IsAtLeastGLES(3u, 1u)) {
     fn.glBindImageTextureEXTFn = reinterpret_cast<glBindImageTextureEXTProc>(
         GetGLProcAddress("glBindImageTexture"));
   } else if (ext.b_GL_EXT_shader_image_load_store) {
@@ -702,7 +691,7 @@
         reinterpret_cast<glClearDepthfProc>(GetGLProcAddress("glClearDepthf"));
   }
 
-  if (ver->IsAtLeastGL(4u, 4u) || ext.b_GL_ARB_clear_texture) {
+  if (ver->IsAtLeastGL(4u, 4u)) {
     fn.glClearTexImageFn = reinterpret_cast<glClearTexImageProc>(
         GetGLProcAddress("glClearTexImage"));
   } else if (ext.b_GL_EXT_clear_texture) {
@@ -1125,8 +1114,7 @@
         GetGLProcAddress("glFinishFenceNV"));
   }
 
-  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u) ||
-      ext.b_GL_ARB_map_buffer_range) {
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
     fn.glFlushMappedBufferRangeFn =
         reinterpret_cast<glFlushMappedBufferRangeProc>(
             GetGLProcAddress("glFlushMappedBufferRange"));
@@ -1386,7 +1374,7 @@
         GetGLProcAddress("glGetFloatvRobustANGLE"));
   }
 
-  if (ver->IsAtLeastGL(3u, 3u) || ext.b_GL_ARB_blend_func_extended) {
+  if (ver->IsAtLeastGL(3u, 3u)) {
     fn.glGetFragDataIndexFn = reinterpret_cast<glGetFragDataIndexProc>(
         GetGLProcAddress("glGetFragDataIndex"));
   } else if (ext.b_GL_EXT_blend_func_extended) {
@@ -2094,8 +2082,7 @@
         reinterpret_cast<glMapBufferProc>(GetGLProcAddress("glMapBufferOES"));
   }
 
-  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u) ||
-      ext.b_GL_ARB_map_buffer_range) {
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
     fn.glMapBufferRangeFn = reinterpret_cast<glMapBufferRangeProc>(
         GetGLProcAddress("glMapBufferRange"));
   } else if (ext.b_GL_EXT_map_buffer_range) {
@@ -2115,8 +2102,7 @@
             GetGLProcAddress("glMemoryBarrierByRegion"));
   }
 
-  if (ver->IsAtLeastGL(4u, 2u) || ver->IsAtLeastGLES(3u, 1u) ||
-      ext.b_GL_ARB_shader_image_load_store) {
+  if (ver->IsAtLeastGL(4u, 2u) || ver->IsAtLeastGLES(3u, 1u)) {
     fn.glMemoryBarrierEXTFn = reinterpret_cast<glMemoryBarrierEXTProc>(
         GetGLProcAddress("glMemoryBarrier"));
   } else if (ext.b_GL_EXT_shader_image_load_store) {
@@ -2188,8 +2174,7 @@
         GetGLProcAddress("glObjectPtrLabelKHR"));
   }
 
-  if (ver->IsAtLeastGL(4u, 0u) || ver->IsAtLeastGLES(3u, 2u) ||
-      ext.b_GL_ARB_tessellation_shader) {
+  if (ver->IsAtLeastGL(4u, 0u) || ver->IsAtLeastGLES(3u, 2u)) {
     fn.glPatchParameteriFn = reinterpret_cast<glPatchParameteriProc>(
         GetGLProcAddress("glPatchParameteri"));
   } else if (ext.b_GL_OES_tessellation_shader) {
diff --git a/ui/gl/gl_bindings_autogen_gl.h b/ui/gl/gl_bindings_autogen_gl.h
index 497e724..8e4e46ac4 100644
--- a/ui/gl/gl_bindings_autogen_gl.h
+++ b/ui/gl/gl_bindings_autogen_gl.h
@@ -1939,20 +1939,15 @@
   bool b_GL_APPLE_vertex_array_object;
   bool b_GL_ARB_ES2_compatibility;
   bool b_GL_ARB_base_instance;
-  bool b_GL_ARB_blend_func_extended;
-  bool b_GL_ARB_clear_texture;
   bool b_GL_ARB_draw_buffers;
   bool b_GL_ARB_draw_instanced;
   bool b_GL_ARB_framebuffer_object;
   bool b_GL_ARB_instanced_arrays;
   bool b_GL_ARB_internalformat_query;
-  bool b_GL_ARB_map_buffer_range;
   bool b_GL_ARB_occlusion_query;
   bool b_GL_ARB_robustness;
   bool b_GL_ARB_sampler_objects;
-  bool b_GL_ARB_shader_image_load_store;
   bool b_GL_ARB_sync;
-  bool b_GL_ARB_tessellation_shader;
   bool b_GL_ARB_texture_multisample;
   bool b_GL_ARB_texture_swizzle;
   bool b_GL_ARB_timer_query;
diff --git a/ui/gl/gl_fence.cc b/ui/gl/gl_fence.cc
index 00735a52..9b9e709 100644
--- a/ui/gl/gl_fence.cc
+++ b/ui/gl/gl_fence.cc
@@ -44,7 +44,6 @@
 
   return g_current_gl_driver->ext.b_GL_ARB_sync ||
          g_current_gl_version->is_es3 ||
-         g_current_gl_version->is_desktop_core_profile ||
          (display && display->ext->b_EGL_KHR_fence_sync) ||
 #if BUILDFLAG(IS_APPLE)
          g_current_gl_driver->ext.b_GL_APPLE_fence ||
@@ -68,8 +67,7 @@
     return fence;
   }
 
-  if (g_current_gl_driver->ext.b_GL_ARB_sync || g_current_gl_version->is_es3 ||
-      g_current_gl_version->is_desktop_core_profile) {
+  if (g_current_gl_driver->ext.b_GL_ARB_sync || g_current_gl_version->is_es3) {
     // Prefer ARB_sync which supports server-side wait.
     fence = std::make_unique<GLFenceARB>();
     DCHECK(fence);
diff --git a/ui/gl/gl_helper.cc b/ui/gl/gl_helper.cc
index 1ea6f3b..092ddc0 100644
--- a/ui/gl/gl_helper.cc
+++ b/ui/gl/gl_helper.cc
@@ -8,7 +8,6 @@
 
 #include "base/check_op.h"
 #include "ui/gl/gl_context.h"
-#include "ui/gl/gl_version_info.h"
 #include "ui/gl/scoped_binders.h"
 
 namespace gl {
@@ -96,9 +95,4 @@
   glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 }
 
-// static
-bool GLHelper::ShouldTestsUseVAOs() {
-  return GLContext::GetCurrent()->GetVersionInfo()->is_desktop_core_profile;
-}
-
 }  // namespace gl
diff --git a/ui/gl/gl_helper.h b/ui/gl/gl_helper.h
index 477eb5d..ae39b60 100644
--- a/ui/gl/gl_helper.h
+++ b/ui/gl/gl_helper.h
@@ -34,10 +34,6 @@
 
   // Draws a quad to the currently bound frame buffer.
   static void DrawQuad(GLuint vertex_buffer);
-
-  // When using the desktop core profile we have to bind a VAO before
-  // calling glVertexAttribPointer.
-  static bool ShouldTestsUseVAOs();
 };
 
 }  // namespace gl
diff --git a/ui/gl/gl_version_info.cc b/ui/gl/gl_version_info.cc
index f1448e9..5c45c0a 100644
--- a/ui/gl/gl_version_info.cc
+++ b/ui/gl/gl_version_info.cc
@@ -17,13 +17,6 @@
 
 namespace {
 
-bool DesktopCoreCommonCheck(
-    bool is_es, unsigned major_version, unsigned minor_version) {
-  return (!is_es &&
-          ((major_version == 3 && minor_version >= 2) ||
-           major_version > 3));
-}
-
 static bool disable_es3_for_testing = false;
 
 }  // namespace
@@ -72,9 +65,6 @@
     if (is_angle && driver_vendor == "ANGLE")
       ExtractDriverVendorANGLE(renderer_str);
   }
-  is_desktop_core_profile =
-      DesktopCoreCommonCheck(is_es, major_version, minor_version) &&
-      !gfx::HasExtension(extensions, "GL_ARB_compatibility");
   is_es3_capable = IsES3Capable(extensions);
 
   // Post-fixup in case the user requested disabling ES3 capability
diff --git a/ui/gl/gl_version_info.h b/ui/gl/gl_version_info.h
index 58494c9..6c025c8 100644
--- a/ui/gl/gl_version_info.h
+++ b/ui/gl/gl_version_info.h
@@ -36,9 +36,7 @@
                      (major_version == major && minor_version >= minor));
   }
 
-  bool BehavesLikeGLES() const {
-    return is_es || is_desktop_core_profile;
-  }
+  bool BehavesLikeGLES() const { return is_es; }
 
   bool SupportsFixedType() const {
     return is_es || IsAtLeastGL(4, 1);
@@ -59,7 +57,7 @@
   // We need to emulate GL_ALPHA and GL_LUMINANCE and GL_LUMINANCE_ALPHA
   // texture formats on core profile and ES3, except for ANGLE and Swiftshader.
   bool NeedsLuminanceAlphaEmulation() const {
-    return !is_angle && !is_swiftshader && (is_es3 || is_desktop_core_profile);
+    return !is_angle && !is_swiftshader && is_es3;
   }
 
   bool is_es = false;
@@ -74,7 +72,6 @@
   unsigned minor_version = 0;
   bool is_es2 = false;
   bool is_es3 = false;
-  bool is_desktop_core_profile = false;
   bool is_es3_capable = false;
   std::string driver_vendor;
   std::string driver_version;
diff --git a/ui/ozone/platform/x11/x11_window.cc b/ui/ozone/platform/x11/x11_window.cc
index 4907de4..11b0e45e 100644
--- a/ui/ozone/platform/x11/x11_window.cc
+++ b/ui/ozone/platform/x11/x11_window.cc
@@ -690,6 +690,8 @@
     }
   }
 
+  UpdateDecorationInsets();
+
   // Do not go through SetBounds as long as it adjusts bounds and sets them to X
   // Server. Instead, we just store the bounds and notify the client that the
   // window occupies the entire screen.
@@ -1497,6 +1499,7 @@
     tiled_state_ = tiled_state;
 #if BUILDFLAG(IS_LINUX)
     platform_window_delegate_->OnWindowTiledStateChanged(tiled_state);
+    UpdateDecorationInsets();
 #endif
   }
 }
diff --git a/ui/views/bubble/bubble_dialog_delegate_view.h b/ui/views/bubble/bubble_dialog_delegate_view.h
index 6a0ac093..7d5597f 100644
--- a/ui/views/bubble/bubble_dialog_delegate_view.h
+++ b/ui/views/bubble/bubble_dialog_delegate_view.h
@@ -13,6 +13,7 @@
 
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/raw_span.h"
 #include "base/memory/weak_ptr.h"
 #include "build/build_config.h"
 #include "ui/accessibility/ax_enums.mojom-forward.h"
@@ -363,7 +364,7 @@
    private:
     std::optional<raw_ptr<views::View>> bubble_view_;
     std::optional<raw_ptr<views::BubbleDialogDelegate>> delegate_;
-    std::optional<base::span<const char*>> allowed_class_names_for_testing_;
+    std::optional<base::raw_span<const char*>> allowed_class_names_for_testing_;
     base::WeakPtrFactory<BubbleUmaLogger> weak_factory_{this};
   };
 
diff --git a/ui/views/controls/message_box_view.cc b/ui/views/controls/message_box_view.cc
index ce109c7..21a41d9 100644
--- a/ui/views/controls/message_box_view.cc
+++ b/ui/views/controls/message_box_view.cc
@@ -248,6 +248,12 @@
 ///////////////////////////////////////////////////////////////////////////////
 // MessageBoxView, View overrides:
 
+gfx::Size MessageBoxView::CalculatePreferredSize(
+    const SizeBounds& available_size) const {
+  return BoxLayoutView::CalculatePreferredSize(
+      SizeBounds(message_width_, available_size.height()));
+}
+
 void MessageBoxView::ViewHierarchyChanged(
     const ViewHierarchyChangedDetails& details) {
   if (details.child == this && details.is_add) {
@@ -284,7 +290,6 @@
 void MessageBoxView::ResetLayoutManager() {
   SetBetweenChildSpacing(inter_row_vertical_spacing_);
   SetMinimumCrossAxisSize(message_width_);
-  scroll_view_->SetPreferredSize(gfx::Size(message_width_, 0));
 
   views::DialogContentType trailing_content_type =
       views::DialogContentType::kText;
diff --git a/ui/views/controls/message_box_view.h b/ui/views/controls/message_box_view.h
index 75e7c9b1..76a11e57 100644
--- a/ui/views/controls/message_box_view.h
+++ b/ui/views/controls/message_box_view.h
@@ -85,6 +85,8 @@
 
  protected:
   // View:
+  gfx::Size CalculatePreferredSize(
+      const SizeBounds& available_size) const override;
   void ViewHierarchyChanged(
       const ViewHierarchyChangedDetails& details) override;
   // Handles Ctrl-C and writes the message in the system clipboard.
diff --git a/ui/views/controls/scroll_view.cc b/ui/views/controls/scroll_view.cc
index e6672db..b2a84dbd 100644
--- a/ui/views/controls/scroll_view.cc
+++ b/ui/views/controls/scroll_view.cc
@@ -620,29 +620,19 @@
 
 gfx::Size ScrollView::CalculatePreferredSize(
     const SizeBounds& available_size) const {
+  gfx::Insets insets = GetInsets();
   gfx::Size size =
-      contents_ ? contents_->GetPreferredSize(available_size) : gfx::Size();
+      contents_ ? contents_->GetPreferredSize(available_size.Inset(insets))
+                : gfx::Size();
+  size.Enlarge(insets.width(), insets.height());
+
   if (is_bounded()) {
     size.SetToMax(gfx::Size(size.width(), min_height_));
     size.SetToMin(gfx::Size(size.width(), max_height_));
   }
-  gfx::Insets insets = GetInsets();
-  size.Enlarge(insets.width(), insets.height());
   return size;
 }
 
-int ScrollView::GetHeightForWidth(int width) const {
-  if (!is_bounded()) {
-    return View::GetHeightForWidth(width);
-  }
-
-  gfx::Insets insets = GetInsets();
-  width = std::max(0, width - insets.width());
-  int height = contents_ ? contents_->GetHeightForWidth(width) + insets.height()
-                         : insets.height();
-  return std::clamp(height, min_height_, max_height_);
-}
-
 void ScrollView::Layout(PassKey) {
   // When either scrollbar is disabled, it should not matter
   // if its OverlapsContent matches other bar's.
diff --git a/ui/views/controls/scroll_view.h b/ui/views/controls/scroll_view.h
index de8db086..3aeb3a4 100644
--- a/ui/views/controls/scroll_view.h
+++ b/ui/views/controls/scroll_view.h
@@ -225,11 +225,9 @@
   base::CallbackListSubscription AddContentsScrollEndedCallback(
       ScrollViewCallback callback);
 
-  // View overrides:
+  // View:
   gfx::Size CalculatePreferredSize(
       const SizeBounds& available_size) const override;
-
-  int GetHeightForWidth(int width) const override;
   void Layout(PassKey) override;
   bool OnKeyPressed(const ui::KeyEvent& event) override;
   bool OnMouseWheel(const ui::MouseWheelEvent& e) override;
diff --git a/ui/views/examples/bubble_example.cc b/ui/views/examples/bubble_example.cc
index acb0b28fa..a9f6e6e 100644
--- a/ui/views/examples/bubble_example.cc
+++ b/ui/views/examples/bubble_example.cc
@@ -122,7 +122,7 @@
       u"Persistent"));
 }
 
-void BubbleExample::ShowBubble(Button** button,
+void BubbleExample::ShowBubble(raw_ptr<Button>* button,
                                BubbleBorder::Shadow shadow,
                                bool persistent,
                                const ui::Event& event) {
diff --git a/ui/views/examples/bubble_example.h b/ui/views/examples/bubble_example.h
index de0b0c2..808a0e1 100644
--- a/ui/views/examples/bubble_example.h
+++ b/ui/views/examples/bubble_example.h
@@ -5,7 +5,7 @@
 #ifndef UI_VIEWS_EXAMPLES_BUBBLE_EXAMPLE_H_
 #define UI_VIEWS_EXAMPLES_BUBBLE_EXAMPLE_H_
 
-#include "base/memory/raw_ptr_exclusion.h"
+#include "base/memory/raw_ptr.h"
 #include "ui/events/event.h"
 #include "ui/views/bubble/bubble_border.h"
 #include "ui/views/examples/example_base.h"
@@ -31,20 +31,14 @@
   void CreateExampleView(View* container) override;
 
  private:
-  void ShowBubble(Button** button,
+  void ShowBubble(raw_ptr<Button>* button,
                   BubbleBorder::Shadow shadow,
                   bool persistent,
                   const ui::Event& event);
 
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #addr-of
-  RAW_PTR_EXCLUSION Button* standard_shadow_;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #addr-of
-  RAW_PTR_EXCLUSION Button* no_shadow_;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #addr-of
-  RAW_PTR_EXCLUSION Button* persistent_;
+  raw_ptr<Button> standard_shadow_;
+  raw_ptr<Button> no_shadow_;
+  raw_ptr<Button> persistent_;
 };
 
 }  // namespace examples
diff --git a/ui/views/examples/dialog_example.cc b/ui/views/examples/dialog_example.cc
index 6e061a1..7a5a028b 100644
--- a/ui/views/examples/dialog_example.cc
+++ b/ui/views/examples/dialog_example.cc
@@ -208,7 +208,7 @@
 }
 
 void DialogExample::StartTextfieldRow(View* parent,
-                                      Textfield** member,
+                                      raw_ptr<Textfield>* member,
                                       std::u16string label,
                                       std::u16string value,
                                       Label** created_label,
@@ -225,7 +225,9 @@
     parent->AddChildView(std::make_unique<View>());
 }
 
-void DialogExample::AddCheckbox(View* parent, Checkbox** member, Label* label) {
+void DialogExample::AddCheckbox(View* parent,
+                                raw_ptr<Checkbox>* member,
+                                Label* label) {
   auto callback = member == &bubble_ ? &DialogExample::BubbleCheckboxPressed
                                      : &DialogExample::OtherCheckboxPressed;
   auto checkbox = std::make_unique<Checkbox>(
diff --git a/ui/views/examples/dialog_example.h b/ui/views/examples/dialog_example.h
index 70c6f8a..5df0b780 100644
--- a/ui/views/examples/dialog_example.h
+++ b/ui/views/examples/dialog_example.h
@@ -6,7 +6,6 @@
 #define UI_VIEWS_EXAMPLES_DIALOG_EXAMPLE_H_
 
 #include "base/memory/raw_ptr.h"
-#include "base/memory/raw_ptr_exclusion.h"
 #include "ui/base/models/simple_combobox_model.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/views/controls/textfield/textfield_controller.h"
@@ -46,12 +45,12 @@
 
   // Helper methods to setup the configuration Views.
   void StartTextfieldRow(View* parent,
-                         Textfield** member,
+                         raw_ptr<Textfield>* member,
                          std::u16string label,
                          std::u16string value,
                          Label** created_label = nullptr,
                          bool pad_last_col = false);
-  void AddCheckbox(View* parent, Checkbox** member, Label* label);
+  void AddCheckbox(View* parent, raw_ptr<Checkbox>* member, Label* label);
 
   // Checkbox callback
   void OnPerformAction();
@@ -78,37 +77,17 @@
   raw_ptr<DialogDelegate> last_dialog_ = nullptr;
   raw_ptr<Label> last_body_label_ = nullptr;
 
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #addr-of
-  RAW_PTR_EXCLUSION Textfield* title_;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #addr-of
-  RAW_PTR_EXCLUSION Textfield* body_;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #addr-of
-  RAW_PTR_EXCLUSION Textfield* ok_button_label_;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #addr-of
-  RAW_PTR_EXCLUSION Checkbox* has_ok_button_;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #addr-of
-  RAW_PTR_EXCLUSION Textfield* cancel_button_label_;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #addr-of
-  RAW_PTR_EXCLUSION Checkbox* has_cancel_button_;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #addr-of
-  RAW_PTR_EXCLUSION Textfield* extra_button_label_;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #addr-of
-  RAW_PTR_EXCLUSION Checkbox* has_extra_button_;
+  raw_ptr<Textfield> title_ = nullptr;
+  raw_ptr<Textfield> body_ = nullptr;
+  raw_ptr<Textfield> ok_button_label_ = nullptr;
+  raw_ptr<Checkbox> has_ok_button_ = nullptr;
+  raw_ptr<Textfield> cancel_button_label_ = nullptr;
+  raw_ptr<Checkbox> has_cancel_button_ = nullptr;
+  raw_ptr<Textfield> extra_button_label_ = nullptr;
+  raw_ptr<Checkbox> has_extra_button_ = nullptr;
   raw_ptr<Combobox> mode_;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #addr-of
-  RAW_PTR_EXCLUSION Checkbox* bubble_;
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #addr-of
-  RAW_PTR_EXCLUSION Checkbox* persistent_bubble_;
+  raw_ptr<Checkbox> bubble_ = nullptr;
+  raw_ptr<Checkbox> persistent_bubble_ = nullptr;
   raw_ptr<LabelButton> show_;
   ui::SimpleComboboxModel mode_model_;
 };
diff --git a/ui/views/layout/layout_types.cc b/ui/views/layout/layout_types.cc
index 0080f54..5fa2343f 100644
--- a/ui/views/layout/layout_types.cc
+++ b/ui/views/layout/layout_types.cc
@@ -50,6 +50,12 @@
   height_ = std::max<SizeBound>(0, height_ + height);
 }
 
+SizeBounds SizeBounds::Inset(const gfx::Insets& inset) const {
+  SizeBounds new_size_bounds(*this);
+  new_size_bounds.Enlarge(-inset.width(), -inset.height());
+  return new_size_bounds;
+}
+
 std::string SizeBounds::ToString() const {
   return base::StrCat({width_.ToString(), " x ", height_.ToString()});
 }
diff --git a/ui/views/layout/layout_types.h b/ui/views/layout/layout_types.h
index 71a2999..54839d60 100644
--- a/ui/views/layout/layout_types.h
+++ b/ui/views/layout/layout_types.h
@@ -139,6 +139,9 @@
   // specified amounts.
   void Enlarge(int width, int height);
 
+  // Shrink the SizeBounds by the given `insets`.
+  SizeBounds Inset(const gfx::Insets& inset) const;
+
   std::string ToString() const;
 
  private:
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
index 3a6d59d..4125bdae 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
@@ -1061,6 +1061,12 @@
 #endif
 }
 
+gfx::Insets DesktopWindowTreeHostPlatform::ConvertInsetsToPixels(
+    const gfx::Insets& insets_dip) const {
+  auto scale = GetRootTransform().To2dScale();
+  return gfx::ScaleToCeiledInsets(insets_dip, scale.x(), scale.y());
+}
+
 void DesktopWindowTreeHostPlatform::OnWorkspaceChanged() {
   OnHostWorkspaceChanged();
 }
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h
index d88eb8d2..a889ec0 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h
@@ -176,6 +176,8 @@
   gfx::Rect ConvertRectToDIP(const gfx::Rect& rect_in_pixels) const override;
   gfx::PointF ConvertScreenPointToLocalDIP(
       const gfx::Point& screen_in_pixels) const override;
+  gfx::Insets ConvertInsetsToPixels(
+      const gfx::Insets& insets_dip) const override;
 
   // ui::WorkspaceExtensionDelegate:
   void OnWorkspaceChanged() override;
diff --git a/ui/webui/resources/cr_components/history_clusters/cluster.ts b/ui/webui/resources/cr_components/history_clusters/cluster.ts
index 2af38fc..947f162 100644
--- a/ui/webui/resources/cr_components/history_clusters/cluster.ts
+++ b/ui/webui/resources/cr_components/history_clusters/cluster.ts
@@ -178,20 +178,14 @@
       // without an explicit event. But we also can't send this until we have
       // updated the image property, so send it on the next idle.
       requestIdleCallback(() => {
-        this.dispatchEvent(new CustomEvent('iron-resize', {
-          bubbles: true,
-          composed: true,
-        }));
+        this.fire('iron-resize');
       });
     } else if (changedProperties.has('cluster')) {
       // Iron-list re-assigns the `cluster` property to reuse existing elements
       // as the user scrolls. Since this property can change the height of this
       // element, we need to notify iron-list that this element's height may
       // need to be re-calculated.
-      this.dispatchEvent(new CustomEvent('iron-resize', {
-        bubbles: true,
-        composed: true,
-      }));
+      this.fire('iron-resize');
     }
   }
 
@@ -223,14 +217,10 @@
     MetricsProxyImpl.getInstance().recordVisitAction(
         VisitAction.kClicked, visitIndex, MetricsProxyImpl.getVisitType(visit));
 
-    this.dispatchEvent(new CustomEvent('record-history-link-click', {
-      bubbles: true,
-      composed: true,
-      detail: {
-        resultType: HistoryResultType.GROUPED,
-        index: visitIndex,
-      },
-    }));
+    this.fire('record-history-link-click', {
+      resultType: HistoryResultType.GROUPED,
+      index: visitIndex,
+    });
   }
 
   protected onOpenAllVisits_() {
@@ -242,20 +232,12 @@
   }
 
   protected onHideAllVisits_() {
-    this.dispatchEvent(new CustomEvent('hide-visits', {
-      bubbles: true,
-      composed: true,
-      detail: this.cluster.visits,
-    }));
+    this.fire('hide-visits', this.cluster.visits);
   }
 
   protected onRemoveAllVisits_() {
     // Pass event up with new detail of all this cluster's visits.
-    this.dispatchEvent(new CustomEvent('remove-visits', {
-      bubbles: true,
-      composed: true,
-      detail: this.cluster.visits,
-    }));
+    this.fire('remove-visits', this.cluster.visits);
   }
 
   protected onHideVisit_(event: CustomEvent<URLVisit>) {
@@ -275,11 +257,7 @@
         VisitAction.kDeleted, this.getVisitIndex_(visit),
         MetricsProxyImpl.getVisitType(visit));
 
-    this.dispatchEvent(new CustomEvent('remove-visits', {
-      bubbles: true,
-      composed: true,
-      detail: [visit],
-    }));
+    this.fire('remove-visits', [visit]);
   }
 
   //============================================================================
@@ -329,11 +307,7 @@
     if (!remainingVisits.length) {
       // If all the visits are removed, fire an event to also remove this
       // cluster from the list of clusters.
-      this.dispatchEvent(new CustomEvent('remove-cluster', {
-        bubbles: true,
-        composed: true,
-        detail: this.index,
-      }));
+      this.fire('remove-cluster', this.index);
 
       MetricsProxyImpl.getInstance().recordClusterAction(
           ClusterAction.kDeleted, this.index);
@@ -343,10 +317,7 @@
     }
 
     this.updateComplete.then(() => {
-      this.dispatchEvent(new CustomEvent('iron-resize', {
-        bubbles: true,
-        composed: true,
-      }));
+      this.fire('iron-resize');
     });
   }
 
diff --git a/ui/webui/resources/cr_components/history_clusters/cluster_menu.ts b/ui/webui/resources/cr_components/history_clusters/cluster_menu.ts
index cbc2da9..d489e42d 100644
--- a/ui/webui/resources/cr_components/history_clusters/cluster_menu.ts
+++ b/ui/webui/resources/cr_components/history_clusters/cluster_menu.ts
@@ -93,10 +93,7 @@
   protected onOpenAllButtonClick_(event: Event) {
     event.preventDefault();  // Prevent default browser action (navigation).
 
-    this.dispatchEvent(new CustomEvent('open-all-visits', {
-      bubbles: true,
-      composed: true,
-    }));
+    this.fire('open-all-visits');
 
     this.closeActionMenu_();
   }
@@ -104,10 +101,7 @@
   protected onHideAllButtonClick_(event: Event) {
     event.preventDefault();  // Prevent default browser action (navigation).
 
-    this.dispatchEvent(new CustomEvent('hide-all-visits', {
-      bubbles: true,
-      composed: true,
-    }));
+    this.fire('hide-all-visits');
 
     this.closeActionMenu_();
   }
@@ -115,10 +109,7 @@
   protected onRemoveAllButtonClick_(event: Event) {
     event.preventDefault();  // Prevent default browser action (navigation).
 
-    this.dispatchEvent(new CustomEvent('remove-all-visits', {
-      bubbles: true,
-      composed: true,
-    }));
+    this.fire('remove-all-visits');
 
     this.closeActionMenu_();
   }
diff --git a/ui/webui/resources/cr_components/history_clusters/search_query.ts b/ui/webui/resources/cr_components/history_clusters/search_query.ts
index 5211f94..04fe2db7 100644
--- a/ui/webui/resources/cr_components/history_clusters/search_query.ts
+++ b/ui/webui/resources/cr_components/history_clusters/search_query.ts
@@ -72,10 +72,7 @@
         RelatedSearchAction.kClicked, this.index);
 
     // Notify the parent <history-cluster> element of this event.
-    this.dispatchEvent(new CustomEvent('related-search-clicked', {
-      bubbles: true,
-      composed: true,
-    }));
+    this.fire('related-search-clicked');
   }
 
   protected onClick_(event: MouseEvent) {
diff --git a/ui/webui/resources/cr_components/history_clusters/url_visit.ts b/ui/webui/resources/cr_components/history_clusters/url_visit.ts
index f5a73bd8..80d1ddd 100644
--- a/ui/webui/resources/cr_components/history_clusters/url_visit.ts
+++ b/ui/webui/resources/cr_components/history_clusters/url_visit.ts
@@ -127,11 +127,7 @@
 
   private onAuxClick_() {
     // Notify the parent <history-cluster> element of this event.
-    this.dispatchEvent(new CustomEvent('visit-clicked', {
-      bubbles: true,
-      composed: true,
-      detail: this.visit,
-    }));
+    this.fire('visit-clicked', this.visit);
   }
 
   protected onClick_(event: MouseEvent) {
@@ -194,11 +190,7 @@
   private emitMenuButtonClick_(event: Event, emitEventName: string) {
     event.preventDefault();  // Prevent default browser action (navigation).
 
-    this.dispatchEvent(new CustomEvent(emitEventName, {
-      bubbles: true,
-      composed: true,
-      detail: this.visit,
-    }));
+    this.fire(emitEventName, this.visit);
 
     // This can also be triggered from the hide visit icon, in which case the
     // menu may not be rendered.
diff --git a/v8 b/v8
index 8ade856..6374ee6 160000
--- a/v8
+++ b/v8
@@ -1 +1 @@
-Subproject commit 8ade8567adea934309455768cb38ffbb99c4779d
+Subproject commit 6374ee67b88dc2b553eaceb203e0b0bac517c86b